diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 5225ed31f..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,39 +0,0 @@ -version: 2.1 - -jobs: - code: - docker: - - image: circleci/golang:1.13 - steps: - - checkout - - update_submodules - - run: - name: "Test code (Generate, Build, Test)" - command: make test - - run: - name: "Check code is formatted" - command: | - make fmt-code - git diff --exit-code - website: - docker: - - image: cibuilds/hugo:0.58.0 - steps: - - checkout - - run: - name: "Build website" - command: make website - -workflows: - version: 2.1 - test_all: - jobs: - - code - - website - -commands: - update_submodules: - steps: - - run: - name: Update submodules - command: git submodule update --init --recursive diff --git a/.github/workflows/add-to-ipfs.yml b/.github/workflows/add-to-ipfs.yml deleted file mode 100644 index 1cdcd2d6f..000000000 --- a/.github/workflows/add-to-ipfs.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Add to IPFS - -on: [push] - -jobs: - add-to-ipfs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: true - - - name: Install Go - run: | - sudo apt-get remove golang-go - sudo apt-get remove --auto-remove golang-go - sudo rm -rf /usr/local/go - sudo rm -rf /usr/local/go1.12 - sudo rm -rf /usr/local/go1.27 - sudo apt-get update - wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz - sudo tar -xvf go1.14.4.linux-amd64.tar.gz - sudo chown -R root:root ./go - sudo cp -r go /usr/local - sudo cp -r go /usr/local/go1.12 - sudo cp -r go /usr/local/go1.27 - sudo ln -sf /usr/local/go/bin/go /usr/bin/go - sudo echo 'GOROOT=/usr/local/go' >> ~/.profile - sudo echo 'GOPATH=$HOME/work' >>~/.profile - sudo echo 'PATH=$GOROOT/bin:$GOPATH/bin' >>~/.profile - source ~/.profile - - - name: Install deps-ga - run: | - sudo make deps-ga - - - name: Build - run: | - sudo chown -R root:root $GITHUB_WORKSPACE - sudo make build - - - uses: ipfs-shipyard/ipfs-github-action@v1.0.0 - with: - path_to_add: $GITHUB_WORKSPACE/build/website - cluster_host: /dnsaddr/cluster.ipfs.io - cluster_user: ${{ secrets.CLUSTER_USER }} - cluster_password: ${{ secrets.CLUSTER_PASSWORD }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/deploy-to-gh-pages.yml b/.github/workflows/deploy-to-gh-pages.yml deleted file mode 100644 index ed499824d..000000000 --- a/.github/workflows/deploy-to-gh-pages.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: github pages deploy - -on: - push: - branches: - - master - -jobs: - build-deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - with: - submodules: true - - - uses: webfactory/ssh-agent@v0.2.0 - with: - ssh-private-key: ${{ secrets.ACTIONS_DEPLOY_KEY }} - - - name: Install Go - run: | - sudo apt-get remove golang-go - sudo apt-get remove --auto-remove golang-go - sudo rm -rf /usr/local/go - sudo rm -rf /usr/local/go1.12 - sudo rm -rf /usr/local/go1.27 - sudo apt-get update - wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz - sudo tar -xvf go1.14.4.linux-amd64.tar.gz - sudo chown -R root:root ./go - sudo cp -r go /usr/local - sudo cp -r go /usr/local/go1.12 - sudo cp -r go /usr/local/go1.27 - sudo ln -sf /usr/local/go/bin/go /usr/bin/go - sudo echo 'GOROOT=/usr/local/go' >> ~/.profile - sudo echo 'GOPATH=$HOME/work' >>~/.profile - sudo echo 'PATH=$GOROOT/bin:$GOPATH/bin' >>~/.profile - source ~/.profile - - - name: Debug - run: | - pwd - go env - which go - go version - - - name: Install deps-ga - run: | - sudo make deps-ga - - - name: Build - run: | - sudo chown -R root:root $GITHUB_WORKSPACE - sudo make build - - - name: Deploy using SSH - env: - DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - sudo chown -R runner $GITHUB_WORKSPACE - sudo chown -R runner .git/ - eval "$(ssh-agent -s)" - ssh-add - <<< "${DEPLOY_KEY}" - - git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git - git config --local user.email "no-reply-spec-deploy@protocol.ai" - git config --local user.name "no-reply-spec-deploy" - - bin/publish-to-gh-pages.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..d94de87e2 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,48 @@ +name: CI + +on: [push] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-go@v2 + with: + go-version: '1.14' + + - uses: actions/setup-node@v2-beta + with: + node-version: '12' + + # get lotus deps... + - run: sudo apt install bzr + + - run: npm install + - run: npm test + - run: npm run build + + # Pin the built site to ipfs-cluster, output the cid as `steps.ipfs.outputs.cid` + # see: https://github.com/ipfs-shipyard/ipfs-github-action + - uses: ipfs-shipyard/ipfs-github-action@v2.0.0 + id: ipfs + with: + path_to_add: public + cluster_host: /dnsaddr/cluster.ipfs.io + cluster_user: ${{ secrets.CLUSTER_USER }} + cluster_password: ${{ secrets.CLUSTER_PASSWORD }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - run: echo /ipfs/${{ steps.ipfs.outputs.cid }} + + - run: echo ${{ github.ref }} + + # Update the dnslink if changes to the current branch should go live + # see https://github.com/ipfs-shipyard/js-dnslink-dnsimple + - run: npx dnslink-dnsimple --domain spec.filecoin.io --link /ipfs/${{ steps.ipfs.outputs.cid }} + env: + DNSIMPLE_TOKEN: ${{ secrets.DNSIMPLE_TOKEN }} + # TODO: change to master once merged. + if: github.ref == 'refs/heads/master' diff --git a/.gitignore b/.gitignore index d9de10541..269b09ae5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,8 @@ .vscode .idea public/ -deps/ -.slime/ -build/ -hugo/resources -hugo/content/docs -hugo/content/ox-hugo -hugo/content/codeGen/main .DS_Store -*.gen.go -hugo/data/version.yml -pkg/ -tools/codeGen/codeGen +yarn.lock +node_modules +resources +static/_gen \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e4c7b982c..000000000 --- a/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "orient"] - path = orient - url = https://github.com/filecoin-project/orient.git -[submodule "hugo/themes/book"] - path = hugo/themes/book - url = https://github.com/alex-shpak/hugo-book -[submodule "src/actors"] - path = src/actors - url = https://github.com/filecoin-project/specs-actors.git diff --git a/.remarkrc.yaml b/.remarkrc.yaml new file mode 100644 index 000000000..723a30ace --- /dev/null +++ b/.remarkrc.yaml @@ -0,0 +1,15 @@ +plugins: + # make remark aware of fontmatter. + remark-frontmatter: + # sensible linter defaults see: https://github.com/remarkjs/remark-lint/tree/main/packages/remark-preset-lint-recommended#rules + remark-preset-lint-recommended: + # add extra rules + remark-lint-heading-increment: + remark-lint-fenced-code-flag: + remark-lint-first-heading-level: + remark-lint-no-hr-after-heading: + # disable some of the sensible defaults given where we are today. + remark-lint-list-item-indent: false + remark-lint-final-newline: false + remark-lint-no-literal-urls: false + remark-lint-list-item-bullet-indent: false \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index fdb45aab2..000000000 --- a/Makefile +++ /dev/null @@ -1,274 +0,0 @@ -# guidelines for editing this makefile: -# -# - keep it simple -- put complicated commands into scripts inside bin/ (eg install-deps.sh) -# - document targets in the 'help' target -# - distinguish main targets (meant for users) from intermediate targets -# - if you write a new tool that requires compilation: -# add a compilation target here and move the binary into bin/ -# - if you add a dependency on another tool: -# make sure you edit install-deps.sh to install or prompt to install it -# - keep diagrams/builsys/buildsys.dot in sync with the targets here -# that is a diagram that is meant to make it easy to understand everything here. - -help: - @echo "SYNOPSIS" - @echo " make -- filecoin spec build toolchain commands" - @echo "" - @echo "USAGE" - @echo " make deps-ga run this once, to instlal & build partial dependencies for Github Actions" - @echo " make deps-basic run this once, to install & build basic dependencies" - @echo " make build run this every time you want to re-build artifacts" - @echo "" - @echo "MAIN TARGETS" - @echo " make help description of the targets (this message)" - @echo " make build build all final artifacts (website only for now)" - @echo " make test run all test cases (test-code only for now)" - @echo " make drafts publish artifacts to ipfs and show an address" - @echo " make publish publish final artifacts to spec website (github pages)" - @echo " make clean removes all build artifacts. you shouldn't need this" - @echo " make serve start hugo in serving mode -- must run 'make build' on changes manually" - @echo "" - @echo "INSTALL DEPENDENCIES" - @echo " make deps install ALL dependencies of this tool chain" - @echo " make deps-ga install Github Action specific dependencies" - @echo " make deps-basic install minimal dependencies of this tool chain" - @echo " make deps-diag install dependencies for rendering diagrams" - @echo " make deps-orient install dependencies for running orient" - @echo " make deps-ouser install dependencies for orient user-environment tooling" - @echo " make bins compile some build tools whose source is in this repo" - @echo "" - @echo "INTERMEDIATE TARGETS" - @echo " make website build the website artifact" - @#echo " make pdf build the pdf artifact" - @echo " make diagrams build diagram artifacts ({dot, mmd} -> svg)" - @echo " make org2md run org mode to markdown compilation" - @echo "" - @echo "HUGO TARGETS" - @echo " make hugo-src copy sources into hugo dir" - @echo " make build-hugo run the hugo part of the pipeline" - @echo " make watch-hugo watch and rebuild hugo" - @echo "" - @echo "CODE TARGETS" - @echo " make gen-code generate code artifacts (eg id -> go)" - @echo " make test-code run test cases in code artifacts" - @echo " make build-code build all src go code (test it)" - @echo " make clean-code remove build code artifacts" - @echo " make watch-code watch and rebuild code" - @echo "" - @echo "CLEAN TARGETS" - @echo " make clean remove all build artifacts" - @echo " make clean-deps remove (some of) the dependencies installed in this repo" - @echo " make clean-hugo remove intermediate hugo artifacts" - @echo " make clean-code remove build code artifacts" - @echo "" - @echo "WATCH TARGETS" - @echo " make serve-and-watch -j2 serve, watch, and rebuild all - works for live edit" - @echo " make watch-code watch and rebuild code" - @echo " make watch-hugo watch and rebuild hugo" - @echo "" - -# main Targets -build: diagrams build-code website - -test: test-code test-codeGen - -drafts: website - bin/publish-to-ipfs.sh - -publish: website - bin/publish-to-gh-pages.sh - -clean: .PHONY - rm -rf build - -# install dependencies - -deps: deps-basic deps-diag deps-orient - @# make bins last, after installing other deps - @# so we re-invoke make. - make bins - -deps-ga: - bin/install-deps-ga.sh -y - -deps-basic: - bin/install-deps-basic.sh -y - -deps-ouser: - bin/install-deps-orient-user.sh -y - -deps-orient: submodules - bin/install-deps-orient.sh -y - -deps-diag: - bin/install-deps-diagrams.sh -y - -submodules: - git submodule update --init --recursive - -clean-deps: .PHONY - @echo "WARNING: this does not uninstall global packages, sorry." - @echo " If you would like to remove them, see bin/install-deps.sh" - -rm -r deps - -git checkout ./deps/package.json - -rm -r .slime - -rm -r bin/.emacs - -# intermediate targets -# NOTE: For now, disable org2md — must manually generate until batch-mode build issues are resolved. -website: diagrams build-hugo # org2md - mkdir -p build/website - -rm -rf build/website/* - mv hugo/public/* build/website - @echo TODO: add generate-code to this target - -pdf: diagrams build-hugo # org2md - @echo TODO: add generate-code to this target - bin/build-pdf.sh - -build-hugo: hugo-src $(shell find hugo/content | grep '.md') - cd hugo && hugo - -hugo-src: $(shell find src | grep '.md') hugo/data/version.yml - rm -rf hugo/content/docs - cp -r src hugo/content/docs - # ox-hugo exports to src/content, so we need to copy that also. - cp -R src/content/ hugo/content/docs - mkdir -p hugo/content/ox-hugo - cp src/static/ox-hugo/* hugo/content/ox-hugo - -# run this every time. -hugo/data/version.yml: src/version.yml .PHONY - bin/write-spec-version.sh <$< >$@ - -# this is used to get "serve-and-watch" working. trick is to use -hugo-src-rsync: $(shell find src | grep '.md') gen-code diagrams - @mkdir -p hugo/content/docs - rsync -av --inplace src/ hugo/content/docs - printf " " >> hugo/content/_index.md # force reload - printf " " >> hugo/content/menu/index.md # force reload - -watch-hugo: .PHONY - bin/watcher --cmd="make hugo-src-rsync" --startcmd src 2>/dev/null - -clean-hugo: .PHONY - rm -rf hugo/content/docs - -all-orient: .PHONY orient - bin/build-spec-orient.sh - -ORIENT_FILES=$(shell find src -name '*.orient') -ORIENT_INPUT_FILES= $(patsubst %.orient, %.json, $(ORIENT_FILES)) -ORIENT_OUTPUT_FILES=$(patsubst src/%.orient, build/%.orient.json, $(ORIENT_FILES)) -orient: $(ORIENT_OUTPUT_FILES) - -$(ORIENT_OUTPUT_FILES): build/%.orient.json: src/%.orient src/%.json - bin/solve-orient.sh $+ $@ - -# convert orgmode to markdown -ORG_FILES=$(shell find src | grep .org) -ORG_MD_FILES=$(patsubst %.org, %.md, $(ORG_FILES)) -org2md: $(ORG_MD_FILES) -%.md: %.org - # use emacs to compile. - # cd to each target's directory, run there - # this should invoke orient - # this should produce hugo markdown output - - # Skip this until batch-mode build issues are resolve. - # bin/org2hugomd.el <$< >$@ - - -# building our tools -bins: bin/codeGen bin/watcher - -bin/codeGen: $(shell find tools/codeGen | grep .go) - cd tools/codeGen && go build -o ../../bin/codeGen - -bin/watcher: - go get -u github.com/radovskyb/watcher/... - go build -o $@ github.com/radovskyb/watcher/cmd/watcher - -test-codeGen: bin/codeGen - cd tools/codeGen && go build && go test ./... - # cd tools/codeGen/test_cases && make test # this is broken - -# other - -serve: build-hugo .PHONY - echo "run 'make website' and refresh to update" - cd hugo && hugo serve --noHTTPCache - -serve-website: website .PHONY - # use this if `make serve` breaks - echo "run 'make website' and refresh to update" - cd build/website && python -m SimpleHTTPServer 1313 - -serve-and-watch: serve watch-hugo - echo "make sure you run this with 'make -j2'" - -.PHONY: - -# code generation and building targets - -GO_INPUT_FILES=$(shell find src -iname '*.go' | grep -v ^src/actors) -GO_OUTPUT_FILES=$(patsubst src/%.go, build/code/%.go, $(GO_INPUT_FILES)) - -GO_UTIL_INPUT_FILE=tools/codeGen/util/util.go -GO_UTIL_OUTPUT_FILE=build/code/util/util.go - -$(GO_UTIL_OUTPUT_FILE): $(GO_UTIL_INPUT_FILE) - mkdir -p $(dir $@) - cp $< $@ - -build/code/%.go: src/%.go - mkdir -p $(dir $@) - cp $< $@ - -ID_FILES=$(shell find src -name '*.id') -GEN_GO_FILES=$(patsubst src/%.id, build/code/%.gen.go, $(ID_FILES)) -build/code/%.gen.go: src/%.id bin/codeGen - mkdir -p $(dir $@) - -bin/codeGen gen $< $@ - -gen-code: bin/codeGen build/code/go.mod $(GEN_GO_FILES) $(GO_OUTPUT_FILES) $(GO_UTIL_OUTPUT_FILE) - -build/code/go.mod: src/build_go.mod - mkdir -p $(dir $@) - cp $< $@ - -build-code: gen-code - cd build/code && go build -gcflags="-e" ./... - -test-code: build-code - cd build/code && go test ./... - -clean-code: - rm -rf build/code - -fmt-code: bin/codeGen - bin/codeGen fmt ./src/... - go fmt ./src/... - go fmt ./tools/... - go fmt ./build/code/... - -watch-code: .PHONY - bin/watcher --cmd="make build-code" --startcmd src 2>/dev/null - -## diagrams - -DOTs=$(shell find src -name '*.dot') -MMDs=$(shell find src -name '*.mmd') -SVGs=$(DOTs:%=%.svg) $(MMDs:%=%.svg) - -diagrams: ${SVGs} - -watch-diagrams: diagrams - bin/watcher --cmd="make diagrams" --startcmd src 2>/dev/null - -%.dot.svg: %.dot - @which dot >/dev/null || echo "requires dot (graphviz) -- run make deps" && exit - dot -Tsvg $< >$@ - -%.mmd.svg: %.mmd %.mmd.css - deps/node_modules/.bin/mmdc -i $< -o $@ --cssFile $(word 2,$^) diff --git a/README.md b/README.md index a8ff4e26c..bc1572a9d 100644 --- a/README.md +++ b/README.md @@ -1,166 +1,290 @@ -# Filecoin Specification -[![CircleCI](https://circleci.com/gh/filecoin-project/specs/tree/master.svg?style=svg)](https://circleci.com/gh/filecoin-project/specs/tree/master) +# Filecoin Specification +![CI](https://github.com/filecoin-project/specs/workflows/CI/badge.svg) This is the [Filecoin Specification](https://github.com/filecoin-project/specs), a repository that contains documents, code, models, and diagrams that constitute the specification of the [Filecoin Protocol](https://filecoin.io). This repository is the singular source of truth for the Filecoin Protocol. All implementations of the Filecoin Protocol should match and comply with the descriptions, interfaces, code, and models defined in this specification. -Note that the `master` branch of the specs moves quickly. We work to merge PRs as fast as possible into master, which means changes or reversals are possible here. Accordingly, we periodically compile swaths of spec along with a high-level difflog into the `release` branch. As the spec stabilizes, this practice will change. +Note that the `beta` branch of the specs moves quickly. We work to merge PRs as fast as possible into master, which means changes or reversals are possible here. Accordingly, we periodically compile swaths of spec along with a high-level difflog into the `release` branch. As the spec stabilizes, this practice will change. -## View Website +## Website -https://filecoin-project.github.io/specs is the user-friendly website rendering, which we recommend for reading this repository. The website is updated automatically with every merge to `master`. +https://beta.spec.filecoin.io is the user-friendly website rendering, which we recommend for reading this repository. The website is updated automatically with every merge to `beta`. -## Contributing +## Previous version +You can find the previous version of the Filecoin Spec in the master branch [here](https://github.com/filecoin-project/specs/tree/master). -Please [read the spec process](https://filecoin-project.github.io/specs/#intro__process). Please file PRs on github with fixes. - -## Develop +## Install -### Install +```sh +git clone https://github.com/filecoin-project/specs.git +yarn install +``` -- Make sure you have installed `go` on your machine. +## Develop +You need to have [Go](https://golang.org/doc/install) and `bzr` installed (required to build lotus) +```bash +brew install go bzr ``` -git clone https://github.com/filecoin-project/specs filecoin-specs -cd filecoin-specs -make deps-basic + +### Serve with Live Reload +```sh +yarn start +# open http://localhost:1313/ in the browser ``` -### Build +### Check your markdown -``` -make build -``` +We have a markdown linter set up to check for common errors like incorrectly nested headers. It runs in CI and you can run it locally with: -### Serve +```bash +npm test +content/algorithms/crypto/randomness.md + 15:39-15:46 warning Found reference to undefined definition no-undefined-references remark-lint + 54:24-54:31 warning Found reference to undefined definition no-undefined-references remark-lint -``` -make serve +⚠ 2 warnings ``` -This will write out an HTTP address to check out with your browser. Most likely: http://localhost:1313 +### Solving Common problems -### Update actors +**Problem** - Site fails to build with an error that states it faled to download modules on macos -The actor code lives in https://github.com/filecoin-project/specs-actors. It is imported: +``` +Error: failed to download modules: go command failed ... +``` -- into the compilation as a Go module, configured in src/build_go.mod -- into the webside as a Git submodule at src/actors +**Solution** - run `npm run clean` - the cache dir hugo uses can get corrupted, and this resets it. See [#1048](https://github.com/filecoin-project/specs/issues/1048) -To change the code, edit in the home repository and then update _both_ the build_go.mod and submodule to point to the new ref. -You should probably make a release of the specs-actors repo for ease of referring to it as a Go module. -### Website +### External modules +External modules should be added as [Hugo Modules](https://gohugo.io/hugo-modules/) +You can find examples in the `config.toml` +```toml +[module] + [[module.imports]] + path = "github.com/filecoin-project/specs-actors" + [[module.imports.mounts]] + source = "." + target = "content/externals/specs-actors" ``` -make website -``` +> `target` should **ALWAYS** use the folder `content/externals` + +This makes files from external repos available for Hugo rendering and allows for linking to up-to-date files that are directly pulled from other repositories. -### Diagrams +The configuration above gives the following information: -Install dependencies for diagram making +- `path`: Repository's URL without protocol. +- `source`: Folder from the repository referenced in the `path` to be mounted into the local Hugo filesystem. +- `target`: Folder where `source` will be mounted locally, this should follow this structure `content/modules/`. + +Example: if you want to link/embed to the file `xyz.go` that lives in `https://github.com/filecoin-project/specs-actors/actors/xyz-folder/xyz.go`, from within a markdown file then with the above configuration the `src` for shortcodes or markdown image syntax would be: ``` -make deps-diag +{{}} ``` +> The first foward slash is important it means the path is relative to the content folder. -Render diagrams +These modules can be updated with +```sh +hugo mod get -u ``` -make diagrams +or to a specific version with + +```sh +hugo mod get github.com/filecoin-project/specs-actors@v0.7.2 ``` -Make sure to check in your rendered output (`*.dot.svg` and `*.mmd.svg`) so that others dont need to install diagram building deps. +## Page Header +The first heading should be an atx style heading `# Head` and should refer to the overall title of the document. -### Orient and Org mode +```md +--- +title: Storage Power Actor +--- -Install dependencies for org mode and orient +# Storage Power Actor +## Header for a section in this document +Some text + +### Sub header for the a nested section + +## Another top level header ``` -make deps-orient + +## Frontmatter + +Description for all the available frontmatter properties + +```md + +title: Libraries + +description: Libraries used from Filecoin + +weight: 3 + +bookCollapseSection: true + +bookhidden: true + +dashboardWeight: 2 + +dashboardState: stable + +dashboardAudit: wip + +dashboardAuditURL: https://url.to.the.report + +dashboardAuditDate: "2020-08-01" + +dashboardTests: 0 ``` -Without these, you won't be able to compile `.org` files, and they may be missing from the document output. +## Code fences + +Code fences should **always** have a lang, if you don't know or don't care just use `text` + +```text + +```text +Random plain text context ... +`` + +``` -## Overviews +## Images, diagrams - Markdown images +To add an image or diagram you just need to use normal markdown syntax. +For diagrams you can use the source files and the pipelines will handle converting that to `svg`, we support mermaid and dot source files. -### Build System Overview +```md +# relative to the markdown file +![Alt text](picture.jpg) -Given the complexity of the protocol, a build system is introduced to leverage the power of modern programs and improve understanding, efficiency, consistency, and velocity of Filecoin spec development. The Filecoin spec is organized into subcomponents as defined in `src/` with high-level and introductory sections in `Introduction` and `Algorithmns`, detailed spec on different Filecoin systems in `Systems`, followed by `Listings`, `Glossary`, and `Appendix`. +# relative to the content folder +![Alt text](/content/intro/diagram1.mmd) -For every subsystem in the Filecoin spec, it must always have a markdown file that specifies the component. Wherever possible and necessary, an `.id` file should be included to automatically generate compiled `.go` files that can be tested to ensure build consistency and served from `hugo`. Similarly, contributors should include an `.orient` file that describes mathematical constraints in a component of the system. `Orient`, a language created to write constraints and models about the system, is used to perform ubercalc and generate artifacts about the system. To facilitate in line code display, an `.org` file can also be included to interweave output from ubercalc and markdown. +![Alt text](graph.dot "Graph title") +``` +> When there's no title we use the alt text as title - -#### Adding new sections +## References - Markdown links +These links use "portable links" just like `relref` so you can just give it the name of the file and it will fetch the correct relative link and title for the `` automatically. +You can override the `` title by passing a second `string` in the link definition. -The specification is broken down into 5 levels (`#.#.#.#.#`). The L1 and L2 numbers in this sequence are determined by the first two directories extending from `/src/`; for example, `/src/systems/filecoin_mining/` resolves to `2.6.`. +> **Note**: When using anchors the title can't be fetched automatically. +```md +[](storage_power_consensus) +# Storage Power Consensus -The L3 number is generated by creating an additional directory within a L2 directory, containing its own appropriately formatted `index.md`. This new directory name must then be added to the `entries` field of the L2 `index.md` file, sequentially ordered as they are to be within the specification. +[Storage Power](storage_power_consensus "Title to override the page original title") +# Storage Power -Further L4 and L5 subsections are added using the `##` and `###` headers respectively within a the content of a L3 section's `index.md` file. +[Tickets](storage_power_consensus#the-ticket-chain-and-drawing-randomness "The Ticket chain and drawing randomness") +# Tickets -### System Overview +``` - -## Detailed Build Usage +## Shortcodes +### `Mermaid` +Inline mermaid syntax rendering +```html +{{< mermaid >}} +graph TD + A[Christmas] -->|Get money| B(Go shopping) + B --> C{Let me think} + C -->|One| D[Laptop] + C -->|Two| E[iPhone] + C -->|Three| F[fa:fa-car Car] + +{{}} +``` -```makefile -> make help -SYNOPSIS - make -- filecoin spec build toolchain commands +### `hint` +```md + +{{< hint info >}} +**Markdown content** +Lorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat +stringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa +{{< /hint >}} +``` +### `embed` +```md +# src relative to the page +{{}} -USAGE - make deps-basic run this once, to install & build basic dependencies - make build run this every time you want to re-build artifacts +# src relative to content folder +{{}} +``` -MAIN TARGETS - make help description of the targets (this message) - make build build all final artifacts (website only for now) - make test run all test cases (test-code only for now) - make drafts publish artifacts to ipfs and show an address - make publish publish final artifacts to spec website (github pages) - make clean removes all build artifacts. you shouldn't need this - make serve start hugo in serving mode -- must run 'make build' on changes manually +## Math mode +For short snippets of math text you can just use the `{{}}` shortcode, but if you need to write lots of math in a page you can just use `math-mode` and avoid writting the katex shortcode everywhere. -INSTALL DEPENDENCIES - make deps install ALL dependencies of this tool chain - make deps-basic install minimal dependencies of this tool chain - make deps-diag install dependencies for rendering diagrams - make deps-orient install dependencies for running orient - make deps-ouser install dependencies for orient user-environment tooling - make bins compile some build tools whose source is in this repo +Parses math typesetting with [KaTeX](https://katex.org/docs/api.html) -INTERMEDIATE TARGETS - make website build the website artifact - make diagrams build diagram artifacts ({dot, mmd} -> svg) - make org2md run org mode to markdown compilation +Check this example [example](https://deploy-preview-969--fil-spec-staging.netlify.app/math-mode/) -HUGO TARGETS - make hugo-src copy sources into hugo dir - make build-hugo run the hugo part of the pipeline - make watch-hugo watch and rebuild hugo +> Some syntax like `\_` can't go through HUGO markdown parser and for that reason we need to wrap math text with code blocks, code fendes or the shortcode `{{}}`. See examples below. +### Add `math-mode` prop to the Frontmatter +```md +--- +title: Math Mode +math-mode: true +--- +``` -CODE TARGETS - make gen-code generate code artifacts (eg id -> go) - make test-code run test cases in code artifacts - make build-code build all src go code (test it) - make clean-code remove build code artifacts - make watch-code watch and rebuild code +### Wrap `def`, `gdef`, etc. +Math text needs to be wrapped to avoid Hugo's Markdown parser. When wrapping defs or any math block that doesn't need to be rendered the recommended option is to use the shortcode `{{}} +``` -CLEAN TARGETS - make clean remove all build artifacts - make clean-deps remove (some of) the dependencies installed in this repo - make clean-hugo remove intermediate hugo artifacts - make clean-code remove build code artifacts +### Wrap inline math text with code blocks +```md +The index of a node in a `$\BinTree$` layer `$l$`. The leftmost node in a tree has `$\index_l = 0$`. +``` -WATCH TARGETS - make serve-and-watch -j2 serve, watch, and rebuild all - works for live edit - make watch-code watch and rebuild code - make watch-hugo watch and rebuild hugo +### Wrap math blocks with code fences +~~~md +```text +$\overline{\underline{\Function \BinTree\dot\createproof(c: \NodeIndex) \rightarrow \BinTreeProof_c}}$ +$\line{1}{\bi}{\leaf: \Safe = \BinTree\dot\leaves[c]}$ +$\line{2}{\bi}{\root: \Safe = \BinTree\dot\root}$ + +$\line{3}{\bi}{\path: \BinPathElement^{[\BinTreeDepth]}= [\ ]}$ +$\line{4}{\bi}{\for l \in [\BinTreeDepth]:}$ +$\line{5}{\bi}{\quad \index_l: [\len(\BinTree\dot\layer_l)] = c \gg l}$ +$\line{6}{\bi}{\quad \missing: \Bit = \index_l \AND 1}$ +$\line{7}{\bi}{\quad \sibling: \Safe = \if \missing = 0:}$ +$\quad\quad\quad \BinTree\dot\layer_l[\index_l + 1]$ +$\quad\quad\thin \else:$ +$\quad\quad\quad \BinTree\dot\layer_l[\index_l - 1]$ +$\line{8}{\bi}{\quad \path\dot\push(\BinPathElement \thin \{\ \sibling, \thin \missing\ \} \thin )}$ + +$\line{9}{\bi}{\return \BinTreeProof_c \thin \{\ \leaf, \thin \root, \thin \path\ \}}$ ``` +~~~ + +## References +- [hugo theme book](https://themes.gohugo.io//theme/hugo-book/docs/shortcodes/columns/) +- [Katex](https://katex.org/) +- [Mermaid](https://mermaid-js.github.io/mermaid/#/) + - [config](https://github.com/mermaid-js/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults) + - [editor](https://mermaid-js.github.io/mermaid-live-editor) +- [Pan/Zoom for SVG](https://github.com/anvaka/panzoom) +- [Icons](https://css.gg/) +- [Working with submodules](https://github.blog/2016-02-01-working-with-submodules/) diff --git a/assets/_code.scss b/assets/_code.scss new file mode 100644 index 000000000..527ae4ecf --- /dev/null +++ b/assets/_code.scss @@ -0,0 +1,4 @@ +.markdown pre { + max-height: 450px; + overflow: auto; +} \ No newline at end of file diff --git a/assets/_colors.scss b/assets/_colors.scss new file mode 100644 index 000000000..88cc3bc19 --- /dev/null +++ b/assets/_colors.scss @@ -0,0 +1,24 @@ +// Colors + + +.text-missing {color: $red;} +.text-incorrect {color: $orange;} +.text-wip {color: $yellow;} +.text-reliable {color: $green;} +.text-stable {color: $blue;} +.text-transparent { color: transparent;} +.text-black { color: black !important;} + +.bg-na { background-color: #6c8293;} +.bg-missing { background-color: $red; } +.bg-incorrect {background-color: $orange;} +.bg-wip {background-color: $yellow;} +.bg-done {background-color: $green; } +.bg-reliable {background-color: $green; } +.bg-stable { background-color: $blue; + a { + color: black; + } +} +.bg-transparent { background-color: transparent;} +.bg-black { background-color: black;} \ No newline at end of file diff --git a/assets/_custom.scss b/assets/_custom.scss new file mode 100644 index 000000000..183f5cd3b --- /dev/null +++ b/assets/_custom.scss @@ -0,0 +1,523 @@ +/* You can add custom styles here. */ + +// Addons + +@import "plugins/numbered"; +@import "plugins/scrollbars"; +@import "plugins/toggles"; +@import "table-sort"; +@import "colors"; +@import "dashboard"; +@import "plugins/toc"; +@import "katex"; +@import "icons"; +@import "code"; +@import "plugins/lightbox"; + + +.markdown { + overflow-x: hidden; + h1, h2, h3, h4, h5, h6 { + padding-top: 1.5rem; + margin-bottom: 1rem; + a { + color: inherit; + text-decoration: none; + &:visited { + color:inherit; + } + &:hover { + text-decoration: none; + &::after { + font-size: 70%; + padding-left:0.3em; + color: $color-link; + content: " #" + } + } + } + } +} +.section-badges { + float: right; + margin-top:-2.5rem; +} + +// SVG Diagrams +.diagrams-container { + margin: 20px 0px; + border: 1px solid $gray-200; + border-radius: $border-radius; +} +.diagrams { + height: 400px; + overflow: hidden; + outline: none; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; +} +.diagrams img { + max-height: 100%; + max-width: 100%; + display: flex; + justify-content: center; + align-items: center; +} +.diagrams:active { + cursor: grabbing; +} +.diagrams-caption { + border-top: 1px solid #e9ecef; + padding: 0.5rem; + font-size: 12px; + font-weight: 500; + .diagrams-link { + text-decoration: none !important; + float:right; + font-weight: 400; + } +} + +// search +#book-search-results { + width: 100%; + padding: 1px .5rem; + border: 0; + border-radius: .25rem; + background: $book-search-results-bg; + margin-top: 3px; +} + +#book-search-results:empty { + display: none; +} + +#book-search-input { + outline: none; +} + +// Tweaks +html { + scroll-behavior: auto; + touch-action: auto; +} +.container { + max-width: 89rem; +} +.book-menu { + flex: 0 0 20rem; +} +.book-page { + padding-top: 0rem; + padding-left: 2rem; + max-width: 52rem; +} + +summary { + outline: none; +} +blockquote { + overflow: auto; +} +.book-menu nav { + width: 20rem; + height: 100%; + padding: 1rem 0.2rem 1rem 1rem; + position: fixed; + top: 0; + bottom: 0; + overflow: hidden; +} +.book-menu .toc { + height: 100%; + overflow: hidden; +} + +.markdown>h1:first-of-type { + margin-top: 0; +} + +.markdown code, code { + margin: 0 1px; + padding: 3px 6px; + font-size: 85%; + border-radius: 3px; + line-height: 16px; + box-decoration-break: clone; +} +.book-brand img { + height: 40px; + width: auto; + vertical-align: middle; + margin-inline-end: .5rem; +} +.book-toc { + flex: 0 0 12rem; + font-size: .75rem; +} +.book-toc div { + padding: 1rem; + position: fixed; + width: 12rem; +} +.book-toc > div nav { + width: auto; + position: relative; + padding: 0; + height: 90vh; +} +.book-menu > nav .toc::-webkit-scrollbar, +.book-toc > div nav::-webkit-scrollbar{ + width: 8px; +} + +.book-menu > nav .toc::-webkit-scrollbar-thumb, +.book-toc > div nav::-webkit-scrollbar-thumb{ + background: transparent; +} + +.book-menu > nav:hover .toc::-webkit-scrollbar-thumb, +.book-toc > div nav:hover .toc::-webkit-scrollbar-thumb{ + background: rgba(255,255,255,.1); +} + +@media screen and (max-width: 56rem) { + .book-page { + padding-left:1rem; + } + .book-menu { + visibility: hidden; + margin-inline-start: -20rem; + } + #menu-control:checked~main .book-menu nav { + transform: translateX(20rem); + } + .toc-label { + font-weight:700; + font-size:10px; + .gg-menu-motion { + display: none; + } + } + .book-header { + margin-bottom: 2rem; + position: fixed; + width: 100%; + background: white; + z-index: 1; + padding: 5px 0.6rem; + box-shadow: 1px 0 2px 0px rgba(0,0,0,0.2); + } + #toc-depth-slider { + display:none; + } +} + +.book-toc { + .book-toc-toggles { + top:0px; + opacity: 0.4; + transition: opacity 0.3s ease-in-out; + } + .book-toc-toggles:hover { + opacity: 1; + } + .toc { + top:78px; + } +} + +.toc-label, .dark-mode-toggle-label { + font-size: 10px; + font-weight: 700; + display: block; + color:$gray-600; +} +.gg-menu-motion, .gg-dark-mode { + display: inline-block; + margin-left: 0; + margin-right: 0; + vertical-align: middle; + font-size: 10px; + transform: scale(0.7); +} + +// Colors +.color-incorrect { + color: #BF616A; +} + +.color-wip { + color: #D08770; +} + +.color-incomplete { + color: #EBCB8B; +} + +.color-stable { + color: #5E81AC; +} + +.color-permanent { + color: #A3BE8C; +} + +i[class^="gg-"] { + display: inline-block; + margin-left: 3px; + margin-right: 3px; + vertical-align: text-top; + line-height: 1.6; +} + +// Icons +.gg-permanent { + color: #A3BE8C; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--ggs,1)); + width: 20px; + height: 20px; + border: 2px solid; + border-radius: 100px + } + + .gg-permanent::after { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + left: 2px; + top: -2px; + width: 6px; + height: 10px; + border-color: currentColor; + border-width: 0 2px 2px 0; + border-style: solid; + transform-origin: bottom left; + transform: rotate(45deg) +} +.gg-stable { + color: #5E81AC; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--ggs,1)); + width: 20px; + height: 20px; + border: 2px solid; + border-radius: 40px + } + + .gg-stable::after, + .gg-stable::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + border-radius: 3px; + width: 2px; + background: currentColor; + left: 7px + } + + .gg-stable::after { + bottom: 2px; + height: 8px + } + + .gg-stable::before { + height: 2px; + top: 2px +} +.gg-incorrect { + color: #BF616A; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--ggs,1)); + width: 20px; + height: 20px; + border: 2px solid; + border-radius: 40px + } + + .gg-incorrect::after, + .gg-incorrect::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + border-radius: 3px; + width: 2px; + background: currentColor; + left: 7px + } + + .gg-incorrect::after { + top: 2px; + height: 8px + } + + .gg-incorrect::before { + height: 2px; + bottom: 2px +} +.gg-incomplete { + color: #EBCB8B; + box-sizing: border-box; + position: relative; + display: block; + transform: rotate(45deg) scale(var(--ggs,1)); + width: 18px; + height: 18px; + border: 2px solid; + border-radius: 100% + } + + .gg-incomplete::after, + .gg-incomplete::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 2px; + height: 7px; + background: currentColor; + border-radius: 5px; + left: 6px + } + + .gg-incomplete::before { + top: -2px + } + + .gg-incomplete::after { + bottom: -2px +} +.gg-wip { + color: #D08770; + transform: scale(var(--ggs,1)) + } + + .gg-wip, + .gg-wip::after, + .gg-wip::before { + box-sizing: border-box; + position: relative; + display: block; + width: 20px; + height: 20px + } + + .gg-wip::after, + .gg-wip::before { + content: ""; + position: absolute; + border-radius: 100px + } + + .gg-wip::before { + animation: spinner 1s + cubic-bezier(.6,0,.4,1) infinite; + border: 3px solid transparent; + border-top-color: currentColor + } + + .gg-wip::after { + border: 3px solid; + opacity: .2 + } + + @keyframes spinner { + 0% { transform: rotate(0deg) } + to { transform: rotate(359deg) } +} + +.gg-menu-motion { + box-sizing: border-box; + position: relative; + display: block; + width: 18px; + height: 14px; + transform: scale(var(--ggs,1)) + } + + .gg-menu-motion::before { + content: ""; + position: absolute; + box-sizing: border-box; + display: block; + width: 10px; + height: 2px; + bottom: 0; + box-shadow: 4px -6px 0,8px -12px 0; + border-radius: 4px; + background: currentColor +} + +.gg-dark-mode { + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--ggs,1)); + border:2px solid; + border-radius:100px; + width:20px; + height:20px +} + +.gg-dark-mode::after, +.gg-dark-mode::before { + content: ""; + box-sizing: border-box; + position: absolute; + display: block +} + +.gg-dark-mode::before { + border:5px solid; + border-top-left-radius:100px; + border-bottom-left-radius:100px; + border-right: 0; + width:9px; + height:18px; + top:-1px; + left:-1px +} + +.gg-dark-mode::after { + border:4px solid; + border-top-right-radius:100px; + border-bottom-right-radius:100px; + border-left: 0; + width:4px; + height:8px; + right:4px; + top:4px +} + +.state-badge { + font-size: 10px; + font-weight: 500; +} +.state-badge-link { + text-decoration: none !important; + color: white !important; + &:hover { + text-decoration: none; + } +} +.state-badge-key, .state-badge-value { + padding: 2px 5px; +} +.state-badge-key { + background-color: #555; +} +.section-intro .state-badge { + display: none; +} \ No newline at end of file diff --git a/assets/_dashboard.scss b/assets/_dashboard.scss new file mode 100644 index 000000000..d09a2b4ba --- /dev/null +++ b/assets/_dashboard.scss @@ -0,0 +1,35 @@ +#dashboard-container { + // the dashboard is generated on the client, so it throws out in page anchor scrolling, so we set the heigt manually here. + // TODO: Fix properly. perhaps generating the table earlier in the page render could fix it... otherwise writing it into the dom as a post process. + height: 2850px; + overflow: auto +} +table.Dashboard { + display: table; + table-layout: fixed; + width: 100%; + font-size: 12px; + margin: 0; +} + +table.Dashboard { + th:first-child { + width: 50%; + } +} + +.Dashboard tr th, +.Dashboard tr td { + padding: 0 1rem !important; + text-align: center; +} +.Dashboard tr td:first-child { + text-align: left; +} + +.Dashboard-section { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + diff --git a/assets/_fonts.scss b/assets/_fonts.scss new file mode 100644 index 000000000..a146c8d93 --- /dev/null +++ b/assets/_fonts.scss @@ -0,0 +1,7 @@ +body { + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; +} + +code { + font-family: "/*[[font-choice]]*/", Consolas, "Liberation Mono", Menlo, Courier, monospace; +} diff --git a/assets/_icons.scss b/assets/_icons.scss new file mode 100644 index 000000000..1e734ef73 --- /dev/null +++ b/assets/_icons.scss @@ -0,0 +1,43 @@ +// Modifiers +.gg-s-half { + --ggs: 0.5 +} + + +// External Icon +.gg-external { + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--ggs,1)); + width: 12px; + height: 12px; + box-shadow: + -2px 2px 0 0, + -4px -4px 0 -2px, + 4px 4px 0 -2px; + margin-left: -2px; + margin-top: 1px +} +.gg-external::after, +.gg-external::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + right: -4px +} +.gg-external::before { + background: currentColor; + transform: rotate(-45deg); + width: 12px; + height: 2px; + top: 1px +} +.gg-external::after { + width: 8px; + height: 8px; + border-right: 2px solid; + border-top: 2px solid; + top: -4px +} \ No newline at end of file diff --git a/assets/_katex.scss b/assets/_katex.scss new file mode 100644 index 000000000..98b7c7bde --- /dev/null +++ b/assets/_katex.scss @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Math;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Math;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Script;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size1;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size2;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size3;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size4;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Typewriter;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype");font-weight:400;font-style:normal}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto;border-color:currentColor}.katex *{-ms-high-contrast-adjust:none!important}.katex .katex-version:after{content:"0.12.0"}.katex .katex-mathml{position:absolute;clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-weight:700;font-style:italic}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{display:inline-table;table-layout:fixed;border-collapse:collapse}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;vertical-align:bottom;position:relative}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;vertical-align:bottom;font-size:1px;width:2px;min-width:2px}.katex .vbox{-ms-flex-direction:column;flex-direction:column;align-items:baseline}.katex .hbox,.katex .vbox{display:-ms-inline-flexbox;display:inline-flex}.katex .hbox{-ms-flex-direction:row;flex-direction:row;width:100%}.katex .thinbox{display:inline-flex;flex-direction:row;width:0;max-width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{width:0;position:relative}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{display:inline-block;border:0 solid;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline{display:inline-block;width:100%;border-bottom-style:dashed}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .op-limits>.vlist-t{text-align:center}.katex .accent>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{display:block;position:absolute;width:100%;height:inherit;fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex svg path{stroke:none}.katex img{border-style:none;min-width:0;min-height:0;max-width:none;max-height:none}.katex .stretchy{width:100%;display:block;position:relative;overflow:hidden}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{width:100%;position:relative;overflow:hidden}.katex .halfarrow-left{position:absolute;left:0;width:50.2%;overflow:hidden}.katex .halfarrow-right{position:absolute;right:0;width:50.2%;overflow:hidden}.katex .brace-left{position:absolute;left:0;width:25.1%;overflow:hidden}.katex .brace-center{position:absolute;left:25%;width:50%;overflow:hidden}.katex .brace-right{position:absolute;right:0;width:25.1%;overflow:hidden}.katex .x-arrow-pad{padding:0 .5em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{box-sizing:border-box;border:.04em solid}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{text-align:left;padding-left:2em} diff --git a/assets/_table-sort.scss b/assets/_table-sort.scss new file mode 100644 index 000000000..79c9b2119 --- /dev/null +++ b/assets/_table-sort.scss @@ -0,0 +1,37 @@ +th[role=columnheader]:not(.no-sort) { + cursor: pointer; + position: relative; + min-width: 110px; +} + +th[role=columnheader]:not(.no-sort):after { + content: ''; + position: absolute; + top: -3px; + right: 10px; + margin-top: 10px; + border-width: 0 4px 4px; + border-style: solid; + border-color: #404040 transparent; + visibility: hidden; + opacity: 0; + -ms-user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +th[aria-sort=ascending]:not(.no-sort):after { + border-bottom: none; + border-width: 4px 4px 0; +} + +th[aria-sort]:not(.no-sort):after { + visibility: visible; + opacity: 0.4; +} + +th[role=columnheader]:not(.no-sort):hover:after { + visibility: visible; + opacity: 1; +} \ No newline at end of file diff --git a/assets/_variables.scss b/assets/_variables.scss new file mode 100644 index 000000000..b1c50d862 --- /dev/null +++ b/assets/_variables.scss @@ -0,0 +1,10 @@ +/* You can override SASS variables here. */ + +$red: #ff0010; +$orange: #ff6f00; +$yellow: #ffef00; +$green: #90ff00; +$blue: #0090ff; + +$book-search-results-bg: #f8f9fa !default; +$color-link: $blue; \ No newline at end of file diff --git a/assets/book-dark.scss b/assets/book-dark.scss new file mode 100644 index 000000000..ae14d7eee --- /dev/null +++ b/assets/book-dark.scss @@ -0,0 +1,17 @@ +@import "defaults"; +@import "variables"; + +// Import the dark overrides. This file is otherwise identical to dark.scss +@import "plugins/dark.scss"; + +@import "normalize"; +@import "utils"; +@import "main"; +@import "fonts"; +@import "print"; + +@import "markdown"; +@import "shortcodes"; + +// Custom defined styles +@import "custom"; diff --git a/assets/dark-mode/dark-mode.js b/assets/dark-mode/dark-mode.js new file mode 100644 index 000000000..5fe0f1d1b --- /dev/null +++ b/assets/dark-mode/dark-mode.js @@ -0,0 +1,46 @@ +// iife to avoid polluting the global. +(function () { + // Run me as soon as possible after the the css links are in the dom. + // This assumes this js file is added to the page after the css links. + const lightMode = document.getElementById('light-mode-link') + const darkMode = document.getElementById('dark-mode-link') + const btn = document.querySelector('.dark-mode-toggle') + let theme = 'light' + + function enableLightMode () { + lightMode.disabled = false + darkMode.disabled = true + btn.setAttribute('aria-pressed', theme === 'dark') + } + + function enableDarkMode () { + darkMode.disabled = false + lightMode.disabled = true + btn.setAttribute('aria-pressed', theme === 'dark') + } + + // wait for localstorage... + const previousChoice = localStorage.getItem('theme') + theme = previousChoice || theme + + // Light is default, so enable dark if user previously chose it. + if (theme === 'dark') { + enableDarkMode() + } + + // set up the toggle once the DOM is ready. + document.addEventListener("DOMContentLoaded", function(event) { + + btn.addEventListener('click', function () { + theme = (theme === 'light' ? 'dark' : 'light') + if (theme === 'dark') { + enableDarkMode() + } else { + enableLightMode() + } + localStorage.setItem('theme', theme) + }) + // init the button state to match the currently selected theme. + btn.setAttribute('aria-pressed', theme === 'dark') + }); +})() diff --git a/assets/js/content-model.js b/assets/js/content-model.js new file mode 100644 index 000000000..aa50912fe --- /dev/null +++ b/assets/js/content-model.js @@ -0,0 +1,62 @@ +// [ +// { text: "Foo", id: "foo", tagName: 'h1', children: [ +// { text: "Xyz", id: "xyz", tagName: 'h2', children: [ +// { text: "Bar", id: "bar", tagName: 'h3, children:[] } +// { text: "Bar", id: "bar", tagName: 'h3, children:[] } +// ]} +// ]}, +// { text: "Baz", id: "baz", tag: 'h1', children: [] } +// ] + +function buildTocModel (contentSelector) { + const model = [] + const headingList = document.querySelector(contentSelector).querySelectorAll('h1,h2,h3,h4,h5,h6') + let parents = [{tagName: 'H0', children: model}] + let prevSibling = null + for (let el of headingList) { + let node = { + id: el.id, + tagName: el.tagName, + text: cleanHeadingText(el), + page: Boolean(el.dataset.page), + dashboardWeight: el.dataset.dashboardWeight, + dashboardAudit: el.dataset.dashboardAudit, + dashboardAuditURL: el.dataset.dashboardAuditUrl, + dashboardAuditDate: el.dataset.dashboardAuditDate, + dashboardState: el.dataset.dashboardState, + children: [] + } + if (!prevSibling || headingNum(node) === headingNum(prevSibling)) { + parents[parents.length - 1].children.push(node) + prevSibling = node + + // is h3 > h2 ? + } else if (headingNum(node) > headingNum(prevSibling)) { + parents.push(prevSibling) + prevSibling.children.push(node) + prevSibling = node + } else { + // h2 or h1 after an h3... gotta find out how far to unwind, parents may not be contiguous in a bad doc, so we walk. + let prevParent = parents.pop() + while (headingNum(node) <= headingNum(prevParent)) { + prevParent = parents.pop() + } + prevParent.children.push(node) + parents.push(prevParent) + prevSibling = node + } + } + return model + } + + function cleanHeadingText (el) { + return el.textContent.trim() + } + + function headingNum (el) { + return Number(el.tagName[1]) + } + + export { + buildTocModel + } \ No newline at end of file diff --git a/assets/js/dashboard-spec.js b/assets/js/dashboard-spec.js new file mode 100644 index 000000000..149ae2b9c --- /dev/null +++ b/assets/js/dashboard-spec.js @@ -0,0 +1,76 @@ +import {html, render} from 'lit-html'; + +const tableData = (model, depth, output=[]) => { + const index = depth.length-1 + for (const node of model) { + depth[index] += 1 + output.push({number: depth.join("."), ...node}) + if (node.children) { + tableData(node.children, [...depth, 0], output) + } + } + return output +} + +const humanize = (input) => { + if(input === 'wip') { + return 'Draft/WIP' + } + + if(input === 'n/a') { + return '' + } + + return input.charAt(0).toUpperCase() + input.substr(1); +} + +const stateToNumber = (s) => { + switch (s) { + case 'done': + case 'stable': + return 1 + case 'reliable': + return 2 + case 'wip': + return 3 + case 'incorrect': + return 4 + case 'missing': + return 5 + default: + return 6 + } +} + +function buildDashboard(selector, model) { + const data = tableData(model, [0]) + const tpl = html` + + + + + + + + + + ${data.map((i)=> i.page ? html` + + + + + + `: '')} + +
SectionStateTheory Audit
${i.number} ${i.text}${humanize(i.dashboardState)} + ${i.dashboardAuditURL + ? html`${i.dashboardAuditDate}` + : humanize(i.dashboardAudit) } +
+ ` + render(tpl, document.querySelector(selector)) +} + +export { + buildDashboard +} \ No newline at end of file diff --git a/assets/js/katex.js b/assets/js/katex.js new file mode 100644 index 000000000..a7f520062 --- /dev/null +++ b/assets/js/katex.js @@ -0,0 +1,18 @@ +import renderMathInElement from 'katex/dist/contrib/auto-render.mjs' + +function renderKatex (target) { + renderMathInElement(target, { + ignoredTags: ["script", "noscript", "style", "textarea"], + throwOnError: false, + delimiters: [ + {left: "$$", right: "$$", display: true}, + {left: "$", right: "$", display: false}, + {left: "\\(", right: "\\)", display: false}, + {left: "\\[", right: "\\]", display: true} + ] + }) +} + +export { + renderKatex +} diff --git a/assets/js/lightbox.js b/assets/js/lightbox.js new file mode 100644 index 000000000..2842357c1 --- /dev/null +++ b/assets/js/lightbox.js @@ -0,0 +1,71 @@ +import zoomable from 'd3-zoomable'; + +function lightbox () { + const transitionSpeedInMilliseconds = 250; + + // template + const fragment = new DocumentFragment() + const container = document.createElement('div') + container.classList.add('lightbox-container') + + const zoom = document.createElement('div') + zoom.classList.add('lightbox-zoom') + + const img = document.createElement('img') + img.src = '' + img.classList.add('lightbox-image') + + container.appendChild(zoom) + zoom.appendChild(img) + fragment.appendChild(container) + document.body.appendChild(fragment) + + // init zoomable in the template + const myZoom = zoomable() + myZoom(container).htmlEl(zoom) + + // hook events + const elements = document.querySelectorAll('.zoomable img') + elements.forEach((element) => { + element.addEventListener('click', () => { + handleElementClick(element); + }); + }); + container.addEventListener('click', hideLightbox); + window.addEventListener('keyup', (event) => { + if (event.key === 'Escape') { + hideLightbox(); + } + }); + + function handleElementClick(htmlElement) { + img.attributes['src'].value = htmlElement.attributes['src'].value; + if (!isVisible()) { + container.classList.remove('hidden'); + container.classList.add('visible'); + document.body.classList.add('lightbox-body-scroll-stop') + } + } + + function hideLightbox() { + if (isVisible()) { + container.classList.add('hidden'); + + setTimeout(() => { + container.classList.remove('visible'); + container.classList.remove('hidden'); + document.body.classList.remove('lightbox-body-scroll-stop') + img.attributes['src'].value = ''; + myZoom.zoomReset() + }, transitionSpeedInMilliseconds); + } + } + + function isVisible() { + return container.classList.contains('visible'); + } + } + + export { + lightbox + } \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 000000000..c0feaf4a9 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,69 @@ +import '@pwabuilder/pwaupdate' +import { initToc } from './toc.js' +import tablesort from 'tablesort' +import Gumshoe from 'gumshoejs' +import { buildTocModel } from './content-model' +import { buildDashboard } from './dashboard-spec' +import { renderKatex } from './katex'; +import { lightbox } from './lightbox' +// Note: the tablesort lib is not ESM friendly, and the sorts expect `Tablesort` to be available on the global +window.Tablesort = tablesort +require('tablesort/dist/sorts/tablesort.number.min.js') + +function initTableSort () { + var elements = document.querySelectorAll(".tablesort") + elements.forEach(function (el) { + tablesort(el); + }) +} + +function initTocDepthSlider () { + var slider = document.getElementById('toc-depth-slider') + var toc = document.querySelector('.toc') + + slider.addEventListener('change', (event) => { + handleSliderChange(Number(event.target.value)) + }) + + function handleSliderChange (depth) { + for (let i = 0; i < 6; i++) { + toc.querySelectorAll(`.depth-${i}`).forEach(el => { + if (i < depth) { + el.classList.remove('maybe-hide') + } else { + el.classList.add('maybe-hide') + } + }) + } + } + // init to the current value + handleSliderChange(slider.value) +} + +function initTocScrollSpy () { + var spy = new Gumshoe('.toc a', { + nested: true, + nestedClass: 'active-parent' + }) +} + +window.addEventListener('DOMContentLoaded', () => { + const model = buildTocModel('.markdown') + initToc({tocSelector:'.toc', model }) + buildDashboard('#dashboard-container', model) + initTocDepthSlider() + initTocScrollSpy() + initTableSort() + lightbox() + // load katex when math-mode page intersect with the viewport + let observer = new IntersectionObserver((entries, observer) => { + entries.forEach(entry => { + if(entry.isIntersecting){ + renderKatex(entry.target) + observer.unobserve(entry.target); + } + }); + }); + document.querySelectorAll('.math-mode').forEach(img => { observer.observe(img) }); + +}); diff --git a/assets/js/toc.js b/assets/js/toc.js new file mode 100644 index 000000000..39afa3815 --- /dev/null +++ b/assets/js/toc.js @@ -0,0 +1,36 @@ +function initToc ({tocSelector, model}) { + const toc = buildTocDom(model) + document.querySelector(tocSelector).appendChild(toc) +} + +function buildTocDom (model) { + const parent = document.createDocumentFragment() + buildList(parent, model, 0) + return parent +} + +function buildList (parent, children, depth) { + let ol = createList(depth) + parent.append(ol) + for (node of children) { + let li = document.createElement('li') + let a = document.createElement('a') + a.setAttribute('href', '#' + node.id) + a.innerText = node.text + li.appendChild(a) + ol.append(li) + if (node.children) { + buildList(li, node.children, depth + 1) + } + } +} + +function createList(depth) { + const ol = document.createElement('ol') + ol.className = 'depth-' + depth + return ol +} + +export { + initToc +} diff --git a/assets/plugins/_dark.scss b/assets/plugins/_dark.scss new file mode 100644 index 000000000..5131ee6cd --- /dev/null +++ b/assets/plugins/_dark.scss @@ -0,0 +1,13 @@ +$gray-100: #232323; +$gray-200: #282a36; + +// https://www.colorhexa.com/090909 +$body-background: #090909; +$body-font-color: rgba(255, 255, 255, 0.80); + +$color-link: #0090ff; +$color-visited-link: #0090ff; + +$icon-filter: brightness(0) invert(1); + +$book-search-results-bg: rgba(255,255,255,.1); diff --git a/assets/plugins/_lightbox.scss b/assets/plugins/_lightbox.scss new file mode 100644 index 000000000..34a7c924d --- /dev/null +++ b/assets/plugins/_lightbox.scss @@ -0,0 +1,80 @@ +.lightbox-container { + transition: all 250ms ease-in-out; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #fff; + z-index: 1000; + justify-content: center; + align-items: center; + display: flex; + transform: scale(0); + opacity: 1; + cursor: zoom-out; + overflow: hidden; + will-change: transform; +} + +.lightbox-body-scroll-stop { + overflow: hidden; + // position:fixed; + width: 100%; +} + +.lightbox-container.visible { + animation-name: animate-in; + animation-duration: 250ms; + animation-fill-mode: forwards; +} +.lightbox-container.hidden { + animation: animate-out; + animation-duration: 250ms; + animation-fill-mode: forwards; +} + +.lightbox-zoom { + transform-origin: top left; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.lightbox-image { + max-width: 100%; + max-height: 100%; + width: auto; + height: 100%; + object-fit: contain; +} +@media (min-width: 768px) { + .lightbox-image { + max-width: 95%; + max-height: 95%; + } +} + +@keyframes animate-in { + 0% { + transform: scale(0); + opacity: 0; } + 1% { + transform: scale(0.9); + opacity: 0; } + 100% { + transform: scale(1); + opacity: 1; } } + + @keyframes animate-out { + 0% { + transform: scale(1); + opacity: 1; } + 99% { + transform: scale(0.9); + opacity: 0; } + 100% { + transform: scale(0); + opacity: 0; } } \ No newline at end of file diff --git a/assets/plugins/_numbered.scss b/assets/plugins/_numbered.scss new file mode 100644 index 000000000..b9821fab2 --- /dev/null +++ b/assets/plugins/_numbered.scss @@ -0,0 +1,49 @@ +$startLevel: 1; +$endLevel: 6; + +.book-page .markdown { + counter-reset: h1 h2 h3 h4 h5 h6; +} + +.book-page .markdown { + @for $currentLevel from $startLevel through $endLevel { + h#{$currentLevel} { + counter-reset: h#{$currentLevel + 1} 0; + counter-increment: h#{$currentLevel}; + } + $content: ""; + @for $n from $startLevel through $currentLevel { + $content: $content + 'counter(h#{$n})"."'; + } + + h#{$currentLevel}::before { + content: unquote($content) " "; + } + } +} + +.book-menu nav ol { + li { + counter-increment: item; + + &:first-child { + counter-reset: item; + } + + a:before { + content: counters(item, ".") " "; + float: left; + margin-inline-end: $padding-4; + color: $gray-600; + } + &.active { + &::before { + content: "⨎"; + color: $blue; + } + > a::before { + color: $blue; + } + } + } +} diff --git a/assets/plugins/_scrollbars.scss b/assets/plugins/_scrollbars.scss new file mode 100644 index 000000000..908c6980e --- /dev/null +++ b/assets/plugins/_scrollbars.scss @@ -0,0 +1,56 @@ +@import "defaults"; +@import "variables"; + +::-webkit-scrollbar { + width: 8.5px; + height: 8.5px; +} + +* { + -ms-overflow-style: -ms-autohiding-scrollbar; + scrollbar-width: thin; + scrollbar-color: transparent rgba(0, 0, 0, 0.3) ; +} + +::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.3); + border-radius: 6px; +} + +::-webkit-scrollbar-button, +::-webkit-scrollbar-track-piece, +::-webkit-scrollbar-corner, +::-webkit-resizer { display: none; } + +// code blocks +.markdown pre::-webkit-scrollbar { + display: none; +} +.markdown pre:hover::-webkit-scrollbar { + display: initial; +} + +.markdown pre { + scrollbar-color: transparent rgba(255, 255, 255, 0.1) ; +} + +.markdown pre::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.1); +} +.markdown pre::-webkit-scrollbar-thumb:active { + background-color: rgba(255, 255, 255, 0.3); +} + +// toc +.toc > ol::-webkit-scrollbar { + display: none; +} +.toc > ol:hover::-webkit-scrollbar { + display: initial; +} + + +// Future +.book-menu nav { + scrollbar-color: transparent $gray-500; +} diff --git a/assets/plugins/_toc.scss b/assets/plugins/_toc.scss new file mode 100644 index 000000000..cc4b337a5 --- /dev/null +++ b/assets/plugins/_toc.scss @@ -0,0 +1,54 @@ +.toc { + overflow-y: auto; + > ol { + height: 90%; + overflow: auto; + position: relative; + > li { + font-weight: 500; + } + } + > ol li { + list-style: none; + } + > ol > li > ol { + padding-bottom: 1rem; + font-weight: 400; + } + ol { + margin: 0; + padding-left: 10px; + } + a { + color: currentColor; + height: 100%; + } + li::before { + content: " "; + display: inline-block; + height: inherit; + left: 0; + margin-top: -1px; + position: absolute; + } + li:not(.active-parent) > .maybe-hide > li:not(.active) { + height:0; + } + li.active, + li.active-parent, + .maybe-hide li.active-parent, + li.active-parent > .maybe-hide > li { + height: auto; + } + ol li { + padding: 0 0; + line-height: 2; + font-size: 14px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + a.toc-link { + height: 100%; + } + } +} diff --git a/assets/plugins/_toggles.scss b/assets/plugins/_toggles.scss new file mode 100644 index 000000000..10c55189d --- /dev/null +++ b/assets/plugins/_toggles.scss @@ -0,0 +1,208 @@ +// edited from https://adrianroselli.com/2019/08/under-engineered-toggles-too.html +.toggle[aria-pressed] { + display: block; + box-sizing: border-box; + border: none; + color: inherit; + background: none; + font: inherit; + line-height: inherit; + text-align: left; + padding: .4em 0 .4em 4em; + position: relative; + +} + +.toggle[aria-pressed][disabled], +.toggle[aria-pressed][disabled]:hover { + color: #999; +} + +.toggle[aria-pressed]:focus, +.toggle[aria-pressed]:hover { + color: #00f; + outline: none; +} + +// .toggle[aria-pressed]:focus::before, +// .toggle[aria-pressed]:hover::before { +// box-shadow: 0 0 0.5em #333; +// } + +.toggle[aria-pressed]:focus::after, +.toggle[aria-pressed]:hover::after { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='50' cy='50' r='50' fill='rgba(0,0,0,.25)'/%3E%3C/svg%3E"); + background-size: 30%; + background-repeat: no-repeat; + background-position: center center; +} + +.toggle[aria-pressed]::before, +.toggle[aria-pressed]::after { + content: ""; + position: absolute; + height: 1.5em; + transition: all 0.25s ease; +} + +.toggle[aria-pressed]::before { + left: 0; + top: 0.2em; + width: 3em; + border: 0.2em solid #767676; + background: #767676; + border-radius: 1.1em; +} + +.toggle[aria-pressed]::after { + left: 0; + top: 0.25em; + background-color: #fff; + background-position: center center; + border-radius: 50%; + width: 1.5em; + border: 0.15em solid #767676; +} + +.toggle[aria-pressed=true]::after { + left: 1.6em; + border-color: #0090ff; + color: #0090ff; +} + +.toggle[aria-pressed=true]::before { + background-color: #0090ff; + border-color: #0090ff; +} + +.toggle[aria-pressed][disabled]::before { + background-color: transparent; + border-color: #ddd; +} + +.toggle[aria-pressed][disabled]::after { + border-color: #ddd; +} + +.toggle[aria-pressed][disabled]:hover { + color: #999; /* case for CSS custom property if not supporting IE/Edge */ +} + +.toggle[aria-pressed][disabled]:hover::before { + box-shadow: none; +} + +.toggle[aria-pressed][disabled]:hover::after { + background-image: none; +} + +/* Put toggles on the right like the iOS the kids like */ + +.toggle.flip[aria-pressed]::before, +.toggle.flip[aria-pressed]::after { + left: auto; + right: 0; +} + +.toggle.flip[aria-pressed]::after { + left: auto; + right: 1.6em; +} + +.toggle.flip[aria-pressed=true]::after { + right: 0; +} + +.toggle.flip[aria-pressed] { + padding-left: 0; + padding-right: 4em; +} + +/* Windows High Contrast Mode Support */ +@media screen and (-ms-high-contrast: active) { + .toggle[aria-pressed]:focus::before, + .toggle[aria-pressed]:hover::before { + outline: 1px dotted windowText; + outline-offset: 0.25em; + } + .toggle[aria-pressed]::after { + background-color: windowText; + } + .toggle[aria-pressed][disabled]::after { + background-color: transparent; + } +} + +/* Reduced motion */ +@media screen and (prefers-reduced-motion: reduce) { + .toggle[aria-pressed]::before, + .toggle[aria-pressed]::after { + transition: none; + } +} + +/* Dark mode */ +@media screen and (prefers-color-scheme: dark) { + .toggle[aria-pressed]:focus, + .toggle[aria-pressed]:hover { + color: #99f; + } + .toggle[aria-pressed]::before { + border-color: #808080; + background: #808080; + } + .toggle[aria-pressed]::after { + background-color: #101010; + } + .toggle[aria-pressed]:focus::after, + .toggle[aria-pressed]:hover::after { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='50' cy='50' r='50' fill='rgba(255,255,255,.25)'/%3E%3C/svg%3E"); + } + .toggle[aria-pressed][disabled]::before, + .toggle[aria-pressed][disabled]::after { + border-color: #555; + } +} + +/* RTL */ +/* https://twitter.com/dror3go/status/1102946375396982784 */ +*[dir="rtl"] .toggle[aria-pressed] { + padding-left: 0; + padding-right: 4em; +} + +*[dir="rtl"] .toggle[aria-pressed]::before, +*[dir="rtl"] .toggle[aria-pressed]::after { + left: auto; + right: 0; +} + +*[dir="rtl"] .toggle[aria-pressed]::after { + right: 0; +} + +*[dir="rtl"] .toggle[aria-pressed=true]::after { + right: 1.6em; +} + +/* Put toggles on the right like the iOS the kids like */ + +*[dir="rtl"] .toggle.flip[aria-pressed]::before, +*[dir="rtl"] .toggle.flip[aria-pressed]::after { + left: 0; + right: auto; +} + +*[dir="rtl"] .toggle.flip[aria-pressed]::after { + right: auto; + left: 1.6em; +} + +*[dir="rtl"] .toggle.flip[aria-pressed=true]::after { + left: 0; +} + +*[dir="rtl"] .toggle.flip[aria-pressed] { + padding-right: 0; + padding-left: 4em; +} \ No newline at end of file diff --git a/assets/site.webmanifest b/assets/site.webmanifest new file mode 100644 index 000000000..fe02f282d --- /dev/null +++ b/assets/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "{{ .Site.Title }}", + "short_name": "{{ .Site.Title }}", + "start_url": "{{ "/" | relURL }}", + "scope": "{{ "/" | relURL }}", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#0090ff", + "background_color": "#0090ff", + "display": "standalone" +} diff --git a/bin/.gitignore b/bin/.gitignore deleted file mode 100644 index 95656c14e..000000000 --- a/bin/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -codeGen -.emacs -watcher diff --git a/bin/build-pdf.sh b/bin/build-pdf.sh deleted file mode 100644 index e185ae610..000000000 --- a/bin/build-pdf.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh - -#------- WIP FLAG -echo "Hold up, this isn't ready yet." -echo "if you need it, ping @jbenet to fix it" -exit 1; -#------- - -set -e - -short=$(git rev-parse --short HEAD) -tag=${1-$short} - -files=( - INTRO.md - data-structures.md - address.md - signatures.md - proofs.md - validation.md - network-protocols.md - bootstrap.md - data-propagation.md - sync.md - state-machine.md - local-storage.md - operation.md - actors.md - mining.md - storage-market.md - retrieval-market.md - faults.md - zigzag-circuit.md - zigzag-porep.md - definitions.md - style.md - process.md -) - -rm -rf .pdfworking -mkdir -p .pdfworking -mkdir -p pdf-build - -i=0 -for f in ${files[@]}; do - printf -v n "%03d" $i - cp "./${f}" "./.pdfworking/${n}_${f}" - i=$((i + 1)) -done - -find ./.pdfworking -type f -exec sed -i "" 's/{{%.*%}}//g' {} \; - -pandoc ./.pdfworking/*.md \ - --pdf-engine xelatex \ - -o "pdf-build/filecoin-spec-$tag".pdf \ - --from markdown+grid_tables \ - --template ./pdf/eisvogel.tex \ - -H ./pdf/helpers.tex \ - --listings \ - --toc \ - -V titlepage=true \ - -V titlepage-color=FFFFFF \ - -V titlepage-rule-color=FFFFFF \ - -V titlepage-rule-height=0 \ - -V logo="./pdf/cover-src.jpg" \ - -V logo-width="120" \ - -V listings-disable-line-numbers=true \ - -V block-headings=true \ - -V mainfont="Georgia" \ - --metadata title="Filecoin Specification $tag" - -rm -rf .pdfbuild - -echo "filecoin-spec-$tag.pdf" diff --git a/bin/build-spec-orient.sh b/bin/build-spec-orient.sh deleted file mode 100755 index 47e569bf1..000000000 --- a/bin/build-spec-orient.sh +++ /dev/null @@ -1,22 +0,0 @@ -output_dir=build/orient -input_dir=src/orient -diagram_dir=src/diagrams/orient - -if [[ -z "${ORIENT_DCALC}" ]]; then - orient_bin=orient/bin/orient -else - orient_bin=orient/bin/dcalc - input_dir=/orientd/$input_dir - diagram_dir=/orientd/$diagram_dir -fi; - -mkdir -p $output_dir -mkdir -p $diagram_dir - -$orient_bin solve --system=$input_dir/filecoin.orient --in=$input_dir/snark-table.json | jq > $output_dir/snark-table.json -$orient_bin solve --system=$input_dir/filecoin.orient --in=$input_dir/filecoin.json | jq > build/orient/solved-parameters.json -$orient_bin solve --system=$input_dir/filecoin.orient --in=$input_dir/multi-params.json | jq > $output_dir/multi-solved-parameters.json -$orient_bin solve --system=$input_dir/fast-porep.orient --in=$input_dir/fast-porep.json | jq > $output_dir/fast-porep.json -$orient_bin report --system=$input_dir/filecoin.orient --in=$input_dir/filecoin.json > $output_dir/filecoin-report.html -$orient_bin dump --system=$input_dir/filecoin.orient | jq > $output_dir/filecoin.json -$orient_bin graph --system=$input_dir/filecoin.orient --in=$input_dir/filecoin.json > $diagram_dir/filecoin.dot diff --git a/bin/emacs-init-build.el b/bin/emacs-init-build.el deleted file mode 100644 index 7c439ae0b..000000000 --- a/bin/emacs-init-build.el +++ /dev/null @@ -1,37 +0,0 @@ -;; Sandbox -(setq - user-emacs-directory (concat (file-name-directory load-file-name) ".emacs/") - package-user-dir (concat user-emacs-directory "elpa/") - use-package-always-ensure t - inhibit-message t) ; if there are errors, remove this. - ; debug-on-error t) ; if there are errors, add this. - -;; require package -(require 'package) - -;; enable melpa, if not there. -(add-to-list - 'package-archives - '("melpa" . "https://melpa.org/packages/") - t) - -;; Update package list -(package-initialize) -(unless (require 'use-package nil 'noerror) - (package-refresh-contents) - (package-install 'use-package)) - -;; Load packages we need -(use-package ox-hugo) - -;; slime is used in orient + orgmode -(use-package slime - :init - (load (expand-file-name "deps/quicklisp/slime-helper.el")) - (setq inferior-lisp-program "bin/sbclw") - (add-to-list 'slime-contribs 'slime-repl)) - -(org-babel-do-load-languages - 'org-babel-load-languages - '((lisp . t))) - diff --git a/bin/emacs-init-user.el b/bin/emacs-init-user.el deleted file mode 100644 index 8b74fb929..000000000 --- a/bin/emacs-init-user.el +++ /dev/null @@ -1,29 +0,0 @@ -;; Options -(setq - use-package-always-ensure t) - -;; require package -(require 'package) - -;; enable melpa, if not there. -(add-to-list - 'package-archives - '("melpa" . "https://melpa.org/packages/") - t) - -;; Update package list -(package-initialize) -(unless (require 'use-package nil 'noerror) - (package-refresh-contents) - (package-install 'use-package)) - -;; Load packages we need -(use-package ox-hugo) - -;; slime is used in orient + orgmode -(use-package slime - :init - (global-set-key (kbd "C-c z") 'slime-repl) - (load (substitute-in-file-name "$HOME/quicklisp/slime-helper.el")) - (setq inferior-lisp-program "sbcl") ; TODO: verify this doesn't require full path to binary - (add-to-list 'slime-contribs 'slime-repl)) diff --git a/bin/install-deps-basic.sh b/bin/install-deps-basic.sh deleted file mode 100755 index bcd16dd6d..000000000 --- a/bin/install-deps-basic.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -source "$(dirname $0)/lib.sh" - -# usage() { -# cat << USAGE -# SYNOPSIS -# install dependencies for the filecoin spec buildsys -# usage: $0 [-y] -# -# OPTIONS -# -h,--help show usage -# -y,--yes pass yes to installers and confirmation prompts -# USAGE -# } -# -# parse_args() { -# while [ $# -gt 0 ]; do -# case "$1" in -# -y|--yes) y=y ;; -# -h|--help) usage ; exit 0 ;; -# *) die "unrecognized argument: $1 (-h shows usage)" ;; -# esac -# shift -# done -# } - -main() { - must_run_from_spec_root - - # package manager packages - tryinstall hugo hugo - tryinstall rsync rsync - - # submodules required for hugo themes - prun git submodule update --init --recursive - - # other packages - require_version "$(hugo version)" hugo 0.58 "recommended install from package manager" - require_version "$(go version)" go 1.13 "recommended install from https://golang.org/dl/" - return 0 -} -main diff --git a/bin/install-deps-diagrams.sh b/bin/install-deps-diagrams.sh deleted file mode 100755 index 7aeb045df..000000000 --- a/bin/install-deps-diagrams.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -source "$(dirname $0)/lib.sh" - -main() { - must_run_from_spec_root - - # package manager packages - tryinstall dot graphviz - tryinstall node node - - # other packages - require_version "$(node --version)" node 10.10 "recommended install from https://nodejs.org/en/" - require_version "$(npm --version)" npm 5.0 "recommended install from https://nodejs.org/en/" - - # npm deps - echo "> installing npm deps" - cwd=$(pwd) - cd deps - npm install || die "npm install failed" - cd "$cwd" - return 0 -} -main diff --git a/bin/install-deps-ga.sh b/bin/install-deps-ga.sh deleted file mode 100755 index b2168e6af..000000000 --- a/bin/install-deps-ga.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -source "$(dirname $0)/lib.sh" - -# usage() { -# cat << USAGE -# SYNOPSIS -# install dependencies for the filecoin spec buildsys -# usage: $0 [-y] -# -# OPTIONS -# -h,--help show usage -# -y,--yes pass yes to installers and confirmation prompts -# USAGE -# } -# -# parse_args() { -# while [ $# -gt 0 ]; do -# case "$1" in -# -y|--yes) y=y ;; -# -h|--help) usage ; exit 0 ;; -# *) die "unrecognized argument: $1 (-h shows usage)" ;; -# esac -# shift -# done -# } - -main() { - must_run_from_spec_root - - # package manager packages - tryinstall rsync rsync - - # Github Actions requires this version of hugo. - snap install hugo --channel=extended - - # submodules required for hugo themes - prun git submodule update --init --recursive - - # other packages - require_version "$(go version)" go 1.13 "recommended install from https://golang.org/dl/" - - return 0 -} -main diff --git a/bin/install-deps-orient-user.sh b/bin/install-deps-orient-user.sh deleted file mode 100755 index 046c91bdd..000000000 --- a/bin/install-deps-orient-user.sh +++ /dev/null @@ -1,132 +0,0 @@ -#!/bin/bash - -# common code -source "$(dirname $0)/lib.sh" - -sbclr() { - sbcl --noinform --non-interactive "$@" --quit -} - -is_quicklisp_installed() { - echo "> check whether quicklisp is already installed." - - lisp_qlcheck="\ - (if\ - (find-package '#:ql)\ - (write-line \"quicklisp is installed\")\ - (write-line \"quicklisp is not installed\"))\ - " - - qli=$(sbclr --eval "$lisp_qlcheck") - [ $? -eq 0 ] || die "failed to check" - - # show whether quicklisp is installed to the user reading the trace - echo "$qli" - - # check if quicklisp is installed - return $(echo "$qli" | grep 'quicklisp is installed' >/dev/null) -} - -install_quicklisp() { - echo "> installing quicklisp and asdf" - - is_quicklisp_installed - if [ $? -ne 0 ]; then - qlif="$(pwd)/deps/quicklisp-install.lisp" - download_if_not_present "https://beta.quicklisp.org/quicklisp.lisp" "$qlif" - - sbclr --load "$qlif" \ - --eval "(quicklisp-quickstart:install :path \"$HOME/quicklisp\")" \ - --eval "(ql-util:without-prompting (ql:add-to-init-file))" - [ $? -eq 0 ] || die "failed to run quicklisp-install.lisp" - - is_quicklisp_installed || die "failed to install quicklisp" - fi -} - -install_slime() { - echo "> installing slime" - sbclr --eval "(ql:quickload \"quicklisp-slime-helper\")" - [ $? -eq 0 ] || die "failed to install slime" -} - -link_orient_to_quicklisp() { - echo "> integrating quicklisp with orient" - - dst="$(pwd)/orient/orient.asd" - src="$HOME/quicklisp/local-projects/orient.asd" - ensure_symlink "$dst" "$src" - - # this is a symlink. brittle! - # if we move orient or quicklisp (relative to each other) we have to change this. -} - -install_cllaunch() { - cll="cl-launch.sh" - dst="/usr/local/bin/cl" - src="https://common-lisp.net/project/xcvb/cl-launch/$cll" - - download_if_not_present "$src" "$dst" - [ $? -eq 0 ] || die "failed to install cl-launch" -} - -install_emacs_deps() { - # loading the init file will do - emacs_init="bin/emacs-init-user.el" - echo "> installing emacs deps from $emacs_init" - emacs --script "$emacs_init" - [ $? -eq 0 ] || die "failed to install emacs deps" -} - -main() { - must_run_from_spec_root - - # warn the user - echo "WARNING: $0 is work in progress." - echo " This warning will be removed once it is done." - - echo "WARNING: this may mess up your user environment, especially if you use:" - echo " emacs" - echo " sbcl" - - # get confirmation from user - if [ "$1" != "-y" ]; then - get_user_confirmation - fi - - # package manager packages - tryinstall wget wget - tryinstall emacs emacs - tryinstall sbcl sbcl - mkdir -p deps/bin - - # lisp / emacs - install_quicklisp - install_slime - install_cllaunch - install_emacs_deps - - # git repos - prun git submodule update --init --recursive - - # orient - link_orient_to_quicklisp - - # TODO: make this automated. - emacs_init="$(pwd)/bin/emacs-init-user.el" - cat <<- EOF - - =============== ORIENT DEPS INSTALL FINISHED =============== - - We need to link emacs, slime, orgmode, and so on. - Do this by loading this file: $emacs_init - - To load it, use this elisp code in an emacs session, or put it in your emacs init file: - (load "$emacs_init") - - Your emacs user init file is usually ~/.emacs, or ~/.emacs.el, or ~/emacs.d/init.el - (TODO automate this) -EOF - return 0 -} -main $1 diff --git a/bin/install-deps-orient.sh b/bin/install-deps-orient.sh deleted file mode 100755 index c129a4ea2..000000000 --- a/bin/install-deps-orient.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/bash - -#------- modes -# set -e - -# load lib -source "$(dirname $0)/lib.sh" - -is_quicklisp_installed() { - echo "> check whether quicklisp is already installed." - bin/sbclw --script >deps/quicklisp.installed-or-not << LISP - (load "bin/sbcl-userinit.lisp") ; --script means --no-userinit - (if - (find-package '#:ql) - (write-line "quicklisp is installed") - (write-line "quicklisp is not installed")) -LISP - [ $? -eq 0 ] || die "failed to check" - - # show whether quicklisp is installed to the user reading the trace - grep 'quicklisp' deps/quicklisp.installed-or-not - - # check if quicklisp is installed - return $(grep 'quicklisp is installed' deps/quicklisp.installed-or-not >/dev/null) -} - -install_quicklisp() { - - # install quicklisp & asdf - echo "> installing quicklisp and asdf" - - is_quicklisp_installed - if [ $? -ne 0 ]; then - download_if_not_present "https://beta.quicklisp.org/quicklisp.lisp" "deps/quicklisp-install.lisp" - - # load quicklisp into sbcl - # bin/sbclw is a wrapper that sets some options first (for isolation) - bin/sbclw --script << LISP - (load "deps/quicklisp-install.lisp") - (quicklisp-quickstart:install :path "$(pwd)/deps/quicklisp") -LISP - [ $? -eq 0 ] || die "failed to run quicklisp-install.lisp" - - is_quicklisp_installed || die "failed to install quicklisp" - fi -} - -install_slime() { - echo "> installing slime" - bin/sbclw --eval "(ql:quickload \"quicklisp-slime-helper\")" --quit - [ $? -eq 0 ] || die "failed to install slime" -} - -link_orient_to_quicklisp() { - echo "> integrating quicklisp with orient" - dst="../../orient/orient.asd" - src="deps/quicklisp/local-projects/orient.asd" - ensure_symlink "$dst" "$src" - - # this is a symlink. brittle! - # if we move orient or quicklisp (relative to each other) we have to change this. -} - -install_cllaunch() { - cll="cl-launch.sh" - dst="deps/bin/cl" - src="https://common-lisp.net/project/xcvb/cl-launch/$cll" - - download_if_not_present "$src" "$dst" - [ $? -eq 0 ] || die "failed to install cl-launch" -} - -install_emacs_deps() { - # loading the init file will do - emacs_init="bin/emacs-init-build.el" - echo "> installing emacs deps from $emacs_init" - HOME=$HOME emacs -Q --script "$emacs_init" - [ $? -eq 0 ] || die "failed to install emacs deps" -} - -main() { - must_run_from_spec_root - - # warn the user - echo "WARNING: $0 is work in progress." - echo " This warning will be removed once it is done." - - # get confirmation from user - if [ "$1" != "-y" ]; then - get_user_confirmation - fi - - # package manager packages - tryinstall wget wget - tryinstall emacs emacs - require_version "$(emacs -version)" emacs 26.3 "recommended install from you package manager" - tryinstall sbcl sbcl - mkdir -p deps/bin - - # lisp / emacs - install_quicklisp - install_slime - install_cllaunch - install_emacs_deps - - # git repos - prun git submodule update --init --recursive - - # orient - link_orient_to_quicklisp - return 0 -} -main $1 diff --git a/bin/lib.sh b/bin/lib.sh deleted file mode 100644 index a23d91007..000000000 --- a/bin/lib.sh +++ /dev/null @@ -1,158 +0,0 @@ -# no shbang, not meant to be run directly - -find_pkgmgr() { - pkgmgrs=(brew snap apt-get) - for pm in ${pkgmgrs[@]}; do - which "$pm" >/dev/null && printf "$pm" && return 0 - done - printf "" -} -pkgmgr=$(find_pkgmgr) - -die() { - echo >&2 "error: $@" - exit 1 -} - -prun() { - echo "> $@" - $@ -} - -which_v() { - printf "which $1: " - which "$1" 2>/dev/null && return 0 - echo "not found" && return 1 -} - -require() { - which_v "$1" || die "$1 required - install package: $2 -$4" -} - -require_version() { - require "$2" "$2" $4 - - v_actual=$(echo "$1" | get_version) - v_expect=$3 - compare_versions "$v_actual" "$v_expect" - case $? in - 0) return ;; - 1) return ;; - 2) die "$2 version $v_expect or greater required. you have $v_actual -$4" ;; - esac -} - -tryinstall() { - # no pkg mgr? bail w/ require msg. - if [ "" = "$pkgmgr" ]; then - require "$1" "$2" - else - which_v "$1" && return 0 # have it - fi - version="$3" - - # pkg mgr, try using it - if [ "$pkgmgr" = "apt-get" ]; then - prun sudo "$pkgmgr" install "$2" - else - prun "$pkgmgr" install "$2" - fi -} - -get_user_confirmation() { - while : ; do - read -p "Continue (y/n)? " choice - case "$choice" in - y|yes ) break ;; - n|no ) die "aborting" ;; - esac - done -} - -download_if_not_present() { - src="$1" - dst="$2" - echo "> installing $dst" - if [ -f "$dst" ]; then - echo "$dst already exists. skipping download. to force redownload, remove the file." - else - echo "downloading $src to $dst" - prun wget -O "$2" "$1" - fi -} - -ensure_symlink() { - dst="$1" - src="$2" - - echo "> linking $src -> $dst" - if [ -L "$src" ]; then - # link already exists - dst2=$(readlink "$src") - if [ "$dst" = "$dst2" ]; then - # link is what we expect. done - return - else - # link exists, but is different. dont clobber - echo "link exists, but has different value:" - echo "\texpected: $src -> $dst" - echo "\tactual: $src -> $dst2" - echo "" - echo "either fix link manually or rm it and rerun this script" - return 1 - fi - elif [ -e "$src" ]; then - # some other file is at "$src" - die "$src exists, but is not a link" - else - # link doesn't exist, make itt - prun ln -s "$dst" "$src" - fi -} - -must_run_from_spec_root() { - # assert we're running from spec root dir - err="please run $(basename $0) from spec root directory" - [ -f "$(pwd)/bin/$(basename $0)" ] || die "$err" - grep 'filecoin-project/specs' "$(pwd)/.git/config" >/dev/null || die "$err" - grep -i 'filecoin spec' "$(pwd)/README.md" >/dev/null || die "$err" -} - - -# from https://stackoverflow.com/questions/4023830/how-to-compare-two-strings-in-dot-separated-version-format-in-bash -compare_versions() { - if [[ $1 == $2 ]] - then - return 0 - fi - local IFS=. - local i ver1=($1) ver2=($2) - # fill empty fields in ver1 with zeros - for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) - do - ver1[i]=0 - done - for ((i=0; i<${#ver1[@]}; i++)) - do - if [[ -z ${ver2[i]} ]] - then - # fill empty fields in ver2 with zeros - ver2[i]=0 - fi - if ((10#${ver1[i]} > 10#${ver2[i]})) - then - return 1 - fi - if ((10#${ver1[i]} < 10#${ver2[i]})) - then - return 2 - fi - done - return 0 -} - -get_version() { - grep -o '[0-9]\+\(\.[0-9]\+\)\+' -} diff --git a/bin/lib_test.sh b/bin/lib_test.sh deleted file mode 100755 index 497898871..000000000 --- a/bin/lib_test.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -source "$(dirname $0)/lib.sh" - -# test require -require emacs emacs -require go go - -# test version compare -compare_versions 10.10 10.11 -compare_versions 1.2.3 1.3.2 -compare_versions 1 999.999.999 - -# test require version -require_version "$(emacs -version)" emacs 26.3 "recommended install from you package manager" -require_version "$(go version)" go 1.10 "recommended install from https://golang.org/dl/" -require_version "$(go version)" go 1.13 "recommended install from https://golang.org/dl/" diff --git a/bin/org2hugomd.el b/bin/org2hugomd.el deleted file mode 100755 index c2bdb74a1..000000000 --- a/bin/org2hugomd.el +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env -S emacs -Q --script - -;; load info -(load (concat (file-name-directory load-file-name) "emacs-init-build.el")) - -(setq org-confirm-babel-evaluate nil) - -;; process input -(with-temp-buffer - (progn - (condition-case nil - (let (line) - (while (setq line (read-from-minibuffer "")) - (insert line) - (insert "\n"))) - (error nil)) - (princ (org-export-as 'hugo)))) - diff --git a/bin/publish-to-gh-pages.sh b/bin/publish-to-gh-pages.sh deleted file mode 100755 index 0c54aa10e..000000000 --- a/bin/publish-to-gh-pages.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -source "$(dirname $0)/lib.sh" - -website=build/website -ghpages=build/gh-pages - -## -- warnings -echo "WARNING: this will publish to github pages." -# get confirmation from user -if [ "$1" != "-y" ]; then - get_user_confirmation -fi - -## -- checks -must_run_from_spec_root -# [[ $(git status -s -uno) ]] && die "the working directory is dirty.\n\ -# Please commit any pending changes and test, before publishing." -[ -d "$website" ] || die "$website not found. did you run: make website ?" - - -## -- work tree setup -echo "Setting up worktree in build/gh-pages" -git fetch origin gh-pages -git worktree remove gh-pages -rm -rf "$ghpages" -git worktree add -B gh-pages "$ghpages" origin/gh-pages - -## -- updating website content -echo "Removing existing files" -dotgit=$(cat "$ghpages/.git") # preserve .git -rm -rf "$ghpages" -cp -r "$website" "$ghpages" -echo "$dotgit" >"$ghpages/.git" # paste .git - -# echo "Generating PDF" -# name=$(bin/build-pdf.sh) -# echo $name -# cp "pdf-build/$name" "static/$name" -# msg="You can also download the full spec in [PDF format](.\/$name)." -# sed -i "" "s/<\!\-\- REPLACE_ME_PDF_LINK \-\->/$msg/" INTRO.md - -echo "Updating gh-pages branch" -shash=$(git rev-parse --short HEAD) -cd "$ghpages" && git add --all && git commit -m "Publishing $shash ($0)" - -## -- publishing -echo "Publishing to github" -git push origin gh-pages diff --git a/bin/publish-to-ipfs.sh b/bin/publish-to-ipfs.sh deleted file mode 100755 index 7b9da90da..000000000 --- a/bin/publish-to-ipfs.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -source "$(dirname $0)/lib.sh" -must_run_from_spec_root - -dir=build/website - -ipfs swarm peers >/dev/null 2>/dev/null || \ - die "is ipfs daemon not running?" - -[ -d "$dir" ] || die "$dir not found. did you run: make website ?" - -hash=$(ipfs add -Q -r "$dir") -echo "published /ipfs/$hash" -echo "http://localhost:8080/ipfs/$hash" -echo "https://ipfs.io/ipfs/$hash" diff --git a/bin/sbcl-userinit.lisp b/bin/sbcl-userinit.lisp deleted file mode 100644 index 43ee789b8..000000000 --- a/bin/sbcl-userinit.lisp +++ /dev/null @@ -1,31 +0,0 @@ -; sbcl-userinit -; -; this file is here because it's tricky to edit the userinit file -; reliably from within sbcl as called by a shell script. i decided -; to do this manually. -; -; use load-quicklisp-verbose if you need to debug quicklisp loading - -(defvar *quicklisp-init-file* - (merge-pathnames "deps/quicklisp/setup.lisp" (user-homedir-pathname))) - -(defun load-quicklisp-verbose () - (write-line (format nil "looking for quicklisp in ~A" *quicklisp-init-file*)) - (if (probe-file *quicklisp-init-file*) - (progn - (write-line "quicklisp found") - (if (load *quicklisp-init-file*) - (write-line "quicklisp loaded") - (write-line "Warning: quicklisp failed to load")) - t) - (progn - (write-line "Warning: quicklisp not found") - t))) - -(defun load-quicklisp-silent () - (when (probe-file *quicklisp-init-file*) - (load *quicklisp-init-file*))) - -; actually run load-quicklisp function. comment one of these out. -; (load-quicklisp-verbose) -(load-quicklisp-silent) diff --git a/bin/sbclw b/bin/sbclw deleted file mode 100755 index cae09044f..000000000 --- a/bin/sbclw +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -# wrapper around sbcl in order to pass in common params to -# run it as part of the build system. - -die() { - echo >&2 "error: $@" - exit 1 -} - -sbclrc="bin/sbcl-userinit.lisp" -stat $sbclrc >/dev/null || die "$sbclrc not found" -which sbcl >/dev/null || die "sbcl not found, is it installed?" - -cmd="sbcl --noinform --disable-debugger --userinit $sbclrc --no-sysinit" -HOME=$(pwd) $cmd "$@" diff --git a/bin/solve-orient.sh b/bin/solve-orient.sh deleted file mode 100755 index d6c79930c..000000000 --- a/bin/solve-orient.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -system_file=$1 -input_file=$2 -output_file=$3 - -if [[ -z "${ORIENT_DCALC}" ]]; then - orient_bin=orient/bin/orient -else - orient_bin=orient/bin/dcalc - system_file=/orientd/$system_file - input_file=/orientd/$input_file -fi; - -mkdir -p $output_file && rmdir $output_file # Dirty hack to ensure output_file directory exists. - -echo $output_file - -$orient_bin solve --system=$system_file --in=$input_file | jq > $output_file diff --git a/bin/write-spec-version.sh b/bin/write-spec-version.sh deleted file mode 100755 index 1f389c4f0..000000000 --- a/bin/write-spec-version.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -source "$(dirname $0)/lib.sh" - -main() { - must_run_from_spec_root - - hash=$(git rev-parse HEAD) - shorthash=$(git rev-parse --short HEAD) - date=$(date -u '+%Y-%m-%d_%H:%M:%SZ') - - while read line; do - eval echo "$line" - done -} -main diff --git a/config.toml b/config.toml new file mode 100644 index 000000000..05ea9a586 --- /dev/null +++ b/config.toml @@ -0,0 +1,124 @@ +# baseURL = '/' +title = 'Filecoin Spec' +ignoreFiles= ["externals", "\\.dot$", "\\.mmd$"] +# theme = 'book' +canonifyurls = false +# relativeURLs = true + +# Book configuration +disablePathToLower = true +enableGitInfo = true + +# Needed for mermaid/katex shortcodes +[markup] +[markup.goldmark.renderer] + unsafe = true +[markup.tableOfContents] + startLevel = 2 +[markup.highlight] + style = "dracula" + +# Multi-lingual mode config +# There are different options to translate files +# See https://gohugo.io/content-management/multilingual/#translation-by-filename +# And https://gohugo.io/content-management/multilingual/#translation-by-content-directory +[languages] +[languages.en] + languageName = 'English' + contentDir = 'content' + weight = 1 + +[languages.pt] + languageName = 'Português' + contentDir = 'content-pt' + weight = 2 + +# [languages.zh] +# languageName = 'Chinese' +# contentDir = 'content.zh' +# weight = 3 + +[menu] +# [[menu.before]] +# [[menu.after]] +# name = "Github" +# url = "https://github.com/filecoin-project/specs" +# weight = 10 + +[params] + # (Optional, default true) Controls table of contents visibility on right side of pages. + # Start and end levels can be controlled with markup.tableOfContents setting. + # You can also specify this parameter per page in front matter. + BookToC = false + + # (Optional, default none) Set the path to a logo for the book. If the logo is + # /static/logo.png then the path would be logo.png + BookLogo = 'filecoin-logo.svg' + + # (Optional, default none) Set leaf bundle to render as side menu + # When not specified file structure and weights will be used + # BookMenuBundle = '/menu' + + # (Optional, default docs) Specify root page to render child pages as menu. + # Page is resoled by .GetPage function: https://gohugo.io/functions/getpage/ + # For backward compatibility you can set '*' to render all sections to menu. Acts same as '/' + BookSection = '*' + + # Set source repository location. + # Used for 'Last Modified' and 'Edit this page' links. + BookRepo = 'https://github.com/filecoin-project/specs' + + # Enable "Edit this page" links for 'doc' page type. + # Disabled by default. Uncomment to enable. Requires 'BookRepo' param. + # Edit path must point to root directory of repo. + BookEditPath = 'edit/beta' + + # Configure the date format used on the pages + # - In git information + # - In blog posts + BookDateFormat = 'July 3, 2006' + + # (Optional, default true) Enables search function with flexsearch, + # Index is built on fly, therefore it might slowdown your website. + # Configuration for indexing can be adjusted in i18n folder per language. + BookSearch = false + + # (Optional, default true) Enables comments template on pages + # By default partals/docs/comments.html includes Disqus template + # See https://gohugo.io/content-management/comments/#configure-disqus + # Can be overwritten by same param in page frontmatter + BookComments = false + + # /!\ This is an experimental feature, might be removed or changed at any time + # (Optional, experimental, default false) Enables portable links and link checks in markdown pages. + # Portable links meant to work with text editors and let you write markdown without {{< relref >}} shortcode + # Theme will print warning if page referenced in markdown does not exists. + BookPortableLinks = true + + # /!\ This is an experimental feature, might be removed or changed at any time + # (Optional, experimental, default false) Enables service worker that caches visited pages and resources for offline use. + BookServiceWorker = false + +[module] + [[module.imports]] + path = "github.com/alex-shpak/hugo-book" + [[module.imports]] + path = "github.com/filecoin-project/specs-actors" + [[module.imports.mounts]] + source = "." + target = "content/externals/specs-actors" + [[module.imports]] + path = "github.com/filecoin-project/go-fil-markets" + [[module.imports.mounts]] + source = "." + target = "content/externals/go-fil-markets" + [[module.imports]] + path = "github.com/filecoin-project/lotus" + [[module.imports.mounts]] + source = "." + target = "content/externals/lotus" + [[module.imports]] + path = "github.com/filecoin-project/go-data-transfer" + [[module.imports.mounts]] + source = "." + target = "content/externals/go-data-transfer" \ No newline at end of file diff --git a/content-pt/_index.md b/content-pt/_index.md new file mode 100644 index 000000000..6e6ba714a --- /dev/null +++ b/content-pt/_index.md @@ -0,0 +1,3 @@ +--- +title: Home +--- \ No newline at end of file diff --git a/src/intro/_index.md b/content-pt/intro/_index.md similarity index 64% rename from src/intro/_index.md rename to content-pt/intro/_index.md index 11ff52a41..cd25627b4 100644 --- a/src/intro/_index.md +++ b/content-pt/intro/_index.md @@ -1,26 +1,11 @@ --- title: Introduction -entries: -# - specmap -- arch -- concepts -- filecoin_vm -- process -- changelog -- system +weight: 1 +dashboardState: wip +bookCollapseSection: true --- -
- -{{% notice warning %}} -**Warning:** This draft of the Filecoin protocol specification is a work in progress. -It is intended to establish the rough overall structure of the document, -enabling experts to fill in different sections in parallel. -However, within each section, content may be out-of-order, incorrect, and/or incomplete. -The reader is advised to refer to the -[official Filecoin spec document](https://filecoin-project.github.io/specs/) -for specification and implementation questions. -{{% /notice %}} +# Introdução Filecoin is a distributed storage network based on a blockchain mechanism. Filecoin *miners* can elect to provide storage capacity for the network, and thereby @@ -41,4 +26,4 @@ in exchange for storing the specific file data that the clients request. Via the distributed implementation of the Filecoin VM, storage deals and other contract mechanisms recorded on the chain continue to be processed over time, without requiring further interaction from the original parties -(such as the clients who requested the data storage). +(such as the clients who requested the data storage). \ No newline at end of file diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 000000000..ce843ca10 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,4 @@ +--- +title: Home +type: single +--- \ No newline at end of file diff --git a/content/algorithms/_index.md b/content/algorithms/_index.md new file mode 100644 index 000000000..210b7c786 --- /dev/null +++ b/content/algorithms/_index.md @@ -0,0 +1,11 @@ +--- +title: Algorithms +weight: 4 + +dashboardWeight: 2 +dashboardState: wip +dashboardAudit: n/a +dashboardTests: 0 +--- + +# Algorithms \ No newline at end of file diff --git a/src/algorithms/block_reception.md b/content/algorithms/block_reception.md similarity index 97% rename from src/algorithms/block_reception.md rename to content/algorithms/block_reception.md index 754ae4a95..54f9640df 100644 --- a/src/algorithms/block_reception.md +++ b/content/algorithms/block_reception.md @@ -1,8 +1,10 @@ --- title: "Block Reception" +draft: true --- -{{