From ee168d39fb0e094fc1f29cb2db5af8bf9e30478c Mon Sep 17 00:00:00 2001 From: libsgh Date: Fri, 4 Mar 2022 15:31:44 +0800 Subject: [PATCH 1/2] :tada:v3 commit --- .gitattributes | 3 + .github/workflows/compile-to-release.yml | 28 +- .gitignore | 9 +- LICENSE | 0 README.md | 4 +- Util/Ali.go | 320 - Util/Base.go | 294 - Util/Cloud189.go | 641 - Util/FTP.go | 186 - Util/FileUtil.go | 399 - Util/GoogleDrive.go | 224 - Util/OneDrive.go | 341 - Util/Teambition.go | 627 - Util/WebDav.go | 152 - Util/Yun139.go | 353 - app.json | 37 - boot/Init.go | 183 - boot/boot.go | 285 + config.json | 11 + config/config.go | 52 - config/config.json | 51 - control/admin.go | 237 + control/dav.go | 59 + control/index.go | 170 + control/middleware/Referer.go | 61 + control/middleware/jwt.go | 122 + control/middleware/pwd.go | 177 + control/public.go | 107 + control/router.go | 83 + control/webdav/file.go | 215 + control/webdav/if.go | 173 + control/webdav/internal/xml/README | 11 + control/webdav/internal/xml/marshal.go | 1223 ++ control/webdav/internal/xml/read.go | 692 + control/webdav/internal/xml/typeinfo.go | 371 + control/webdav/internal/xml/xml.go | 1998 +++ control/webdav/lock.go | 445 + control/webdav/prop.go | 480 + control/webdav/webdav.go | 760 + control/webdav/xml.go | 519 + dao/db.go | 628 + dao/mysql.go | 32 + dao/postgres.go | 32 + dao/sqlite.go | 32 + docker/Dockerfile | 0 docker/arm64/Dockerfile | 0 docker/arm64/getPanIndex.sh | 0 docker/build.sh | 4 +- docker/getPanIndex.sh | 0 docs/.nojekyll | 0 docs/_coverpage.md | 2 +- docs/_images/1-2.png | Bin docs/_images/audio.png | Bin docs/_images/teambition-project.png | Bin docs/_media/favicon.ico | Bin docs/_media/index.png | Bin docs/changelog.md | 4 + docs/index.html | 0 docs/v1/README.md | 0 docs/v1/_images/1-2.png | Bin docs/v1/_images/audio.png | Bin docs/v1/_images/teambition-project.png | Bin entity/entity.go | 212 - go.mod | 69 +- go.sum | 445 +- heroku.yml | 3 - jobs/Jobs.go | 293 - jobs/jobs.go | 50 + main.go | 765 +- model/sqlitedb.go | 144 - module/entity.go | 259 + pan/Ali.go | 626 + pan/Cloud189.go | 556 + pan/FTP.go | 262 + pan/GoogleDrive.go | 356 + pan/Native.go | 249 + pan/OneDrive.go | 448 + pan/Teambition.go | 601 + pan/WebDAV.go | 229 + pan/Yun139.go | 592 + pan/pan.go | 64 + service/service.go | 1723 +-- static/css/index.css | 18 + static/img/favicon-cloud189.ico | Bin static/img/favicon-native.ico | Bin static/img/favicon-teambition-us.ico | Bin static/img/favicon-teambition.ico | Bin static/img/favicon-webdav.ico | Bin static/img/music-cover.png | Bin 0 -> 16607 bytes static/js/admin.js | 507 +- static/js/main.js | 412 - static/js/mdui-view.js | 106 - static/js/mdui.index.js | 318 + static/js/mdui.video.js | 331 + static/js/simple.index.js | 203 + static/js/simple.video.js | 97 + static/lib/artplayer@4.3.1/artplayer.min.js | 14 + .../bootstrap@4.6.1/css/bootstrap-grid.css | 3872 ++++++ .../css/bootstrap-grid.css.map | 1 + .../css/bootstrap-grid.min.css | 7 + .../css/bootstrap-grid.min.css.map | 1 + .../bootstrap@4.6.1/css/bootstrap-reboot.css | 325 + .../css/bootstrap-reboot.css.map | 1 + .../css/bootstrap-reboot.min.css | 8 + .../css/bootstrap-reboot.min.css.map | 1 + static/lib/bootstrap@4.6.1/css/bootstrap.css | 10315 ++++++++++++++ .../lib/bootstrap@4.6.1/css/bootstrap.css.map | 1 + .../lib/bootstrap@4.6.1/css/bootstrap.min.css | 7 + .../bootstrap@4.6.1/css/bootstrap.min.css.map | 1 + .../bootstrap@4.6.1/js/bootstrap.bundle.js | 6972 ++++++++++ .../js/bootstrap.bundle.js.map | 1 + .../js/bootstrap.bundle.min.js | 7 + .../js/bootstrap.bundle.min.js.map | 1 + static/lib/bootstrap@4.6.1/js/bootstrap.js | 4357 ++++++ .../lib/bootstrap@4.6.1/js/bootstrap.js.map | 1 + .../lib/bootstrap@4.6.1/js/bootstrap.min.js | 7 + .../bootstrap@4.6.1/js/bootstrap.min.js.map | 1 + static/lib/dplayer@1.26.0/dist/DPlayer.min.js | 2 - .../dplayer@1.26.0/dist/DPlayer.min.js.map | 1 - static/lib/flv.js@1.6.2/dist/flv.js | 10585 ++++++++++++++ static/lib/flv.js@1.6.2/dist/flv.js.map | 1 + static/lib/flv.js@1.6.2/dist/flv.min.js.map | 1 + static/lib/fontawesome@5.15.4/css/all.css | 4616 ++++++ static/lib/fontawesome@5.15.4/css/all.min.css | 5 + static/lib/fontawesome@5.15.4/css/brands.css | 15 + .../lib/fontawesome@5.15.4/css/brands.min.css | 5 + .../fontawesome@5.15.4/css/fontawesome.css | 4582 ++++++ .../css/fontawesome.min.css | 5 + static/lib/fontawesome@5.15.4/css/regular.css | 15 + .../fontawesome@5.15.4/css/regular.min.css | 5 + static/lib/fontawesome@5.15.4/css/solid.css | 16 + .../lib/fontawesome@5.15.4/css/solid.min.css | 5 + .../fontawesome@5.15.4/css/svg-with-js.css | 371 + .../css/svg-with-js.min.css | 5 + .../lib/fontawesome@5.15.4/css/v4-shims.css | 2172 +++ .../fontawesome@5.15.4/css/v4-shims.min.css | 5 + .../webfonts/fa-brands-400.eot | Bin 0 -> 134294 bytes .../webfonts/fa-brands-400.svg | 3717 +++++ .../webfonts/fa-brands-400.ttf | Bin 0 -> 133988 bytes .../webfonts/fa-brands-400.woff | Bin 0 -> 89988 bytes .../webfonts/fa-brands-400.woff2 | Bin 0 -> 76736 bytes .../webfonts/fa-regular-400.eot | Bin 0 -> 34034 bytes .../webfonts/fa-regular-400.svg | 801 ++ .../webfonts/fa-regular-400.ttf | Bin 0 -> 33736 bytes .../webfonts/fa-regular-400.woff | Bin 0 -> 16276 bytes .../webfonts/fa-regular-400.woff2 | Bin 0 -> 13224 bytes .../webfonts/fa-solid-900.eot | Bin 0 -> 203030 bytes .../webfonts/fa-solid-900.svg | 5034 +++++++ .../webfonts/fa-solid-900.ttf | Bin 0 -> 202744 bytes .../webfonts/fa-solid-900.woff | Bin 0 -> 101648 bytes .../webfonts/fa-solid-900.woff2 | Bin 0 -> 78268 bytes .../cdn-release@11.2.0/build/LICENSE | 29 - .../cdn-release@11.2.0/build/README.md | 45 - .../cdn-release@11.2.0/build/es/core.js | 2503 ---- .../cdn-release@11.2.0/build/es/core.min.js | 297 - .../cdn-release@11.2.0/build/es/highlight.js | 11580 --------------- .../build/es/highlight.min.js | 1121 -- .../build/es/languages/1c.min.js | 23 - .../build/es/languages/abnf.min.js | 12 - .../build/es/languages/accesslog.min.js | 17 - .../build/es/languages/actionscript.min.js | 17 - .../build/es/languages/ada.min.js | 25 - .../build/es/languages/angelscript.min.js | 20 - .../build/es/languages/apache.min.js | 13 - .../build/es/languages/applescript.min.js | 22 - .../build/es/languages/arcade.min.js | 27 - .../build/es/languages/arduino.min.js | 56 - .../build/es/languages/armasm.min.js | 16 - .../build/es/languages/asciidoc.min.js | 35 - .../build/es/languages/aspectj.min.js | 30 - .../build/es/languages/autohotkey.min.js | 12 - .../build/es/languages/autoit.min.js | 20 - .../build/es/languages/avrasm.min.js | 11 - .../build/es/languages/awk.min.js | 10 - .../build/es/languages/axapta.min.js | 10 - .../build/es/languages/bash.min.js | 19 - .../build/es/languages/basic.min.js | 8 - .../build/es/languages/bnf.min.js | 5 - .../build/es/languages/brainfuck.min.js | 6 - .../build/es/languages/c.min.js | 41 - .../build/es/languages/cal.min.js | 13 - .../build/es/languages/capnproto.min.js | 12 - .../build/es/languages/ceylon.min.js | 14 - .../build/es/languages/clean.min.js | 7 - .../build/es/languages/clojure-repl.min.js | 3 - .../build/es/languages/clojure.min.js | 17 - .../build/es/languages/cmake.min.js | 6 - .../build/es/languages/coffeescript.min.js | 28 - .../build/es/languages/coq.min.js | 6 - .../build/es/languages/cos.min.js | 14 - .../build/es/languages/cpp.min.js | 48 - .../build/es/languages/crmsh.min.js | 18 - .../build/es/languages/crystal.min.js | 47 - .../build/es/languages/csharp.min.js | 46 - .../build/es/languages/csp.min.js | 5 - .../build/es/languages/css.min.js | 29 - .../build/es/languages/d.min.js | 19 - .../build/es/languages/dart.min.js | 21 - .../build/es/languages/delphi.min.js | 16 - .../build/es/languages/diff.min.js | 12 - .../build/es/languages/django.min.js | 12 - .../build/es/languages/dns.min.js | 10 - .../build/es/languages/dockerfile.min.js | 7 - .../build/es/languages/dos.min.js | 12 - .../build/es/languages/dsconfig.min.js | 8 - .../build/es/languages/dts.min.js | 21 - .../build/es/languages/dust.min.js | 7 - .../build/es/languages/ebnf.min.js | 6 - .../build/es/languages/elixir.min.js | 33 - .../build/es/languages/elm.min.js | 17 - .../build/es/languages/erb.min.js | 4 - .../build/es/languages/erlang-repl.min.js | 13 - .../build/es/languages/erlang.min.js | 26 - .../build/es/languages/excel.min.js | 9 - .../build/es/languages/fix.min.js | 6 - .../build/es/languages/flix.min.js | 9 - .../build/es/languages/fortran.min.js | 16 - .../build/es/languages/fsharp.min.js | 13 - .../build/es/languages/gams.min.js | 29 - .../build/es/languages/gauss.min.js | 35 - .../build/es/languages/gcode.min.js | 16 - .../build/es/languages/gherkin.min.js | 8 - .../build/es/languages/glsl.min.js | 7 - .../build/es/languages/gml.min.js | 9 - .../build/es/languages/go.min.js | 12 - .../build/es/languages/golo.min.js | 5 - .../build/es/languages/gradle.min.js | 5 - .../build/es/languages/groovy.min.js | 20 - .../build/es/languages/haml.min.js | 17 - .../build/es/languages/handlebars.min.js | 34 - .../build/es/languages/haskell.min.js | 28 - .../build/es/languages/haxe.min.js | 26 - .../build/es/languages/hsp.min.js | 13 - .../build/es/languages/http.min.js | 13 - .../build/es/languages/hy.min.js | 14 - .../build/es/languages/inform7.min.js | 9 - .../build/es/languages/ini.min.js | 18 - .../build/es/languages/irpf90.min.js | 15 - .../build/es/languages/isbl.min.js | 24 - .../build/es/languages/java.min.js | 34 - .../build/es/languages/javascript.min.js | 73 - .../build/es/languages/jboss-cli.min.js | 9 - .../build/es/languages/json.min.js | 6 - .../build/es/languages/julia-repl.min.js | 3 - .../build/es/languages/julia.min.js | 17 - .../build/es/languages/kotlin.min.js | 44 - .../build/es/languages/lasso.min.js | 28 - .../build/es/languages/latex.min.js | 36 - .../build/es/languages/ldif.min.js | 4 - .../build/es/languages/leaf.min.js | 7 - .../build/es/languages/less.min.js | 40 - .../build/es/languages/lisp.min.js | 15 - .../build/es/languages/livecodeserver.min.js | 20 - .../build/es/languages/livescript.min.js | 34 - .../build/es/languages/llvm.min.js | 14 - .../build/es/languages/lsl.min.js | 18 - .../build/es/languages/lua.min.js | 13 - .../build/es/languages/makefile.min.js | 13 - .../build/es/languages/markdown.min.js | 30 - .../build/es/languages/mathematica.min.js | 24 - .../build/es/languages/matlab.min.js | 15 - .../build/es/languages/maxima.min.js | 11 - .../build/es/languages/mel.min.js | 7 - .../build/es/languages/mercury.min.js | 15 - .../build/es/languages/mipsasm.min.js | 14 - .../build/es/languages/mizar.min.js | 3 - .../build/es/languages/mojolicious.min.js | 5 - .../build/es/languages/monkey.min.js | 16 - .../build/es/languages/moonscript.min.js | 22 - .../build/es/languages/n1ql.min.js | 12 - .../build/es/languages/nestedtext.min.js | 8 - .../build/es/languages/nginx.min.js | 22 - .../build/es/languages/nim.min.js | 14 - .../build/es/languages/nix.min.js | 10 - .../build/es/languages/node-repl.min.js | 4 - .../build/es/languages/nsis.min.js | 19 - .../build/es/languages/objectivec.min.js | 21 - .../build/es/languages/ocaml.min.js | 13 - .../build/es/languages/openscad.min.js | 14 - .../build/es/languages/oxygene.min.js | 13 - .../build/es/languages/parser3.min.js | 9 - .../build/es/languages/perl.min.js | 40 - .../build/es/languages/pf.min.js | 8 - .../build/es/languages/pgsql.min.js | 68 - .../build/es/languages/php-template.min.js | 7 - .../build/es/languages/php.min.js | 35 - .../build/es/languages/plaintext.min.js | 2 - .../build/es/languages/pony.min.js | 11 - .../build/es/languages/powershell.min.js | 39 - .../build/es/languages/processing.min.js | 21 - .../build/es/languages/profile.min.js | 8 - .../build/es/languages/prolog.min.js | 10 - .../build/es/languages/properties.min.js | 10 - .../build/es/languages/protobuf.min.js | 11 - .../build/es/languages/puppet.min.js | 16 - .../build/es/languages/purebasic.min.js | 10 - .../build/es/languages/python-repl.min.js | 4 - .../build/es/languages/python.min.js | 53 - .../build/es/languages/q.min.js | 7 - .../build/es/languages/qml.min.js | 29 - .../build/es/languages/r.min.js | 30 - .../build/es/languages/reasonml.min.js | 42 - .../build/es/languages/rib.min.js | 5 - .../build/es/languages/roboconf.min.js | 12 - .../build/es/languages/routeros.min.js | 21 - .../build/es/languages/rsl.min.js | 9 - .../build/es/languages/ruby.min.js | 49 - .../build/es/languages/ruleslanguage.min.js | 8 - .../build/es/languages/rust.min.js | 29 - .../build/es/languages/sas.min.js | 19 - .../build/es/languages/scala.min.js | 20 - .../build/es/languages/scheme.min.js | 18 - .../build/es/languages/scilab.min.js | 12 - .../build/es/languages/scss.min.js | 28 - .../build/es/languages/shell.min.js | 4 - .../build/es/languages/smali.min.js | 12 - .../build/es/languages/smalltalk.min.js | 10 - .../build/es/languages/sml.min.js | 13 - .../build/es/languages/sqf.min.js | 16 - .../build/es/languages/sql.min.js | 21 - .../build/es/languages/stan.min.js | 16 - .../build/es/languages/stata.min.js | 10 - .../build/es/languages/step21.min.js | 9 - .../build/es/languages/stylus.min.js | 32 - .../build/es/languages/subunit.min.js | 9 - .../build/es/languages/swift.min.js | 59 - .../build/es/languages/taggerscript.min.js | 6 - .../build/es/languages/tap.min.js | 6 - .../build/es/languages/tcl.min.js | 15 - .../build/es/languages/thrift.min.js | 11 - .../build/es/languages/tp.min.js | 18 - .../build/es/languages/twig.min.js | 14 - .../build/es/languages/typescript.min.js | 87 - .../build/es/languages/vala.min.js | 8 - .../build/es/languages/vbnet.min.js | 28 - .../build/es/languages/vbscript-html.min.js | 3 - .../build/es/languages/vbscript.min.js | 14 - .../build/es/languages/verilog.min.js | 13 - .../build/es/languages/vhdl.min.js | 13 - .../build/es/languages/vim.min.js | 11 - .../build/es/languages/wasm.min.js | 13 - .../build/es/languages/wren.min.js | 34 - .../build/es/languages/x86asm.min.js | 17 - .../build/es/languages/xl.min.js | 14 - .../build/es/languages/xml.min.js | 31 - .../build/es/languages/xquery.min.js | 32 - .../build/es/languages/yaml.min.js | 24 - .../build/es/languages/zephir.min.js | 17 - .../cdn-release@11.2.0/build/es/package.json | 1 - .../cdn-release@11.2.0/build/highlight.js | 11586 ---------------- .../cdn-release@11.2.0/build/highlight.min.js | 1120 -- .../build/languages/1c.min.js | 23 - .../build/languages/abnf.min.js | 11 - .../build/languages/accesslog.min.js | 16 - .../build/languages/actionscript.min.js | 18 - .../build/languages/ada.min.js | 25 - .../build/languages/angelscript.min.js | 21 - .../build/languages/apache.min.js | 13 - .../build/languages/applescript.min.js | 22 - .../build/languages/arcade.min.js | 26 - .../build/languages/arduino.min.js | 55 - .../build/languages/armasm.min.js | 15 - .../build/languages/asciidoc.min.js | 36 - .../build/languages/aspectj.min.js | 31 - .../build/languages/autohotkey.min.js | 13 - .../build/languages/autoit.min.js | 19 - .../build/languages/avrasm.min.js | 11 - .../build/languages/awk.min.js | 9 - .../build/languages/axapta.min.js | 9 - .../build/languages/bash.min.js | 19 - .../build/languages/basic.min.js | 8 - .../build/languages/bnf.min.js | 5 - .../build/languages/brainfuck.min.js | 7 - .../build/languages/c.min.js | 41 - .../build/languages/cal.min.js | 12 - .../build/languages/capnproto.min.js | 12 - .../build/languages/ceylon.min.js | 13 - .../build/languages/clean.min.js | 6 - .../build/languages/clojure-repl.min.js | 3 - .../build/languages/clojure.min.js | 17 - .../build/languages/cmake.min.js | 5 - .../build/languages/coffeescript.min.js | 27 - .../build/languages/coq.min.js | 6 - .../build/languages/cos.min.js | 14 - .../build/languages/cpp.min.js | 48 - .../build/languages/crmsh.min.js | 18 - .../build/languages/crystal.min.js | 47 - .../build/languages/csharp.min.js | 45 - .../build/languages/csp.min.js | 5 - .../build/languages/css.min.js | 29 - .../build/languages/d.min.js | 19 - .../build/languages/dart.min.js | 20 - .../build/languages/delphi.min.js | 15 - .../build/languages/diff.min.js | 12 - .../build/languages/django.min.js | 11 - .../build/languages/dns.min.js | 9 - .../build/languages/dockerfile.min.js | 6 - .../build/languages/dos.min.js | 11 - .../build/languages/dsconfig.min.js | 9 - .../build/languages/dts.min.js | 21 - .../build/languages/dust.min.js | 7 - .../build/languages/ebnf.min.js | 7 - .../build/languages/elixir.min.js | 33 - .../build/languages/elm.min.js | 16 - .../build/languages/erb.min.js | 3 - .../build/languages/erlang-repl.min.js | 13 - .../build/languages/erlang.min.js | 25 - .../build/languages/excel.min.js | 10 - .../build/languages/fix.min.js | 6 - .../build/languages/flix.min.js | 10 - .../build/languages/fortran.min.js | 16 - .../build/languages/fsharp.min.js | 13 - .../build/languages/gams.min.js | 29 - .../build/languages/gauss.min.js | 34 - .../build/languages/gcode.min.js | 16 - .../build/languages/gherkin.min.js | 7 - .../build/languages/glsl.min.js | 8 - .../build/languages/gml.min.js | 9 - .../build/languages/go.min.js | 11 - .../build/languages/golo.min.js | 6 - .../build/languages/gradle.min.js | 5 - .../build/languages/groovy.min.js | 19 - .../build/languages/haml.min.js | 16 - .../build/languages/handlebars.min.js | 33 - .../build/languages/haskell.min.js | 28 - .../build/languages/haxe.min.js | 25 - .../build/languages/hsp.min.js | 13 - .../build/languages/http.min.js | 13 - .../build/languages/hy.min.js | 14 - .../build/languages/inform7.min.js | 9 - .../build/languages/ini.min.js | 18 - .../build/languages/irpf90.min.js | 14 - .../build/languages/isbl.min.js | 24 - .../build/languages/java.min.js | 33 - .../build/languages/javascript.min.js | 72 - .../build/languages/jboss-cli.min.js | 9 - .../build/languages/json.min.js | 6 - .../build/languages/julia-repl.min.js | 3 - .../build/languages/julia.min.js | 17 - .../build/languages/kotlin.min.js | 44 - .../build/languages/lasso.min.js | 27 - .../build/languages/latex.min.js | 36 - .../build/languages/ldif.min.js | 4 - .../build/languages/leaf.min.js | 6 - .../build/languages/less.min.js | 39 - .../build/languages/lisp.min.js | 15 - .../build/languages/livecodeserver.min.js | 21 - .../build/languages/livescript.min.js | 34 - .../build/languages/llvm.min.js | 14 - .../build/languages/lsl.min.js | 19 - .../build/languages/lua.min.js | 13 - .../build/languages/makefile.min.js | 12 - .../build/languages/markdown.min.js | 29 - .../build/languages/mathematica.min.js | 24 - .../build/languages/matlab.min.js | 14 - .../build/languages/maxima.min.js | 11 - .../build/languages/mel.min.js | 6 - .../build/languages/mercury.min.js | 14 - .../build/languages/mipsasm.min.js | 14 - .../build/languages/mizar.min.js | 3 - .../build/languages/mojolicious.min.js | 5 - .../build/languages/monkey.min.js | 15 - .../build/languages/moonscript.min.js | 22 - .../build/languages/n1ql.min.js | 11 - .../build/languages/nestedtext.min.js | 8 - .../build/languages/nginx.min.js | 22 - .../build/languages/nim.min.js | 13 - .../build/languages/nix.min.js | 10 - .../build/languages/node-repl.min.js | 4 - .../build/languages/nsis.min.js | 18 - .../build/languages/objectivec.min.js | 21 - .../build/languages/ocaml.min.js | 13 - .../build/languages/openscad.min.js | 14 - .../build/languages/oxygene.min.js | 14 - .../build/languages/parser3.min.js | 10 - .../build/languages/perl.min.js | 40 - .../build/languages/pf.min.js | 9 - .../build/languages/pgsql.min.js | 68 - .../build/languages/php-template.min.js | 7 - .../build/languages/php.min.js | 36 - .../build/languages/plaintext.min.js | 2 - .../build/languages/pony.min.js | 11 - .../build/languages/powershell.min.js | 38 - .../build/languages/processing.min.js | 21 - .../build/languages/profile.min.js | 8 - .../build/languages/prolog.min.js | 10 - .../build/languages/properties.min.js | 9 - .../build/languages/protobuf.min.js | 10 - .../build/languages/puppet.min.js | 16 - .../build/languages/purebasic.min.js | 9 - .../build/languages/python-repl.min.js | 4 - .../build/languages/python.min.js | 52 - .../build/languages/q.min.js | 6 - .../build/languages/qml.min.js | 29 - .../build/languages/r.min.js | 30 - .../build/languages/reasonml.min.js | 41 - .../build/languages/rib.min.js | 5 - .../build/languages/roboconf.min.js | 11 - .../build/languages/routeros.min.js | 21 - .../build/languages/rsl.min.js | 9 - .../build/languages/ruby.min.js | 48 - .../build/languages/ruleslanguage.min.js | 8 - .../build/languages/rust.min.js | 28 - .../build/languages/sas.min.js | 19 - .../build/languages/scala.min.js | 20 - .../build/languages/scheme.min.js | 17 - .../build/languages/scilab.min.js | 12 - .../build/languages/scss.min.js | 28 - .../build/languages/shell.min.js | 4 - .../build/languages/smali.min.js | 12 - .../build/languages/smalltalk.min.js | 9 - .../build/languages/sml.min.js | 13 - .../build/languages/sqf.min.js | 15 - .../build/languages/sql.min.js | 20 - .../build/languages/stan.min.js | 17 - .../build/languages/stata.min.js | 10 - .../build/languages/step21.min.js | 9 - .../build/languages/stylus.min.js | 32 - .../build/languages/subunit.min.js | 9 - .../build/languages/swift.min.js | 59 - .../build/languages/taggerscript.min.js | 6 - .../build/languages/tap.min.js | 7 - .../build/languages/tcl.min.js | 14 - .../build/languages/thrift.min.js | 10 - .../build/languages/tp.min.js | 18 - .../build/languages/twig.min.js | 13 - .../build/languages/typescript.min.js | 87 - .../build/languages/vala.min.js | 9 - .../build/languages/vbnet.min.js | 28 - .../build/languages/vbscript-html.min.js | 3 - .../build/languages/vbscript.min.js | 14 - .../build/languages/verilog.min.js | 13 - .../build/languages/vhdl.min.js | 12 - .../build/languages/vim.min.js | 10 - .../build/languages/wasm.min.js | 14 - .../build/languages/wren.min.js | 33 - .../build/languages/x86asm.min.js | 18 - .../build/languages/xl.min.js | 14 - .../build/languages/xml.min.js | 31 - .../build/languages/xquery.min.js | 32 - .../build/languages/yaml.min.js | 24 - .../build/languages/zephir.min.js | 18 - .../cdn-release@11.2.0/build/package.json | 86 - .../build/styles/a11y-dark.min.css | 7 - .../build/styles/a11y-light.min.css | 7 - .../build/styles/agate.min.css | 20 - .../build/styles/an-old-hope.min.css | 9 - .../build/styles/androidstudio.min.css | 1 - .../build/styles/arduino-light.min.css | 1 - .../build/styles/arta.min.css | 1 - .../build/styles/ascetic.min.css | 1 - .../styles/atom-one-dark-reasonable.min.css | 1 - .../build/styles/base16/3024.min.css | 7 - .../build/styles/base16/apathy.min.css | 7 - .../build/styles/base16/apprentice.min.css | 7 - .../build/styles/base16/ashes.min.css | 7 - .../styles/base16/atelier-cave-light.min.css | 7 - .../build/styles/base16/atelier-cave.min.css | 7 - .../styles/base16/atelier-dune-light.min.css | 7 - .../build/styles/base16/atelier-dune.min.css | 7 - .../base16/atelier-estuary-light.min.css | 7 - .../styles/base16/atelier-estuary.min.css | 7 - .../base16/atelier-forest-light.min.css | 7 - .../styles/base16/atelier-forest.min.css | 7 - .../styles/base16/atelier-heath-light.min.css | 7 - .../build/styles/base16/atelier-heath.min.css | 7 - .../base16/atelier-lakeside-light.min.css | 7 - .../styles/base16/atelier-lakeside.min.css | 7 - .../base16/atelier-plateau-light.min.css | 7 - .../styles/base16/atelier-plateau.min.css | 7 - .../base16/atelier-savanna-light.min.css | 7 - .../styles/base16/atelier-savanna.min.css | 7 - .../base16/atelier-seaside-light.min.css | 7 - .../styles/base16/atelier-seaside.min.css | 7 - .../base16/atelier-sulphurpool-light.min.css | 7 - .../styles/base16/atelier-sulphurpool.min.css | 7 - .../build/styles/base16/atlas.min.css | 7 - .../build/styles/base16/bespin.min.css | 7 - .../styles/base16/black-metal-bathory.min.css | 7 - .../styles/base16/black-metal-burzum.min.css | 7 - .../base16/black-metal-dark-funeral.min.css | 7 - .../base16/black-metal-gorgoroth.min.css | 7 - .../base16/black-metal-immortal.min.css | 7 - .../styles/base16/black-metal-khold.min.css | 7 - .../styles/base16/black-metal-marduk.min.css | 7 - .../styles/base16/black-metal-mayhem.min.css | 7 - .../styles/base16/black-metal-nile.min.css | 7 - .../styles/base16/black-metal-venom.min.css | 7 - .../build/styles/base16/black-metal.min.css | 7 - .../build/styles/base16/brewer.min.css | 7 - .../build/styles/base16/bright.min.css | 7 - .../build/styles/base16/brogrammer.min.css | 7 - .../styles/base16/brush-trees-dark.min.css | 7 - .../build/styles/base16/brush-trees.min.css | 7 - .../build/styles/base16/chalk.min.css | 7 - .../build/styles/base16/circus.min.css | 7 - .../build/styles/base16/classic-dark.min.css | 7 - .../build/styles/base16/classic-light.min.css | 7 - .../build/styles/base16/codeschool.min.css | 7 - .../build/styles/base16/colors.min.css | 7 - .../build/styles/base16/cupcake.min.css | 7 - .../build/styles/base16/cupertino.min.css | 7 - .../build/styles/base16/danqing.min.css | 7 - .../build/styles/base16/darcula.min.css | 7 - .../build/styles/base16/dark-violet.min.css | 7 - .../build/styles/base16/darkmoss.min.css | 7 - .../build/styles/base16/darktooth.min.css | 7 - .../build/styles/base16/decaf.min.css | 7 - .../build/styles/base16/default-dark.min.css | 7 - .../build/styles/base16/default-light.min.css | 7 - .../build/styles/base16/dirtysea.min.css | 7 - .../build/styles/base16/dracula.min.css | 7 - .../build/styles/base16/edge-dark.min.css | 7 - .../build/styles/base16/edge-light.min.css | 7 - .../build/styles/base16/eighties.min.css | 7 - .../build/styles/base16/embers.min.css | 7 - .../styles/base16/equilibrium-dark.min.css | 7 - .../base16/equilibrium-gray-dark.min.css | 7 - .../base16/equilibrium-gray-light.min.css | 7 - .../styles/base16/equilibrium-light.min.css | 7 - .../build/styles/base16/espresso.min.css | 7 - .../build/styles/base16/eva-dim.min.css | 7 - .../build/styles/base16/eva.min.css | 7 - .../build/styles/base16/flat.min.css | 7 - .../build/styles/base16/framer.min.css | 7 - .../build/styles/base16/fruit-soda.min.css | 7 - .../build/styles/base16/gigavolt.min.css | 7 - .../build/styles/base16/github.min.css | 7 - .../build/styles/base16/google-dark.min.css | 7 - .../build/styles/base16/google-light.min.css | 7 - .../styles/base16/grayscale-dark.min.css | 7 - .../styles/base16/grayscale-light.min.css | 7 - .../build/styles/base16/green-screen.min.css | 7 - .../styles/base16/gruvbox-dark-hard.min.css | 7 - .../styles/base16/gruvbox-dark-medium.min.css | 7 - .../styles/base16/gruvbox-dark-pale.min.css | 7 - .../styles/base16/gruvbox-dark-soft.min.css | 7 - .../styles/base16/gruvbox-light-hard.min.css | 7 - .../base16/gruvbox-light-medium.min.css | 7 - .../styles/base16/gruvbox-light-soft.min.css | 7 - .../build/styles/base16/hardcore.min.css | 7 - .../styles/base16/harmonic16-dark.min.css | 7 - .../styles/base16/harmonic16-light.min.css | 7 - .../build/styles/base16/heetch-dark.min.css | 7 - .../build/styles/base16/heetch-light.min.css | 7 - .../build/styles/base16/helios.min.css | 7 - .../build/styles/base16/hopscotch.min.css | 7 - .../build/styles/base16/horizon-dark.min.css | 7 - .../build/styles/base16/horizon-light.min.css | 7 - .../build/styles/base16/humanoid-dark.min.css | 7 - .../styles/base16/humanoid-light.min.css | 7 - .../build/styles/base16/ia-dark.min.css | 7 - .../build/styles/base16/ia-light.min.css | 7 - .../build/styles/base16/icy-dark.min.css | 7 - .../build/styles/base16/ir-black.min.css | 7 - .../build/styles/base16/isotope.min.css | 7 - .../build/styles/base16/kimber.min.css | 7 - .../build/styles/base16/london-tube.min.css | 7 - .../build/styles/base16/macintosh.min.css | 7 - .../build/styles/base16/marrakesh.min.css | 7 - .../build/styles/base16/materia.min.css | 7 - .../styles/base16/material-darker.min.css | 7 - .../styles/base16/material-lighter.min.css | 7 - .../styles/base16/material-palenight.min.css | 7 - .../styles/base16/material-vivid.min.css | 7 - .../build/styles/base16/material.min.css | 7 - .../build/styles/base16/mellow-purple.min.css | 7 - .../build/styles/base16/mexico-light.min.css | 7 - .../build/styles/base16/mocha.min.css | 7 - .../build/styles/base16/monokai.min.css | 7 - .../build/styles/base16/nebula.min.css | 7 - .../build/styles/base16/nord.min.css | 7 - .../build/styles/base16/nova.min.css | 7 - .../build/styles/base16/ocean.min.css | 7 - .../build/styles/base16/oceanicnext.min.css | 7 - .../build/styles/base16/one-light.min.css | 7 - .../build/styles/base16/onedark.min.css | 7 - .../build/styles/base16/outrun-dark.min.css | 7 - .../styles/base16/papercolor-dark.min.css | 7 - .../styles/base16/papercolor-light.min.css | 7 - .../build/styles/base16/paraiso.min.css | 7 - .../build/styles/base16/pasque.min.css | 7 - .../build/styles/base16/phd.min.css | 7 - .../build/styles/base16/pico.min.css | 7 - .../build/styles/base16/pop.min.css | 7 - .../build/styles/base16/porple.min.css | 7 - .../build/styles/base16/qualia.min.css | 7 - .../build/styles/base16/railscasts.min.css | 7 - .../build/styles/base16/rebecca.min.css | 7 - .../build/styles/base16/ros-pine-dawn.min.css | 7 - .../build/styles/base16/ros-pine-moon.min.css | 7 - .../build/styles/base16/ros-pine.min.css | 7 - .../build/styles/base16/sagelight.min.css | 7 - .../build/styles/base16/sandcastle.min.css | 7 - .../build/styles/base16/seti-ui.min.css | 7 - .../build/styles/base16/shapeshifter.min.css | 7 - .../build/styles/base16/silk-dark.min.css | 7 - .../build/styles/base16/silk-light.min.css | 7 - .../build/styles/base16/snazzy.min.css | 7 - .../styles/base16/solar-flare-light.min.css | 7 - .../build/styles/base16/solar-flare.min.css | 7 - .../styles/base16/solarized-dark.min.css | 7 - .../styles/base16/solarized-light.min.css | 7 - .../build/styles/base16/spacemacs.min.css | 7 - .../build/styles/base16/summercamp.min.css | 7 - .../styles/base16/summerfruit-dark.min.css | 7 - .../styles/base16/summerfruit-light.min.css | 7 - .../synth-midnight-terminal-dark.min.css | 7 - .../synth-midnight-terminal-light.min.css | 7 - .../build/styles/base16/tango.min.css | 7 - .../build/styles/base16/tender.min.css | 7 - .../styles/base16/tomorrow-night.min.css | 7 - .../build/styles/base16/tomorrow.min.css | 7 - .../build/styles/base16/twilight.min.css | 7 - .../build/styles/base16/unikitty-dark.min.css | 7 - .../styles/base16/unikitty-light.min.css | 7 - .../build/styles/base16/vulcan.min.css | 7 - .../styles/base16/windows-10-light.min.css | 7 - .../build/styles/base16/windows-10.min.css | 7 - .../styles/base16/windows-95-light.min.css | 7 - .../build/styles/base16/windows-95.min.css | 7 - .../windows-high-contrast-light.min.css | 7 - .../base16/windows-high-contrast.min.css | 7 - .../styles/base16/windows-nt-light.min.css | 7 - .../build/styles/base16/windows-nt.min.css | 7 - .../build/styles/base16/woodland.min.css | 7 - .../build/styles/base16/xcode-dusk.min.css | 7 - .../build/styles/base16/zenburn.min.css | 7 - .../build/styles/brown-paper.min.css | 1 - .../build/styles/brown-papersq.png | Bin 18198 -> 0 bytes .../build/styles/codepen-embed.min.css | 1 - .../build/styles/color-brewer.min.css | 1 - .../build/styles/dark.min.css | 1 - .../build/styles/default.min.css | 9 - .../build/styles/devibeans.min.css | 7 - .../build/styles/docco.min.css | 1 - .../build/styles/far.min.css | 1 - .../build/styles/foundation.min.css | 1 - .../build/styles/github-dark-dimmed.min.css | 9 - .../build/styles/github-dark.min.css | 10 - .../build/styles/github.min.css | 10 - .../build/styles/gml.min.css | 1 - .../build/styles/googlecode.min.css | 1 - .../build/styles/gradient-dark.min.css | 1 - .../build/styles/gradient-light.min.css | 1 - .../build/styles/grayscale.min.css | 1 - .../build/styles/hybrid.min.css | 1 - .../build/styles/idea.min.css | 1 - .../build/styles/ir-black.min.css | 1 - .../build/styles/isbl-editor-dark.min.css | 1 - .../build/styles/isbl-editor-light.min.css | 1 - .../build/styles/kimbie-dark.min.css | 1 - .../build/styles/kimbie-light.min.css | 1 - .../build/styles/lightfair.min.css | 1 - .../build/styles/lioshi.min.css | 1 - .../build/styles/magula.min.css | 1 - .../build/styles/mono-blue.min.css | 1 - .../build/styles/monokai-sublime.min.css | 1 - .../build/styles/monokai.min.css | 1 - .../build/styles/night-owl.min.css | 1 - .../build/styles/nnfx-dark.min.css | 10 - .../build/styles/nnfx-light.min.css | 10 - .../build/styles/nord.min.css | 1 - .../build/styles/obsidian.min.css | 1 - .../build/styles/paraiso-dark.min.css | 1 - .../build/styles/paraiso-light.min.css | 1 - .../build/styles/pojoaque.jpg | Bin 1186 -> 0 bytes .../build/styles/pojoaque.min.css | 1 - .../build/styles/purebasic.min.css | 1 - .../build/styles/qtcreator-dark.min.css | 1 - .../build/styles/qtcreator-light.min.css | 1 - .../build/styles/rainbow.min.css | 1 - .../build/styles/routeros.min.css | 1 - .../build/styles/school-book.min.css | 1 - .../build/styles/shades-of-purple.min.css | 1 - .../build/styles/srcery.min.css | 1 - .../build/styles/stackoverflow-dark.min.css | 13 - .../build/styles/stackoverflow-light.min.css | 13 - .../build/styles/sunburst.min.css | 1 - .../build/styles/tomorrow-night-blue.min.css | 1 - .../styles/tomorrow-night-bright.min.css | 1 - .../build/styles/vs.min.css | 1 - .../build/styles/vs2015.min.css | 1 - .../build/styles/xcode.min.css | 1 - .../build/styles/xt256.min.css | 1 - .../cdn-release@11.4.0/build/highlight.min.js | 1160 ++ .../build/styles/atom-one-dark.min.css | 0 .../build/styles/atom-one-light.min.css | 0 static/lib/hls.js@1.0.7/dist/hls-demo.js.map | 1 - static/lib/hls.js@1.0.7/dist/hls.js.map | 1 - static/lib/hls.js@1.0.7/dist/hls.light.js.map | 1 - static/lib/hls.js@1.0.7/dist/hls.light.min.js | 2 - .../hls.js@1.0.7/dist/hls.light.min.js.map | 1 - static/lib/hls.js@1.0.7/dist/hls.min.js | 2 - static/lib/hls.js@1.0.7/dist/hls.min.js.map | 1 - .../dist/hls-demo.js | 57 +- static/lib/hls.js@1.1.2/dist/hls-demo.js.map | 1 + .../dist/hls.js | 838 +- .../dist/hls.js.d.ts | 375 +- static/lib/hls.js@1.1.2/dist/hls.js.map | 1 + .../dist/hls.light.js | 159 +- static/lib/hls.js@1.1.2/dist/hls.light.js.map | 1 + static/lib/hls.js@1.1.2/dist/hls.light.min.js | 2 + .../hls.js@1.1.2/dist/hls.light.min.js.map | 1 + static/lib/hls.js@1.1.2/dist/hls.min.js | 2 + static/lib/hls.js@1.1.2/dist/hls.min.js.map | 1 + static/lib/md5/md5.min.js | 2 + static/lib/md5/md5.min.js.map | 1 + static/lib/mdui@1.0.1/js/mdui.esm.js.map | 1 - static/lib/mdui@1.0.1/js/mdui.js.map | 1 - static/lib/mdui@1.0.1/js/mdui.min.js | 7 - static/lib/mdui@1.0.1/js/mdui.min.js.map | 1 - .../{mdui@1.0.1 => mdui@1.0.2}/css/mdui.css | 4 +- .../css/mdui.css.map | 2 +- .../css/mdui.min.css | 4 +- .../css/mdui.min.css.map | 2 +- .../fonts/roboto/LICENSE.txt | 0 .../fonts/roboto/Roboto-Black.woff | Bin .../fonts/roboto/Roboto-Black.woff2 | Bin .../fonts/roboto/Roboto-BlackItalic.woff | Bin .../fonts/roboto/Roboto-BlackItalic.woff2 | Bin .../fonts/roboto/Roboto-Bold.woff | Bin .../fonts/roboto/Roboto-Bold.woff2 | Bin .../fonts/roboto/Roboto-BoldItalic.woff | Bin .../fonts/roboto/Roboto-BoldItalic.woff2 | Bin .../fonts/roboto/Roboto-Light.woff | Bin .../fonts/roboto/Roboto-Light.woff2 | Bin .../fonts/roboto/Roboto-LightItalic.woff | Bin .../fonts/roboto/Roboto-LightItalic.woff2 | Bin .../fonts/roboto/Roboto-Medium.woff | Bin .../fonts/roboto/Roboto-Medium.woff2 | Bin .../fonts/roboto/Roboto-MediumItalic.woff | Bin .../fonts/roboto/Roboto-MediumItalic.woff2 | Bin .../fonts/roboto/Roboto-Regular.woff | Bin .../fonts/roboto/Roboto-Regular.woff2 | Bin .../fonts/roboto/Roboto-RegularItalic.woff | Bin .../fonts/roboto/Roboto-RegularItalic.woff2 | Bin .../fonts/roboto/Roboto-Thin.woff | Bin .../fonts/roboto/Roboto-Thin.woff2 | Bin .../fonts/roboto/Roboto-ThinItalic.woff | Bin .../fonts/roboto/Roboto-ThinItalic.woff2 | Bin .../icons/material-icons/LICENSE.txt | 0 .../MaterialIcons-Regular.ijmap | 0 .../material-icons/MaterialIcons-Regular.woff | Bin .../MaterialIcons-Regular.woff2 | Bin .../{mdui@1.0.1 => mdui@1.0.2}/js/mdui.esm.js | 8 +- static/lib/mdui@1.0.2/js/mdui.esm.js.map | 1 + .../lib/{mdui@1.0.1 => mdui@1.0.2}/js/mdui.js | 8 +- static/lib/mdui@1.0.2/js/mdui.js.map | 1 + static/lib/mdui@1.0.2/js/mdui.min.js | 7 + static/lib/mdui@1.0.2/js/mdui.min.js.map | 1 + .../natural-compare-lite@1.4.0/index.min.js | 3 + .../dist/sweetalert2.min.css | 1 + .../dist/sweetalert2.min.js | 1 + templates/pan/admin/appearance.html | 23 +- templates/pan/admin/base.html | 118 +- templates/pan/admin/bypass.html | 74 + templates/pan/admin/cache.html | 78 + templates/pan/admin/common.html | 61 +- templates/pan/admin/disk.html | 150 +- templates/pan/admin/hide.html | 21 +- templates/pan/admin/login.html | 13 +- templates/pan/admin/pwd.html | 28 +- templates/pan/admin/safety.html | 16 +- templates/pan/admin/view.html | 18 +- templates/pan/admin/webdav.html | 78 + templates/pan/bootstrap/index.html | 242 +- templates/pan/cdn/admin/appearance.html | 46 - templates/pan/cdn/admin/base.html | 147 - templates/pan/cdn/admin/common.html | 71 - templates/pan/cdn/admin/disk.html | 291 - templates/pan/cdn/admin/hide.html | 53 - templates/pan/cdn/admin/login.html | 30 - templates/pan/cdn/admin/pwd.html | 64 - templates/pan/cdn/admin/safety.html | 41 - templates/pan/cdn/admin/view.html | 54 - templates/pan/cdn/bootstrap/index.html | 274 - templates/pan/cdn/classic/index.html | 102 - templates/pan/cdn/materialdesign/index.html | 259 - templates/pan/cdn/mdui/index.html | 353 - templates/pan/cdn/mdui/view-audio.html | 78 - templates/pan/cdn/mdui/view-base.html | 202 - templates/pan/cdn/mdui/view-code.html | 44 - templates/pan/cdn/mdui/view-epub.html | 143 - templates/pan/cdn/mdui/view-img.html | 16 - templates/pan/cdn/mdui/view-md.html | 21 - templates/pan/cdn/mdui/view-ns.html | 18 - templates/pan/cdn/mdui/view-office.html | 14 - templates/pan/cdn/mdui/view-pdf.html | 22 - templates/pan/cdn/mdui/view-video.html | 116 - templates/pan/classic/index.html | 147 +- templates/pan/materialdesign/index.html | 259 - templates/pan/mdui/index.html | 283 +- templates/pan/mdui/view-audio.html | 37 +- templates/pan/mdui/view-base.html | 240 +- templates/pan/mdui/view-code.html | 33 +- templates/pan/mdui/view-epub.html | 12 +- templates/pan/mdui/view-img.html | 16 +- templates/pan/mdui/view-md.html | 13 +- templates/pan/mdui/view-ns.html | 10 +- templates/pan/mdui/view-office.html | 9 +- templates/pan/mdui/view-pdf.html | 23 +- templates/pan/mdui/view-video.html | 134 +- util/common.go | 714 + util/file.go | 11 + 905 files changed, 77741 insertions(+), 47630 deletions(-) create mode 100644 .gitattributes mode change 100755 => 100644 .github/workflows/compile-to-release.yml mode change 100755 => 100644 .gitignore mode change 100755 => 100644 LICENSE mode change 100755 => 100644 README.md delete mode 100644 Util/Ali.go delete mode 100644 Util/Base.go delete mode 100644 Util/Cloud189.go delete mode 100644 Util/FTP.go delete mode 100755 Util/FileUtil.go delete mode 100644 Util/GoogleDrive.go delete mode 100644 Util/OneDrive.go delete mode 100755 Util/Teambition.go delete mode 100644 Util/WebDav.go delete mode 100644 Util/Yun139.go delete mode 100755 app.json delete mode 100644 boot/Init.go create mode 100644 boot/boot.go create mode 100644 config.json delete mode 100755 config/config.go delete mode 100755 config/config.json create mode 100644 control/admin.go create mode 100644 control/dav.go create mode 100644 control/index.go create mode 100644 control/middleware/Referer.go create mode 100644 control/middleware/jwt.go create mode 100644 control/middleware/pwd.go create mode 100644 control/public.go create mode 100644 control/router.go create mode 100644 control/webdav/file.go create mode 100644 control/webdav/if.go create mode 100644 control/webdav/internal/xml/README create mode 100644 control/webdav/internal/xml/marshal.go create mode 100644 control/webdav/internal/xml/read.go create mode 100644 control/webdav/internal/xml/typeinfo.go create mode 100644 control/webdav/internal/xml/xml.go create mode 100644 control/webdav/lock.go create mode 100644 control/webdav/prop.go create mode 100644 control/webdav/webdav.go create mode 100644 control/webdav/xml.go create mode 100644 dao/db.go create mode 100644 dao/mysql.go create mode 100644 dao/postgres.go create mode 100644 dao/sqlite.go mode change 100755 => 100644 docker/Dockerfile mode change 100755 => 100644 docker/arm64/Dockerfile mode change 100755 => 100644 docker/arm64/getPanIndex.sh mode change 100755 => 100644 docker/getPanIndex.sh mode change 100755 => 100644 docs/.nojekyll mode change 100755 => 100644 docs/_coverpage.md mode change 100755 => 100644 docs/_images/1-2.png mode change 100755 => 100644 docs/_images/audio.png mode change 100755 => 100644 docs/_images/teambition-project.png mode change 100755 => 100644 docs/_media/favicon.ico mode change 100755 => 100644 docs/_media/index.png mode change 100755 => 100644 docs/index.html mode change 100755 => 100644 docs/v1/README.md mode change 100755 => 100644 docs/v1/_images/1-2.png mode change 100755 => 100644 docs/v1/_images/audio.png mode change 100755 => 100644 docs/v1/_images/teambition-project.png delete mode 100755 entity/entity.go mode change 100755 => 100644 go.mod mode change 100755 => 100644 go.sum delete mode 100755 heroku.yml delete mode 100755 jobs/Jobs.go create mode 100644 jobs/jobs.go mode change 100755 => 100644 main.go delete mode 100755 model/sqlitedb.go create mode 100644 module/entity.go create mode 100644 pan/Ali.go create mode 100644 pan/Cloud189.go create mode 100644 pan/FTP.go create mode 100644 pan/GoogleDrive.go create mode 100644 pan/Native.go create mode 100644 pan/OneDrive.go create mode 100644 pan/Teambition.go create mode 100644 pan/WebDAV.go create mode 100644 pan/Yun139.go create mode 100644 pan/pan.go mode change 100755 => 100644 service/service.go mode change 100755 => 100644 static/img/favicon-cloud189.ico mode change 100755 => 100644 static/img/favicon-native.ico mode change 100755 => 100644 static/img/favicon-teambition-us.ico mode change 100755 => 100644 static/img/favicon-teambition.ico mode change 100755 => 100644 static/img/favicon-webdav.ico create mode 100644 static/img/music-cover.png delete mode 100755 static/js/main.js delete mode 100644 static/js/mdui-view.js create mode 100644 static/js/mdui.index.js create mode 100644 static/js/mdui.video.js create mode 100644 static/js/simple.index.js create mode 100644 static/js/simple.video.js create mode 100644 static/lib/artplayer@4.3.1/artplayer.min.js create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-grid.css create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-grid.css.map create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-grid.min.css create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-grid.min.css.map create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-reboot.css create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-reboot.css.map create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-reboot.min.css create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap-reboot.min.css.map create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap.css create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap.css.map create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap.min.css create mode 100644 static/lib/bootstrap@4.6.1/css/bootstrap.min.css.map create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.bundle.js create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.bundle.js.map create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.bundle.min.js create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.bundle.min.js.map create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.js create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.js.map create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.min.js create mode 100644 static/lib/bootstrap@4.6.1/js/bootstrap.min.js.map delete mode 100644 static/lib/dplayer@1.26.0/dist/DPlayer.min.js delete mode 100644 static/lib/dplayer@1.26.0/dist/DPlayer.min.js.map create mode 100644 static/lib/flv.js@1.6.2/dist/flv.js create mode 100644 static/lib/flv.js@1.6.2/dist/flv.js.map create mode 100644 static/lib/flv.js@1.6.2/dist/flv.min.js.map create mode 100644 static/lib/fontawesome@5.15.4/css/all.css create mode 100644 static/lib/fontawesome@5.15.4/css/all.min.css create mode 100644 static/lib/fontawesome@5.15.4/css/brands.css create mode 100644 static/lib/fontawesome@5.15.4/css/brands.min.css create mode 100644 static/lib/fontawesome@5.15.4/css/fontawesome.css create mode 100644 static/lib/fontawesome@5.15.4/css/fontawesome.min.css create mode 100644 static/lib/fontawesome@5.15.4/css/regular.css create mode 100644 static/lib/fontawesome@5.15.4/css/regular.min.css create mode 100644 static/lib/fontawesome@5.15.4/css/solid.css create mode 100644 static/lib/fontawesome@5.15.4/css/solid.min.css create mode 100644 static/lib/fontawesome@5.15.4/css/svg-with-js.css create mode 100644 static/lib/fontawesome@5.15.4/css/svg-with-js.min.css create mode 100644 static/lib/fontawesome@5.15.4/css/v4-shims.css create mode 100644 static/lib/fontawesome@5.15.4/css/v4-shims.min.css create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-brands-400.eot create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-brands-400.svg create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-brands-400.ttf create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-brands-400.woff create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-brands-400.woff2 create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.eot create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.svg create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.ttf create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.woff create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.woff2 create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.eot create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.svg create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.ttf create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.woff create mode 100644 static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.woff2 delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/LICENSE delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/README.md delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/core.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/core.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/highlight.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/highlight.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/1c.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/abnf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/accesslog.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/actionscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ada.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/angelscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/apache.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/applescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/arcade.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/arduino.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/armasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/asciidoc.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/aspectj.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/autohotkey.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/autoit.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/avrasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/awk.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/axapta.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/bash.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/basic.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/bnf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/brainfuck.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/c.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/cal.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/capnproto.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ceylon.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/clean.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/clojure-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/clojure.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/cmake.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/coffeescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/coq.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/cos.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/cpp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/crmsh.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/crystal.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/csharp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/csp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/css.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/d.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/dart.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/delphi.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/diff.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/django.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/dns.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/dockerfile.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/dos.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/dsconfig.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/dts.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/dust.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ebnf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/elixir.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/elm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/erb.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/erlang-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/erlang.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/excel.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/fix.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/flix.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/fortran.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/fsharp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/gams.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/gauss.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/gcode.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/gherkin.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/glsl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/gml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/go.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/golo.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/gradle.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/groovy.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/haml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/handlebars.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/haskell.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/haxe.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/hsp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/http.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/hy.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/inform7.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ini.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/irpf90.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/isbl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/java.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/javascript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/jboss-cli.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/json.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/julia-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/julia.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/kotlin.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/lasso.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/latex.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ldif.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/leaf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/less.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/lisp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/livecodeserver.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/livescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/llvm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/lsl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/lua.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/makefile.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/markdown.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/mathematica.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/matlab.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/maxima.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/mel.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/mercury.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/mipsasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/mizar.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/mojolicious.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/monkey.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/moonscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/n1ql.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/nestedtext.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/nginx.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/nim.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/nix.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/node-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/nsis.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/objectivec.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ocaml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/openscad.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/oxygene.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/parser3.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/perl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/pf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/pgsql.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/php-template.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/php.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/plaintext.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/pony.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/powershell.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/processing.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/profile.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/prolog.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/properties.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/protobuf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/puppet.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/purebasic.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/python-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/python.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/q.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/qml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/r.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/reasonml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/rib.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/roboconf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/routeros.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/rsl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ruby.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/ruleslanguage.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/rust.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/sas.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/scala.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/scheme.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/scilab.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/scss.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/shell.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/smali.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/smalltalk.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/sml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/sqf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/sql.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/stan.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/stata.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/step21.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/stylus.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/subunit.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/swift.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/taggerscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/tap.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/tcl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/thrift.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/tp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/twig.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/typescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/vala.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/vbnet.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/vbscript-html.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/vbscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/verilog.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/vhdl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/vim.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/wasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/wren.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/x86asm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/xl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/xml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/xquery.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/yaml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/languages/zephir.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/es/package.json delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/highlight.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/highlight.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/1c.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/abnf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/accesslog.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/actionscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ada.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/angelscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/apache.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/applescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/arcade.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/arduino.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/armasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/asciidoc.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/aspectj.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/autohotkey.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/autoit.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/avrasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/awk.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/axapta.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/bash.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/basic.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/bnf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/brainfuck.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/c.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/cal.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/capnproto.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ceylon.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/clean.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/clojure-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/clojure.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/cmake.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/coffeescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/coq.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/cos.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/cpp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/crmsh.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/crystal.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/csharp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/csp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/css.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/d.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/dart.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/delphi.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/diff.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/django.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/dns.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/dockerfile.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/dos.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/dsconfig.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/dts.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/dust.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ebnf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/elixir.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/elm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/erb.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/erlang-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/erlang.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/excel.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/fix.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/flix.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/fortran.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/fsharp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/gams.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/gauss.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/gcode.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/gherkin.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/glsl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/gml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/go.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/golo.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/gradle.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/groovy.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/haml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/handlebars.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/haskell.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/haxe.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/hsp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/http.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/hy.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/inform7.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ini.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/irpf90.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/isbl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/java.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/javascript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/jboss-cli.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/json.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/julia-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/julia.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/kotlin.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/lasso.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/latex.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ldif.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/leaf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/less.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/lisp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/livecodeserver.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/livescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/llvm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/lsl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/lua.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/makefile.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/markdown.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/mathematica.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/matlab.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/maxima.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/mel.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/mercury.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/mipsasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/mizar.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/mojolicious.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/monkey.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/moonscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/n1ql.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/nestedtext.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/nginx.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/nim.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/nix.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/node-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/nsis.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/objectivec.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ocaml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/openscad.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/oxygene.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/parser3.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/perl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/pf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/pgsql.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/php-template.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/php.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/plaintext.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/pony.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/powershell.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/processing.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/profile.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/prolog.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/properties.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/protobuf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/puppet.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/purebasic.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/python-repl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/python.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/q.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/qml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/r.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/reasonml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/rib.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/roboconf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/routeros.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/rsl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ruby.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/ruleslanguage.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/rust.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/sas.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/scala.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/scheme.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/scilab.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/scss.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/shell.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/smali.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/smalltalk.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/sml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/sqf.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/sql.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/stan.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/stata.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/step21.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/stylus.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/subunit.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/swift.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/taggerscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/tap.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/tcl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/thrift.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/tp.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/twig.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/typescript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/vala.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/vbnet.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/vbscript-html.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/vbscript.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/verilog.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/vhdl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/vim.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/wasm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/wren.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/x86asm.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/xl.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/xml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/xquery.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/yaml.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/languages/zephir.min.js delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/package.json delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/a11y-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/a11y-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/agate.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/an-old-hope.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/androidstudio.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/arduino-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/arta.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/ascetic.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/atom-one-dark-reasonable.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/3024.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/apathy.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/apprentice.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ashes.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-cave-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-cave.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-dune-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-dune.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-estuary-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-estuary.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-forest-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-forest.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-heath-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-heath.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-lakeside-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-lakeside.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-plateau-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-plateau.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-savanna-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-savanna.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-seaside-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-seaside.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-sulphurpool-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atelier-sulphurpool.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/atlas.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/bespin.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-bathory.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-burzum.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-dark-funeral.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-gorgoroth.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-immortal.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-khold.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-marduk.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-mayhem.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-nile.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal-venom.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/black-metal.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/brewer.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/bright.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/brogrammer.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/brush-trees-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/brush-trees.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/chalk.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/circus.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/classic-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/classic-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/codeschool.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/colors.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/cupcake.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/cupertino.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/danqing.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/darcula.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/dark-violet.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/darkmoss.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/darktooth.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/decaf.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/default-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/default-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/dirtysea.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/dracula.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/edge-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/edge-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/eighties.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/embers.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/equilibrium-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/equilibrium-gray-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/equilibrium-gray-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/equilibrium-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/espresso.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/eva-dim.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/eva.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/flat.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/framer.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/fruit-soda.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gigavolt.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/github.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/google-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/google-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/grayscale-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/grayscale-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/green-screen.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gruvbox-dark-hard.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gruvbox-dark-medium.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gruvbox-dark-pale.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gruvbox-dark-soft.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gruvbox-light-hard.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gruvbox-light-medium.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/gruvbox-light-soft.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/hardcore.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/harmonic16-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/harmonic16-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/heetch-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/heetch-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/helios.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/hopscotch.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/horizon-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/horizon-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/humanoid-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/humanoid-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ia-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ia-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/icy-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ir-black.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/isotope.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/kimber.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/london-tube.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/macintosh.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/marrakesh.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/materia.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/material-darker.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/material-lighter.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/material-palenight.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/material-vivid.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/material.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/mellow-purple.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/mexico-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/mocha.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/monokai.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/nebula.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/nord.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/nova.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ocean.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/oceanicnext.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/one-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/onedark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/outrun-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/papercolor-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/papercolor-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/paraiso.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/pasque.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/phd.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/pico.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/pop.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/porple.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/qualia.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/railscasts.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/rebecca.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ros-pine-dawn.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ros-pine-moon.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/ros-pine.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/sagelight.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/sandcastle.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/seti-ui.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/shapeshifter.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/silk-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/silk-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/snazzy.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/solar-flare-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/solar-flare.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/solarized-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/solarized-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/spacemacs.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/summercamp.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/summerfruit-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/summerfruit-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/synth-midnight-terminal-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/synth-midnight-terminal-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/tango.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/tender.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/tomorrow-night.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/tomorrow.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/twilight.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/unikitty-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/unikitty-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/vulcan.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-10-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-10.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-95-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-95.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-high-contrast-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-high-contrast.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-nt-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/windows-nt.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/woodland.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/xcode-dusk.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/base16/zenburn.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/brown-paper.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/brown-papersq.png delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/codepen-embed.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/color-brewer.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/default.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/devibeans.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/docco.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/far.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/foundation.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/github-dark-dimmed.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/github-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/github.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/gml.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/googlecode.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/gradient-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/gradient-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/grayscale.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/hybrid.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/idea.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/ir-black.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/isbl-editor-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/isbl-editor-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/kimbie-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/kimbie-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/lightfair.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/lioshi.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/magula.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/mono-blue.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/monokai-sublime.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/monokai.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/night-owl.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/nnfx-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/nnfx-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/nord.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/obsidian.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/paraiso-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/paraiso-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/pojoaque.jpg delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/pojoaque.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/purebasic.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/qtcreator-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/qtcreator-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/rainbow.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/routeros.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/school-book.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/shades-of-purple.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/srcery.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/stackoverflow-dark.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/stackoverflow-light.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/sunburst.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/tomorrow-night-blue.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/tomorrow-night-bright.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/vs.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/vs2015.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/xcode.min.css delete mode 100644 static/lib/highlightjs/cdn-release@11.2.0/build/styles/xt256.min.css create mode 100644 static/lib/highlightjs/cdn-release@11.4.0/build/highlight.min.js rename static/lib/highlightjs/{cdn-release@11.2.0 => cdn-release@11.4.0}/build/styles/atom-one-dark.min.css (100%) rename static/lib/highlightjs/{cdn-release@11.2.0 => cdn-release@11.4.0}/build/styles/atom-one-light.min.css (100%) delete mode 100644 static/lib/hls.js@1.0.7/dist/hls-demo.js.map delete mode 100644 static/lib/hls.js@1.0.7/dist/hls.js.map delete mode 100644 static/lib/hls.js@1.0.7/dist/hls.light.js.map delete mode 100644 static/lib/hls.js@1.0.7/dist/hls.light.min.js delete mode 100644 static/lib/hls.js@1.0.7/dist/hls.light.min.js.map delete mode 100644 static/lib/hls.js@1.0.7/dist/hls.min.js delete mode 100644 static/lib/hls.js@1.0.7/dist/hls.min.js.map rename static/lib/{hls.js@1.0.7 => hls.js@1.1.2}/dist/hls-demo.js (99%) create mode 100644 static/lib/hls.js@1.1.2/dist/hls-demo.js.map rename static/lib/{hls.js@1.0.7 => hls.js@1.1.2}/dist/hls.js (97%) rename static/lib/{hls.js@1.0.7 => hls.js@1.1.2}/dist/hls.js.d.ts (87%) create mode 100644 static/lib/hls.js@1.1.2/dist/hls.js.map rename static/lib/{hls.js@1.0.7 => hls.js@1.1.2}/dist/hls.light.js (99%) create mode 100644 static/lib/hls.js@1.1.2/dist/hls.light.js.map create mode 100644 static/lib/hls.js@1.1.2/dist/hls.light.min.js create mode 100644 static/lib/hls.js@1.1.2/dist/hls.light.min.js.map create mode 100644 static/lib/hls.js@1.1.2/dist/hls.min.js create mode 100644 static/lib/hls.js@1.1.2/dist/hls.min.js.map create mode 100644 static/lib/md5/md5.min.js create mode 100644 static/lib/md5/md5.min.js.map delete mode 100644 static/lib/mdui@1.0.1/js/mdui.esm.js.map delete mode 100644 static/lib/mdui@1.0.1/js/mdui.js.map delete mode 100644 static/lib/mdui@1.0.1/js/mdui.min.js delete mode 100644 static/lib/mdui@1.0.1/js/mdui.min.js.map rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/css/mdui.css (99%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/css/mdui.css.map (99%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/css/mdui.min.css (99%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/css/mdui.min.css.map (99%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/LICENSE.txt (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Black.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Black.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-BlackItalic.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-BlackItalic.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Bold.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Bold.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-BoldItalic.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-BoldItalic.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Light.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Light.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-LightItalic.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-LightItalic.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Medium.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Medium.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-MediumItalic.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-MediumItalic.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Regular.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Regular.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-RegularItalic.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-RegularItalic.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Thin.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-Thin.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-ThinItalic.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/fonts/roboto/Roboto-ThinItalic.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/icons/material-icons/LICENSE.txt (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/icons/material-icons/MaterialIcons-Regular.ijmap (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/icons/material-icons/MaterialIcons-Regular.woff (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/icons/material-icons/MaterialIcons-Regular.woff2 (100%) rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/js/mdui.esm.js (99%) create mode 100644 static/lib/mdui@1.0.2/js/mdui.esm.js.map rename static/lib/{mdui@1.0.1 => mdui@1.0.2}/js/mdui.js (99%) create mode 100644 static/lib/mdui@1.0.2/js/mdui.js.map create mode 100644 static/lib/mdui@1.0.2/js/mdui.min.js create mode 100644 static/lib/mdui@1.0.2/js/mdui.min.js.map create mode 100644 static/lib/natural-compare-lite@1.4.0/index.min.js create mode 100644 static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.css create mode 100644 static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.js create mode 100644 templates/pan/admin/bypass.html create mode 100644 templates/pan/admin/cache.html create mode 100644 templates/pan/admin/webdav.html delete mode 100644 templates/pan/cdn/admin/appearance.html delete mode 100644 templates/pan/cdn/admin/base.html delete mode 100644 templates/pan/cdn/admin/common.html delete mode 100644 templates/pan/cdn/admin/disk.html delete mode 100644 templates/pan/cdn/admin/hide.html delete mode 100644 templates/pan/cdn/admin/login.html delete mode 100644 templates/pan/cdn/admin/pwd.html delete mode 100644 templates/pan/cdn/admin/safety.html delete mode 100644 templates/pan/cdn/admin/view.html delete mode 100644 templates/pan/cdn/bootstrap/index.html delete mode 100644 templates/pan/cdn/classic/index.html delete mode 100644 templates/pan/cdn/materialdesign/index.html delete mode 100644 templates/pan/cdn/mdui/index.html delete mode 100644 templates/pan/cdn/mdui/view-audio.html delete mode 100644 templates/pan/cdn/mdui/view-base.html delete mode 100644 templates/pan/cdn/mdui/view-code.html delete mode 100644 templates/pan/cdn/mdui/view-epub.html delete mode 100644 templates/pan/cdn/mdui/view-img.html delete mode 100644 templates/pan/cdn/mdui/view-md.html delete mode 100644 templates/pan/cdn/mdui/view-ns.html delete mode 100644 templates/pan/cdn/mdui/view-office.html delete mode 100644 templates/pan/cdn/mdui/view-pdf.html delete mode 100644 templates/pan/cdn/mdui/view-video.html delete mode 100644 templates/pan/materialdesign/index.html create mode 100644 util/common.go create mode 100644 util/file.go diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..d1f99700 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.js linguist-language=golang +*.css linguist-language=golang +*.html linguist-language=golang \ No newline at end of file diff --git a/.github/workflows/compile-to-release.yml b/.github/workflows/compile-to-release.yml old mode 100755 new mode 100644 index a44baaa8..71384cb2 --- a/.github/workflows/compile-to-release.yml +++ b/.github/workflows/compile-to-release.yml @@ -3,12 +3,26 @@ on: release: types: [created] jobs: - releases-matrix: - name: Release Go Binary - runs-on: ubuntu-latest - # if: github.event.repository.owner.id == github.event.sender.id + release: + strategy: + matrix: + platform: [ubuntu-latest] + go-version: [1.17] + name: PanIndex Release + runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v2 - - uses: libsgh/PanIndex-release-action@master + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout + uses: actions/checkout@v2 + with: + persist-credentials: false + ref: master + - name: Build PanIndex + uses: libsgh/PanIndex-build-action@main + - name: Release + uses: softprops/action-gh-release@v1 with: - github_token: ${{ secrets.GH_TOKEN }} \ No newline at end of file + files: /home/runner/work/PanIndex/PanIndex/dist/compress/* \ No newline at end of file diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index cae2b7fc..9e4c9788 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,2 @@ -.env -.docker_build/ -.idea/ -bin/ -/bin/ -PanIndex -data/ +/bin/* +/.idea/ diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 03127ca8..925f414a --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - OneDrive国际版 ## 示例 -- [在线演示](https://t1.noki.icu "https://t1.noki.icu") +- [在线演示](https://t1.netrss.cf "https://t1.netrss.cf") ## 文档 [在线文档](https://libsgh.github.io/PanIndex/) @@ -27,4 +27,4 @@ - 后端框架:[gin-gonic](https://github.com/gin-gonic/gin) ## 声明 -本程序旨在分享网盘文件,方便下载,请勿滥用。在使用本程序之前,你应了解并承担相应的风险,包括但不限于账号被ban,下载限速等。 +本程序旨在分享网盘文件,方便下载,请勿滥用。在使用本程序之前,你应了解并承担相应的风险,包括但不限于账号被ban,下载限速等。 \ No newline at end of file diff --git a/Util/Ali.go b/Util/Ali.go deleted file mode 100644 index ea50a974..00000000 --- a/Util/Ali.go +++ /dev/null @@ -1,320 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "PanIndex/model" - "bytes" - "encoding/json" - "fmt" - jsoniter "github.com/json-iterator/go" - "github.com/libsgh/nic" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "io/ioutil" - "mime/multipart" - "net/http" - "sort" - "strings" - "time" -) - -var Alis = map[string]entity.TokenResp{} - -func AliRefreshToken(account entity.Account) string { - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - resp, err := nic.Post("https://auth.aliyundrive.com/v2/account/token", nic.H{ - JSON: nic.KV{ - "refresh_token": account.RefreshToken, - "grant_type": "refresh_token", - }, - }) - if err != nil { - panic(err.Error()) - return "" - } - var tokenResp entity.TokenResp - err = jsoniter.Unmarshal(resp.Bytes, &tokenResp) - if err != nil { - panic(err.Error()) - return "" - } - Alis[account.Id] = tokenResp - return tokenResp.RefreshToken -} - -func AliGetFiles(accountId, rootId, fileId, p string, hide, hasPwd int, syncChild bool) { - tokenResp := Alis[accountId] - auth := tokenResp.TokenType + " " + tokenResp.AccessToken - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - limit := 100 - nextMarker := "" - for { - resp, err := nic.Post("https://api.aliyundrive.com/v2/file/list", nic.H{ - Headers: nic.KV{ - "authorization": auth, - }, - JSON: nic.KV{ - "all": false, - "drive_id": tokenResp.UserInfo.DefaultDriveId, - "fields": "*", - "image_thumbnail_process": "image/resize,w_400/format,jpeg", - "image_url_process": "image/resize,w_1920/format,jpeg", - "limit": limit, - "marker": nextMarker, - "order_by": "updated_at", - "order_direction": "DESC", - "parent_file_id": fileId, - "video_thumbnail_process": "video/snapshot,t_0,f_jpg,ar_auto,w_300", - }, - }) - if err != nil { - panic(err.Error()) - } - byteFiles := []byte(resp.Text) - d := jsoniter.Get(byteFiles, "items") - nextMarker = jsoniter.Get(byteFiles, "next_marker").ToString() - var m []map[string]interface{} - json.Unmarshal([]byte(d.ToString()), &m) - for _, item := range m { - fn := entity.FileNode{} - fn.AccountId = accountId - fn.FileId = item["file_id"].(string) - fn.FileName = item["name"].(string) - fn.FileIdDigest = "" - fn.CreateTime = UTCTimeFormat(item["created_at"].(string)) - fn.LastOpTime = UTCTimeFormat(item["updated_at"].(string)) - fn.Delete = 1 - kind := item["type"].(string) - if kind == "file" { - if item["file_extension"] == nil { - fn.FileType = "" - } else { - fn.FileType = item["file_extension"].(string) - } - fn.IsFolder = false - fn.FileSize = int64(item["size"].(float64)) - fn.SizeFmt = FormatFileSize(fn.FileSize) - category := item["category"].(string) - if category == "image" { - //图片 - fn.MediaType = 1 - } else if category == "doc" { - //文本 - fn.MediaType = 4 - } else if category == "video" { - //视频 - fn.MediaType = 3 - } else if category == "audio" { - //音频 - fn.MediaType = 2 - } else { - //其他类型 - fn.MediaType = 0 - } - fn.DownloadUrl = item["download_url"].(string) - } else { - fn.FileType = "" - fn.IsFolder = true - fn.FileSize = 0 - fn.SizeFmt = "-" - fn.MediaType = 0 - fn.DownloadUrl = "" - } - //天翼云网盘独有,这里随便定义一个 - fn.IsStarred = item["starred"].(bool) - fn.ParentId = item["parent_file_id"].(string) - fn.Hide = 0 - fn.HasPwd = 0 - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - fn.ParentPath = p - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - if fn.IsFolder == true { - if syncChild { - AliGetFiles(accountId, rootId, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fn.Id = uuid.NewV4().String() - fn.CacheTime = time.Now().UnixNano() - model.SqliteDb.Create(fn) - } - if nextMarker == "" { - break - } - } - -} -func AliGetDownloadUrl(accountId, fileId string) string { - tokenResp := Alis[accountId] - auth := tokenResp.TokenType + " " + tokenResp.AccessToken - resp, err := nic.Post("https://api.aliyundrive.com/v2/file/get_download_url", nic.H{ - Headers: nic.KV{ - "authorization": auth, - }, - JSON: nic.KV{ - "drive_id": tokenResp.UserInfo.DefaultDriveId, - "file_id": fileId, - "expire_sec": 14400, - }, - }) - if err != nil { - return "" - } - fmt.Println(resp.Text) - downUrl := jsoniter.Get(resp.Bytes, "url").ToString() - speedLimit := jsoniter.Get(resp.Bytes, "ratelimit").Get("part_speed").ToInt() - if downUrl == "" { - log.Warningln("阿里云盘下载地址获取失败") - } - if speedLimit != -1 { - log.Warningf("该文件限速:%d", speedLimit) - } - return downUrl -} - -func AliFolderDownload(accountId, fileId, archiveName, ua string) string { - tokenResp := Alis[accountId] - auth := tokenResp.TokenType + " " + tokenResp.AccessToken - resp, err := nic.Post("https://api.aliyundrive.com/adrive/v1/file/multiDownloadUrl", nic.H{ - Headers: nic.KV{ - "authorization": auth, - "User-Agent": ua, - }, - JSON: nic.KV{ - "download_infos": []nic.KV{nic.KV{ - "drive_id": tokenResp.DefaultDriveId, - "files": []nic.KV{nic.KV{ - "file_id": fileId, - }}, - }, - }, - "archive_name": archiveName, - }, - }) - if err != nil { - return "" - } - downUrl := jsoniter.Get(resp.Bytes, "download_url").ToString() - if downUrl == "" { - log.Warningln("阿里云盘下载地址获取失败") - } - return downUrl -} - -func AliUpload(accountId, parentId string, files []*multipart.FileHeader) bool { - tokenResp := Alis[accountId] - auth := tokenResp.TokenType + " " + tokenResp.AccessToken - for _, file := range files { - t1 := time.Now() - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - resp, _ := nic.Post("https://api.aliyundrive.com/v2/file/create_with_proof", nic.H{ - Headers: nic.KV{ - "authorization": auth, - }, - JSON: nic.KV{ - "drive_id": tokenResp.DefaultDriveId, - "part_info_list": []nic.KV{nic.KV{ - "part_number": 1, - }, - }, - "pre_hash": "", - "parent_file_id": parentId, - "name": file.Filename, - "type": "file", - "check_name_mode": "auto_rename", - "size": file.Size, - }, - }) - rapidUpload := jsoniter.Get(resp.Bytes, "rapid_upload").ToBool() - if rapidUpload { - //秒传成功 - log.Debugf("上传接口返回:%s", resp.Text) - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - return true - } - fileId := jsoniter.Get(resp.Bytes, "file_id").ToString() - uploadId := jsoniter.Get(resp.Bytes, "upload_id").ToString() - driveId := jsoniter.Get(resp.Bytes, "drive_id").ToString() - partInfoListString := jsoniter.Get(resp.Bytes, "part_info_list").ToString() - partInfoList := []entity.AliPartInfo{} - jsoniter.UnmarshalFromString(partInfoListString, &partInfoList) - log.Debugf("文件分片数:%d", len(partInfoList)) - for _, partInfo := range partInfoList { - fileContent, _ := file.Open() - byteContent, _ := ioutil.ReadAll(fileContent) - client := &http.Client{} - req, err := http.NewRequest(http.MethodPut, partInfo.UploadUrl, bytes.NewBuffer(byteContent)) - if err != nil { - log.Error("上传失败") - return false - } - client.Do(req) - } - resp, _ = nic.Post("https://api.aliyundrive.com/v2/file/complete", nic.H{ - Headers: nic.KV{ - "authorization": auth, - }, - JSON: nic.KV{ - "drive_id": driveId, - "file_id": fileId, - "upload_id": uploadId, - }, - }) - log.Debugf("上传接口返回:%s", resp.Text) - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return true -} - -//阿里云转码 -func AliTranscoding(accountId, fileId string) string { - tokenResp := Alis[accountId] - auth := tokenResp.TokenType + " " + tokenResp.AccessToken - resp, _ := nic.Post("https://api.aliyundrive.com/v2/file/get_video_preview_play_info", nic.H{ - Headers: nic.KV{ - "authorization": auth, - }, - JSON: nic.KV{ - "category": "live_transcoding", - "drive_id": tokenResp.DefaultDriveId, - "file_id": fileId, - "template_id": "", - }, - }) - return resp.Text -} diff --git a/Util/Base.go b/Util/Base.go deleted file mode 100644 index ba67e65f..00000000 --- a/Util/Base.go +++ /dev/null @@ -1,294 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "bufio" - "crypto/md5" - "encoding/hex" - "encoding/json" - "fmt" - log "github.com/sirupsen/logrus" - "golang.org/x/text/encoding" - "golang.org/x/text/encoding/simplifiedchinese" - "golang.org/x/text/encoding/unicode" - "io/fs" - "math/rand" - "path/filepath" - "sort" - "strconv" - "strings" - "time" -) - -func ShortDur(d time.Duration) string { - v, _ := strconv.ParseFloat(fmt.Sprintf("%.1f", d.Seconds()), 64) - return fmt.Sprint(v) + "s" -} -func GetCurBetweenStr(str, start, end string) string { - n := strings.Index(str, start) - if n == -1 { - return "" - } - n = n + len(start) - str = string([]byte(str)[n:]) - m := strings.Index(str, end) - if m == -1 { - return "" - } - str = string([]byte(str)[:m]) - return str -} - -func GetRandomString(n int) string { - randBytes := make([]byte, n/2) - rand.Read(randBytes) - return fmt.Sprintf("%x", randBytes) -} - -func GetNextOrPrevious(slice []fs.FileInfo, fs fs.FileInfo, flag int) fs.FileInfo { - index := 0 - for p, v := range slice { - if v.Name() == fs.Name() { - index = p - } - } - if flag == 0 { - return fs - } else if flag == -1 { - if index > 0 { - index = index + flag - } else { - return nil - } - } else if flag == 1 { - if index < len(slice)-1 { - index = index + flag - } else { - return nil - } - } - return slice[index] -} - -func FilterFiles(slice []fs.FileInfo, fullPath, sColumn, sOrder string) []fs.FileInfo { - sort.Slice(slice, func(i, j int) bool { - d1 := 0 - if slice[i].IsDir() { - d1 = 1 - } - d2 := 0 - if slice[j].IsDir() { - d2 = 1 - } - if d1 > d2 { - return true - } else if d1 == d2 { - if sColumn == "file_name" { - c := strings.Compare(slice[i].Name(), slice[j].Name()) - if sOrder == "desc" { - return c >= 0 - } else { - return c <= 0 - } - } else if sColumn == "file_size" { - if sOrder == "desc" { - return slice[i].Size() >= slice[j].Size() - } else { - return slice[i].Size() <= slice[j].Size() - } - } else if sColumn == "last_op_time" { - if sOrder == "desc" { - return slice[i].ModTime().After(slice[j].ModTime()) - } else { - return slice[i].ModTime().Before(slice[j].ModTime()) - } - } else { - return slice[i].ModTime().After(slice[j].ModTime()) - } - } else { - return false - } - }) - arr := []fs.FileInfo{} - for _, v := range slice { - fileId := filepath.Join(fullPath, v.Name()) - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fileId) - if i < len(listSTring) && listSTring[i] == fileId { - continue - } - } - if !v.IsDir() { - arr = append(arr, v) - } - } - return arr -} - -func DetermineEncoding(r *bufio.Reader) encoding.Encoding { - _, err := r.Peek(1024) - if err != nil { - log.Error("get code error") - return unicode.UTF8 - } - return simplifiedchinese.GBK -} - -func CheckPwdOld(PwdDirIds, fileId, pwd string) (bool, bool) { - hasPath := false - pwdOk := false - s := strings.Split(PwdDirIds, ",") - for _, v := range s { - if strings.Split(v, ":")[0] == fileId { - hasPath = true - } - if pwd == strings.Split(v, ":")[1] { - pwdOk = true - } - } - return hasPath, pwdOk -} -func CheckPwd(configPwd, fileId, cookiePwd string) (bool, bool, string) { - hasPwd := false - msg := "" - pwd := GetPwdFromCookie(cookiePwd, fileId) - pwdOk := false - s := strings.Split(configPwd, ",") - for _, v := range s { - if strings.Split(v, ":")[0] == fileId { - hasPwd = true - if strings.Split(v, ":")[1] == pwd { - pwdOk = true - } - } - } - if pwd != "" && !pwdOk { - msg = "密码错误" - } - return hasPwd, pwdOk, msg -} -func CheckHide(fileId, hideIds string) bool { - hideOk := false - if hideIds != "" { - s := strings.Split(hideIds, ",") - for _, v := range s { - r := strings.HasPrefix(fileId, v) - if r { - hideOk = true - break - } - } - } - return hideOk -} -func GetPwdFromCookie(pwd, fileId string) string { - s := strings.Split(pwd, ",") - if len(s) > 0 { - for _, v := range s { - if strings.Split(v, ":")[0] == fileId { - return strings.Split(v, ":")[1] - } - } - } - return "" -} - -const ( - VAL = 0x3FFFFFFF - INDEX = 0x0000003D -) - -var ( - alphabet = []byte("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") -) - -/** implementation of short url algorithm **/ -func Transform(longURL string) ([4]string, error) { - md5Str := getMd5Str(longURL) - //var hexVal int64 - var tempVal int64 - var result [4]string - var tempUri []byte - for i := 0; i < 4; i++ { - tempSubStr := md5Str[i*8 : (i+1)*8] - hexVal, err := strconv.ParseInt(tempSubStr, 16, 64) - if err != nil { - return result, nil - } - tempVal = int64(VAL) & hexVal - var index int64 - tempUri = []byte{} - for i := 0; i < 6; i++ { - index = INDEX & tempVal - tempUri = append(tempUri, alphabet[index]) - tempVal = tempVal >> 5 - } - result[i] = string(tempUri) - } - return result, nil -} - -/** generate md5 checksum of URL in hex format **/ -func getMd5Str(str string) string { - m := md5.New() - m.Write([]byte(str)) - c := m.Sum(nil) - return hex.EncodeToString(c) -} -func Strval(value interface{}) string { - // interface 转 string - var key string - if value == nil { - return key - } - - switch value.(type) { - case float64: - ft := value.(float64) - key = strconv.FormatFloat(ft, 'f', -1, 64) - case float32: - ft := value.(float32) - key = strconv.FormatFloat(float64(ft), 'f', -1, 64) - case int: - it := value.(int) - key = strconv.Itoa(it) - case uint: - it := value.(uint) - key = strconv.Itoa(int(it)) - case int8: - it := value.(int8) - key = strconv.Itoa(int(it)) - case uint8: - it := value.(uint8) - key = strconv.Itoa(int(it)) - case int16: - it := value.(int16) - key = strconv.Itoa(int(it)) - case uint16: - it := value.(uint16) - key = strconv.Itoa(int(it)) - case int32: - it := value.(int32) - key = strconv.Itoa(int(it)) - case uint32: - it := value.(uint32) - key = strconv.Itoa(int(it)) - case int64: - it := value.(int64) - key = strconv.FormatInt(it, 10) - case uint64: - it := value.(uint64) - key = strconv.FormatUint(it, 10) - case string: - key = value.(string) - case []byte: - key = string(value.([]byte)) - default: - newValue, _ := json.Marshal(value) - key = string(newValue) - } - - return key -} diff --git a/Util/Cloud189.go b/Util/Cloud189.go deleted file mode 100644 index 7f585fc4..00000000 --- a/Util/Cloud189.go +++ /dev/null @@ -1,641 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "PanIndex/model" - "bytes" - "crypto/hmac" - "crypto/rand" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "encoding/base64" - "encoding/hex" - "encoding/json" - "encoding/pem" - "fmt" - jsoniter "github.com/json-iterator/go" - "github.com/libsgh/nic" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "io" - "io/ioutil" - math_rand "math/rand" - "mime/multipart" - "net/http" - "os" - "regexp" - "sort" - "strconv" - "strings" - "time" -) - -//var CLoud189Session nic.Session -var CLoud189Sessions = map[string]entity.Cloud189{} - -//获取文件列表2.0 -func Cloud189GetFiles(accountId, rootId, fileId, p string, hide, hasPwd int, syncChild bool) { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - pageNum := 1 - for { - url := fmt.Sprintf("https://cloud.189.cn/api/open/file/listFiles.action?noCache=%s&pageSize=100&pageNum=%d&mediaType=0&folderId=%s&iconOption=5&orderBy=lastOpTime&descending=true", random(), pageNum, fileId) - resp, err := CLoud189Session.Get(url, nic.H{ - Headers: nic.KV{ - "accept": "application/json;charset=UTF-8", - }, - }) - if err != nil { - panic(err.Error()) - } - byteFiles := []byte(resp.Text) - totalCount := jsoniter.Get(byteFiles, "fileListAO").Get("count").ToInt() - if totalCount == 0 { - break - } - d := jsoniter.Get(byteFiles, "fileListAO").Get("folderList") - var folderList []Folder - json.Unmarshal([]byte(d.ToString()), &folderList) - //同步文件夹 - for _, item := range folderList { - fn := entity.FileNode{} - fn.FileId = fmt.Sprintf("%d", item.Id) - fn.AccountId = accountId - fn.FileName = item.Name - fn.CreateTime = item.CreateDate - fn.LastOpTime = item.LastOpTime - fn.FileType = "" - fn.IsFolder = true - fn.FileSize = 0 - fn.SizeFmt = "-" - fn.MediaType = 0 - fn.DownloadUrl = "" - fn.ParentId = fmt.Sprintf("%d", item.ParentId) - fn.ParentPath = p - fn.Hide = 0 - fn.HasPwd = 0 - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - if fn.IsFolder == true { - //同步子目录&&子目录不为空 - if syncChild && item.FileCount > 0 { - Cloud189GetFiles(accountId, rootId, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fn.Delete = 1 - fn.Id = uuid.NewV4().String() - fn.CacheTime = time.Now().UnixNano() - model.SqliteDb.Create(fn) - /**/ - } - //同步文件 - d = jsoniter.Get(byteFiles, "fileListAO").Get("fileList") - var fileList []File - json.Unmarshal([]byte(d.ToString()), &fileList) - //同步文件夹 - for _, item := range fileList { - fn := entity.FileNode{} - fn.AccountId = accountId - fn.FileId = fmt.Sprintf("%d", item.Id) - fn.FileName = item.Name - fn.FileIdDigest = "" - fn.CreateTime = item.CreateDate - fn.LastOpTime = item.LastOpTime - fn.FileSize = item.Size - fn.SizeFmt = FormatFileSize(fn.FileSize) - fn.Id = uuid.NewV4().String() - fn.CacheTime = time.Now().UnixNano() - fn.IsFolder = false - fn.IsStarred = false - fn.MediaType = item.MediaType - fn.FileType = GetFileType(fn.FileName) - fn.ParentId = fileId - fn.ParentPath = p - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - fn.Hide = 0 - fn.HasPwd = 0 - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - fn.Delete = 1 - fn.Id = uuid.NewV4().String() - fn.CacheTime = time.Now().UnixNano() - model.SqliteDb.Create(fn) - } - pageNum++ - } -} - -type Folder struct { - CreateDate string `json:"createDate"` - FileCata int `json:"fileCata"` - FileCount int `json:"fileCount"` - FileListSize int `json:"fileListSize"` - Id int64 `json:"id"` - LastOpTime string `json:"lastOpTime"` - Name string `json:"name"` - ParentId int64 `json:"parentId"` - Rev string `json:"rev"` - StarLabel int `json:"starLabel"` -} -type File struct { - CreateDate string `json:"createDate"` - FileCata int `json:"fileCata"` - Id int64 `json:"id"` - LastOpTime string `json:"lastOpTime"` - Md5 string `json:"md5"` - MediaType int `json:"mediaType"` - Name string `json:"name"` - Rev string `json:"rev"` - StarLabel int `json:"starLabel"` - Size int64 `json:"size"` -} - -func GetDownlaodUrlNew(accountId, fileId string) string { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - defer CLoud189Session.Client.CloseIdleConnections() - dRedirectRep, err := CLoud189Session.Get(fmt.Sprintf("https://cloud.189.cn/api/open/file/getFileDownloadUrl.action?noCache=%s&fileId=%s", random(), fileId), nic.H{ - Headers: nic.KV{ - "accept": "application/json;charset=UTF-8 ", - }, - }) - if dRedirectRep != nil { - defer dRedirectRep.Body.Close() - } - if err != nil { - log.Error(err) - return "" - } - resCode := jsoniter.Get(dRedirectRep.Bytes, "res_code").ToInt() - if resCode == 0 { - fileDownloadUrl := jsoniter.Get(dRedirectRep.Bytes, "fileDownloadUrl").ToString() - dRedirectRep, err = CLoud189Session.Get(fileDownloadUrl, nic.H{ - AllowRedirect: false, - Timeout: 20, - DisableKeepAlives: true, - }) - if dRedirectRep != nil { - defer dRedirectRep.Body.Close() - } - if err != nil { - log.Error(err) - return "" - } - return dRedirectRep.Header.Get("location") - } else { - return "" - } -} -func GetDownlaodMultiFiles(accountId, fileId string) string { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - dRedirectRep, _ := CLoud189Session.Get(fmt.Sprintf("https://cloud.189.cn/downloadMultiFiles.action?fileIdS=%s&downloadType=1&recursive=1", fileId), nic.H{ - AllowRedirect: false, - }) - redirectUrl := dRedirectRep.Header.Get("Location") - return redirectUrl -} - -//天翼云网盘登录 -func Cloud189Login(accountId, user, password string) string { - CLoud189Session := nic.Session{} - url := "https://cloud.189.cn/api/portal/loginUrl.action?redirectURL=https%3A%2F%2Fcloud.189.cn%2Fmain.action" - res, err := CLoud189Session.Get(url, nil) - if err != nil { - log.Errorln(err) - return "5" - } - log.Debugf("登录页面接口:%s", res.Status) - b := res.Text - lt := "" - ltText := regexp.MustCompile(`lt = "(.+?)"`) - ltTextArr := ltText.FindStringSubmatch(b) - if len(ltTextArr) > 0 { - lt = ltTextArr[1] - } else { - return "" - } - captchaToken := regexp.MustCompile(`captchaToken' value='(.+?)'`).FindStringSubmatch(b)[1] - returnUrl := regexp.MustCompile(`returnUrl = '(.+?)'`).FindStringSubmatch(b)[1] - paramId := regexp.MustCompile(`paramId = "(.+?)"`).FindStringSubmatch(b)[1] - //reqId := regexp.MustCompile(`reqId = "(.+?)"`).FindStringSubmatch(b)[1] - jRsakey := regexp.MustCompile(`j_rsaKey" value="(\S+)"`).FindStringSubmatch(b)[1] - vCodeID := regexp.MustCompile(`picCaptcha\.do\?token\=([A-Za-z0-9\&\=]+)`).FindStringSubmatch(b)[1] - vCodeRS := "" - if vCodeID != "" { - //vCodeRS = GetValidateCode(accountId, vCodeID) - //log.Warningln("[登录接口]得到验证码:" + vCodeRS) - //log.Warningln("[登录接口]需要输入验证码") - //return "4" - } - userRsa := RsaEncode([]byte(user), jRsakey) - passwordRsa := RsaEncode([]byte(password), jRsakey) - url = "https://open.e.189.cn/api/logbox/oauth2/loginSubmit.do" - loginResp, _ := CLoud189Session.Post(url, nic.H{ - Data: nic.KV{ - "appKey": "cloud", - "accountType": "01", - "userName": "{RSA}" + userRsa, - "password": "{RSA}" + passwordRsa, - "validateCode": vCodeRS, - "captchaToken": captchaToken, - "returnUrl": returnUrl, - "mailSuffix": "@pan.cn", - "paramId": paramId, - "clientType": "10010", - "dynamicCheck": "FALSE", - "cb_SaveName": "1", - "isOauth2": "false", - }, - Headers: nic.KV{ - "lt": lt, - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/76.0", - "Referer": "https://open.e.189.cn/", - }, - }) - restCode := jsoniter.Get([]byte(loginResp.Text), "result").ToInt() - //0登录成功,-2,需要获取验证码,-5 app info获取失败 - if restCode == 0 { - toUrl := jsoniter.Get([]byte(loginResp.Text), "toUrl").ToString() - res, err := CLoud189Session.Get(toUrl, nic.H{ - AllowRedirect: false, - }) - if err != nil { - log.Warningln(err.Error()) - return "4" - } - sessionKey := GetSessionKey(CLoud189Session) - CLoud189Sessions[accountId] = entity.Cloud189{CLoud189Session, sessionKey} - return res.Cookies()[0].Value - } - errorReason := jsoniter.Get([]byte(loginResp.Text), "msg").ToString() - if errorReason == "" { - switch restCode { - case -2: - errorReason = "需要验证码" - case -5: - errorReason = "App Info 获取失败" - default: - errorReason = "未知错误" - } - } - log.Warningln("[登录接口]登录失败,错误代码:" + strconv.Itoa(restCode) + " (" + errorReason + ")") - return "4" -} - -func GetSessionKey(session nic.Session) string { - resp, error := session.Get("https://cloud.189.cn/v2/getUserBriefInfo.action?noCache="+random(), nil) - if error != nil { - return "" - } - sessionKey := jsoniter.Get(resp.Bytes, "sessionKey").ToString() - return sessionKey -} - -func GetRsaKey(accountId string) (string, string) { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - resp, error := CLoud189Session.Get("https://cloud.189.cn/api/security/generateRsaKey.action?noCache="+random(), nic.H{ - Headers: nic.KV{ - "accept": "application/json;charset=UTF-8", - }, - }) - if error != nil { - return "", "" - } - pubKey := jsoniter.Get(resp.Bytes, "pubKey").ToString() - pkId := jsoniter.Get(resp.Bytes, "pkId").ToString() - return pubKey, pkId -} - -func Cloud189IsLogin(accountId string) bool { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - if _, ok := CLoud189Sessions[accountId]; ok { - resp, err := CLoud189Session.Get("https://cloud.189.cn/v2/getLoginedInfos.action?showPC=true", nic.H{ - Timeout: 20, - DisableKeepAlives: true, - }) - if resp != nil { - defer resp.Body.Close() - } - if err == nil && resp != nil && resp.Text != "" && jsoniter.Valid(resp.Bytes) && jsoniter.Get(resp.Bytes, "errorMsg").ToString() == "" { - return true - } else { - if jsoniter.Get(resp.Bytes, "errorCode").ToString() == "InvalidSessionKey" { - return false - } else { - return true - } - } - } - return false -} - -// 加密 -func RsaEncode(origData []byte, j_rsakey string) string { - publicKey := []byte("-----BEGIN PUBLIC KEY-----\n" + j_rsakey + "\n-----END PUBLIC KEY-----") - block, _ := pem.Decode(publicKey) - pubInterface, _ := x509.ParsePKIXPublicKey(block.Bytes) - pub := pubInterface.(*rsa.PublicKey) - b, err := rsa.EncryptPKCS1v15(rand.Reader, pub, origData) - if err != nil { - log.Errorf("err: %s", err.Error()) - } - return b64tohex(base64.StdEncoding.EncodeToString(b)) -} - -// 打码狗平台登录 -func LoginDamagou(accountId string) string { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - url := "http://www.damagou.top/apiv1/login-bak.html?username=" + config.GloablConfig.Damagou.Username + "&password=" + config.GloablConfig.Damagou.Password - res, _ := CLoud189Session.Get(url, nil) - rsText := regexp.MustCompile(`([A-Za-z0-9]+)`).FindStringSubmatch(res.Text)[1] - return rsText -} - -// 调用打码狗获取验证码结果 -func GetValidateCode(accountId, params string) string { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - timeStamp := strconv.FormatInt(time.Now().UnixNano()/1e6, 10) - url := "https://open.e.189.cn/api/logbox/oauth2/picCaptcha.do?token=" + params + timeStamp - log.Warningln("[登录接口]正在尝试获取验证码") - res, err := CLoud189Session.Get(url, nic.H{ - Headers: nic.KV{ - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/76.0", - "Referer": "https://open.e.pan.cn/", - "Sec-Fetch-Dest": "image", - "Sec-Fetch-Mode": "no-cors", - "Sec-Fetch-Site": "same-origin", - }, - }) - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if err != nil { - panic(err.Error()) - } else { - f, err := os.OpenFile("validateCode.png", os.O_RDWR|os.O_CREATE, os.ModePerm) - if err != nil { - panic(err) - } - defer f.Close() - f.Write(res.Bytes) - damagouKey := LoginDamagou(accountId) - base64Str := base64.StdEncoding.EncodeToString(res.Bytes) - base64Str = "data:image/png;base64," + base64Str - url := "http://www.damagou.top/apiv1/recognize.html" - vres, _ := CLoud189Session.Post(url, nic.H{ - Data: nic.KV{ - "userkey": damagouKey, - "image": base64Str, - }, - }) - return vres.Text - } - return "" -} - -func Cloud189UploadFilesNew(accountId, parentId string, files []*multipart.FileHeader) bool { - CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - sessionKey := CLoud189Sessions[accountId].SessionKey - UPLOAD_PART_SIZE := 10 * 1024 * 1024 - date := time.Now().Unix() - rid := "8aab8fc8-99ae-458e-89dd-85e0d7b7d4f6" - pk := strings.ReplaceAll(rid, "-", "") - pubKey, pId := GetRsaKey(accountId) - fmt.Println(qs(nic.KV{ - "parentFolderId": parentId, - "fileName": files[0].Filename, - "fileSize": files[0].Size, - "sliceSize": UPLOAD_PART_SIZE, - "lazyCheck": 1, - })) - re, _ := nic.Post("https://www.devglan.com/online-tools/aes-encryption", nic.H{ - Data: nic.KV{ - "file": "undefined", - "data": nic.KV{ - "textToEncrypt": qs(nic.KV{ - "parentFolderId": parentId, - "fileName": files[0].Filename, - "fileSize": files[0].Size, - "sliceSize": UPLOAD_PART_SIZE, - "lazyCheck": 1, - }), - "secretKey": pk[0:16], - "mode": "ECB", - "keySize": "128", - "dataFormat": "Hex", - }, - }, - }) - params := jsoniter.Get(re.Bytes, "output").ToString() - signature := hmacSha1(fmt.Sprintf("SessionKey=%s&Operate=GET&RequestURI=%s&Date=%s¶ms=%s", sessionKey, "/person/initMultiUpload", date, params), pk) - encryptiontext := RsaEncode([]byte(pk), pubKey) - headers := nic.KV{ - "encryptiontext": encryptiontext, - "pkid": pId, - "signature": signature, - "sessionkey": sessionKey, - "x-request-id": rid, - "x-request-date": date, - "origin": "https://cloud.189.cn", - "referer": "https://cloud.189.cn/", - } - response, _ := CLoud189Session.Get("https://upload.cloud.189.cn"+"/person/initMultiUpload?params="+params, nic.H{ - Headers: headers, - }) - fmt.Println(response.Text) - return true -} -func hmacSha1(data string, secret string) string { - h := hmac.New(sha1.New, []byte(secret)) - h.Write([]byte(data)) - return hex.EncodeToString(h.Sum(nil)) -} -func Cloud189UploadFiles(accountId, parentId string, files []*multipart.FileHeader) bool { - //CLoud189Session := CLoud189Sessions[accountId].Cloud189Session - //response, _ := CLoud189Session.Get("https://cloud.189.cn/main.action#home", nil) - //sessionKey := GetCurBetweenStr(response.Text, "window.edrive.sessionKey = '", "';") - sessionKey := CLoud189Sessions[accountId].SessionKey - log.Debug(sessionKey) - for _, file := range files { - t1 := time.Now() - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - fileContent, _ := file.Open() - byteContent, _ := ioutil.ReadAll(fileContent) - reader := bytes.NewReader(byteContent) - b := &bytes.Buffer{} - writer := multipart.NewWriter(b) - writer.WriteField("parentId", parentId) - writer.WriteField("sessionKey", sessionKey) - writer.WriteField("opertype", "1") - writer.WriteField("fname", file.Filename) - part, _ := writer.CreateFormFile("Filedata", file.Filename) - io.Copy(part, reader) - writer.Close() - r, _ := http.NewRequest("POST", "https://hb02.upload.cloud.189.cn/v1/DCIWebUploadAction", b) - r.Header.Add("Content-Type", writer.FormDataContentType()) - res, _ := http.DefaultClient.Do(r) - defer res.Body.Close() - body, _ := ioutil.ReadAll(res.Body) - log.Debugf("上传接口返回:%s", string(body)) - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return true -} - -var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - -var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz" - -func int2char(a int) string { - return strings.Split(BI_RM, "")[a] -} - -func b64tohex(a string) string { - d := "" - e := 0 - c := 0 - for i := 0; i < len(a); i++ { - m := strings.Split(a, "")[i] - if m != "=" { - v := strings.Index(b64map, m) - if 0 == e { - e = 1 - d += int2char(v >> 2) - c = 3 & v - } else if 1 == e { - e = 2 - d += int2char(c<<2 | v>>4) - c = 15 & v - } else if 2 == e { - e = 3 - d += int2char(c) - d += int2char(v >> 2) - c = 3 & v - } else { - e = 0 - d += int2char(c<<2 | v>>4) - d += int2char(15 & v) - } - } - } - if e == 1 { - d += int2char(c << 2) - } - return d -} - -//获取随机数 -func random() string { - return fmt.Sprintf("0.%17v", math_rand.New(math_rand.NewSource(time.Now().UnixNano())).Int63n(100000000000000000)) -} - -func FormatFileSize(fileSize int64) (size string) { - if fileSize == 0 { - return "-" - } else if fileSize < 1024 { - //return strconv.FormatInt(fileSize, 10) + "B" - return fmt.Sprintf("%.2f B", float64(fileSize)/float64(1)) - } else if fileSize < (1024 * 1024) { - return fmt.Sprintf("%.2f KB", float64(fileSize)/float64(1024)) - } else if fileSize < (1024 * 1024 * 1024) { - return fmt.Sprintf("%.2f MB", float64(fileSize)/float64(1024*1024)) - } else if fileSize < (1024 * 1024 * 1024 * 1024) { - return fmt.Sprintf("%.2f GB", float64(fileSize)/float64(1024*1024*1024)) - } else if fileSize < (1024 * 1024 * 1024 * 1024 * 1024) { - return fmt.Sprintf("%.2f TB", float64(fileSize)/float64(1024*1024*1024*1024)) - } else { //if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024) - return fmt.Sprintf("%.2f EB", float64(fileSize)/float64(1024*1024*1024*1024*1024)) - } -} - -func GetBetweenStr(str, start, end string) string { - n := strings.Index(str, start) - if n == -1 { - n = 0 - } else { - n = n + len(start) - } - str = string([]byte(str)[n:]) - m := strings.Index(str, end) - if m == -1 { - m = len(str) - } - str = string([]byte(str)[:m]) - return str -} - -func qs(params nic.KV) string { - var dataParams string - //ksort - var keys []string - for k := range params { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - fmt.Println("key:", k, "Value:", Strval(params[k])) - dataParams = dataParams + k + "=" + Strval(params[k]) + "&" - } - ff := dataParams[0 : len(dataParams)-1] - return ff -} diff --git a/Util/FTP.go b/Util/FTP.go deleted file mode 100644 index 87ca6b65..00000000 --- a/Util/FTP.go +++ /dev/null @@ -1,186 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "PanIndex/model" - "github.com/jlaffaye/ftp" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "io/ioutil" - "mime/multipart" - "sort" - "strconv" - "strings" - "time" -) - -func FtpLogin(account entity.Account, isCheck bool) (*ftp.ServerConn, error) { - c, err := ftp.Connect(account.ApiUrl) - if err != nil { - log.Errorf("FTP服务器[%s]连接失败:%s", account.ApiUrl, err) - } else { - if account.User != "" && account.Password != "" { - err = c.Login(account.User, account.Password) - } else { - err = c.Login("anonymous", "anonymous") - } - if err != nil { - log.Errorf("FTP服务器[%s]登录失败,请检查用户名密码是否正确:%s", account.ApiUrl, err) - } else { - if isCheck { - err = c.Logout() - if err != nil { - log.Errorf("FTP服务器[%s]退出登录异常:%s", account.ApiUrl, err) - err = nil - } - err = c.Quit() - if err != nil { - log.Errorf("FTP服务器[%s]退出异常:%s", account.ApiUrl, err) - err = nil - } - } - } - } - return c, err -} - -func FtpGetFiles(account entity.Account, fileId, path string, hide, hasPwd int, syncChild bool) { - c, er := FtpLogin(account, false) - fileNodes := []entity.FileNode{} - if er != nil { - log.Errorf("FTP服务器[%s]连接或登录异常:%s", account.ApiUrl, er) - } else { - entries, err := c.List(fileId) - if er != nil { - log.Errorf("FTP服务器[%s]目录列表[%s]加载失败:%s", account.ApiUrl, path, er) - } else { - for _, entry := range entries { - fn := entity.FileNode{} - fn.AccountId = account.Id - fn.Id = uuid.NewV4().String() - fn.FileName = entry.Name - fileSize, _ := strconv.ParseInt(strconv.FormatUint(entry.Size, 10), 10, 64) - fn.FileSize = fileSize - fn.SizeFmt = FormatFileSize(fileSize) - if path == "/" { - fn.Path = path + fn.FileName - } else { - fn.Path = path + "/" + fn.FileName - } - if fileId == "/" { - fn.FileId = fileId + fn.FileName - } else { - fn.FileId = fileId + "/" + fn.FileName - } - fn.FileIdDigest = entry.Target - fn.FileType = GetFileType(fn.FileName) - fn.MediaType = GetMimeType(fn.FileName) - if entry.Type == ftp.EntryTypeFolder { - fn.IsFolder = true - } else { - fn.IsFolder = false - } - fn.IsStarred = true - fn.LastOpTime = time.Unix(entry.Time.Unix(), 0).Format("2006-01-02 15:04:05") - fn.CreateTime = fn.LastOpTime - fn.ParentPath = path - fn.ParentId = fileId - fn.Hide = 0 - fn.HasPwd = 0 - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - if fn.IsFolder == true { - if syncChild { - FtpGetFiles(account, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fn.CacheTime = time.Now().UnixNano() - fn.Delete = 1 - model.SqliteDb.Create(fn) - fileNodes = append(fileNodes, fn) - } - } - if err = c.Quit(); err != nil { - log.Fatal(err) - } - } -} - -func FtpReadFileToBytes(account entity.Account, fileId string) []byte { - c, er := FtpLogin(account, false) - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if er != nil { - log.Errorf("FTP服务器[%s]连接或登录异常:%s", account.ApiUrl, er) - } else { - r, err := c.Retr(fileId) - if err != nil { - panic(err) - } - defer r.Close() - buf, err := ioutil.ReadAll(r) - if err != nil { - panic(err) - } - return buf - } - return nil -} - -func FtpUpload(account entity.Account, fileId string, files []*multipart.FileHeader) bool { - c, er := FtpLogin(account, false) - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if er != nil { - log.Errorf("FTP服务器[%s]连接或登录异常:%s", account.ApiUrl, er) - } else { - for _, file := range files { - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - t1 := time.Now() - fileContent, _ := file.Open() - defer fileContent.Close() - filePath := "" - if fileId == "/" { - filePath = fileId + file.Filename - } else { - filePath = fileId + "/" + file.Filename - } - err := c.Stor(filePath, fileContent) - if err != nil { - panic(err) - } - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return true - } - return false -} diff --git a/Util/FileUtil.go b/Util/FileUtil.go deleted file mode 100755 index 2d6971f7..00000000 --- a/Util/FileUtil.go +++ /dev/null @@ -1,399 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "archive/zip" - "bytes" - "fmt" - "github.com/bluele/gcache" - log "github.com/sirupsen/logrus" - "golang.org/x/text/encoding/simplifiedchinese" - "golang.org/x/text/transform" - "io" - "io/ioutil" - "mime" - "net/http" - "os" - "path/filepath" - "sort" - "strings" - "time" - "unicode/utf8" -) - -var GC = gcache.New(10).LRU().Build() - -func FileExist(path string) bool { - _, err := os.Stat(path) //os.Stat获取文件信息 - if err != nil { - return os.IsExist(err) - } - return true -} - -func IsDirectory(filename string) bool { - info, err := os.Stat(filename) - if err != nil { - return false - } - return info.IsDir() -} - -func IsFile(filename string) bool { - info, err := os.Stat(filename) - if err != nil { - return false - } - return !info.IsDir() -} - -func IsHiddenFile(name string) bool { - if strings.TrimSpace(name) == "" { - return false - } - return strings.HasPrefix(name, ".") -} - -func GetMimeType(fileName string) int { - mime := strings.Split(mime.TypeByExtension(filepath.Ext(fileName)), "/")[0] - ext := filepath.Ext(fileName) - if mime == "image" { - return 1 - } else if mime == "audio" { - return 2 - } else if mime == "video" { - return 3 - } else if mime == "text" { - if strings.Contains(".pdf", ext) { - return 0 - } - return 4 - } else { - if strings.Contains(".yml,.properties,.conf.js,.txt,.py,.go,.css,.lua,.sh,.sql,.html,.json,.java,.jsp", ext) { - return 4 - } else if strings.Contains(".mp4,.m4v,.mkv,.webm,.mov,.avi,.wmv,.mpg,.flv,.3gp,.m3u8,.ts", ext) { - return 3 - } else if strings.Contains(".jpg,.png,.gif,.webp,.cr2,.tif,.bmp,.heif,.jxr,.psd,.ico,.dwg", ext) { - return 1 - } else if strings.Contains(".mid,.mp3,.m4a,.ogg,.flac,.wav,.amr,.aac", ext) { - return 2 - } - return 0 - } -} - -func GetPrePath(path string) []map[string]string { - //path := "/a/b/c/d" - prePaths := []map[string]string{} - //result := make(map[string]interface{}) - paths := strings.Split(path, "/") - for i, n := range paths { - item := make(map[string]string) - var buffer bytes.Buffer - for j := 0; j <= i; j++ { - if paths[j] == "" { - buffer.WriteString(paths[j]) - } else { - buffer.WriteString("/") - buffer.WriteString(paths[j]) - } - } - if buffer.String() != "" { - item["PathName"] = n - item["PathUrl"] = buffer.String() - prePaths = append(prePaths, item) - } - } - return prePaths -} -func ReadStringByFile(filePth string) string { - f, err := os.Open(filePth) - if err != nil { - log.Errorln(err) - return "" - } - b, err := ioutil.ReadAll(f) - if err != nil { - log.Errorln(err) - return "" - } - return fmt.Sprintf("%s", b) -} -func ReadStringByUrl(account entity.Account, url, fileId string) string { - content := "" - //为了提高效率,从缓存查询 - value, _ := GC.Get(fileId) - if value != nil { - log.Debugf("从缓存中读取文本内容{%s}", fileId) - return value.(string) - } - data := []byte("") - if account.Mode == "webdav" { - data = WebDavReadFileToBytes(account, fileId) - } else if account.Mode == "ftp" { - data = FtpReadFileToBytes(account, fileId) - } else { - resp, err := http.Get(url) - if err != nil { - log.Errorln(err) - return content - } - defer resp.Body.Close() - data, err = ioutil.ReadAll(resp.Body) - if err != nil { - log.Errorln(err) - return content - } - } - content = fmt.Sprintf("%s", data) - GC.Set(fileId, content) - return content -} -func FileSearch(rootPath, path, key string) []entity.FileNode { - if path == "" { - path = "/" - } - list := []entity.FileNode{} - //列出文件夹相对路径 - fullPath := filepath.Join(rootPath, path) - if FileExist(fullPath) { - //是目录 - // 读取该文件夹下所有文件 - fileInfos, err := ioutil.ReadDir(fullPath) - if err != nil { - panic(err.Error()) - } else { - for _, fileInfo := range fileInfos { - fileId := filepath.Join(fullPath, fileInfo.Name()) - // 按照文件名过滤 - if !fileInfo.IsDir() && !strings.Contains(fileInfo.Name(), key) { - continue - } - // 当前文件是隐藏文件(以.开头)则不显示 - if IsHiddenFile(fileInfo.Name()) { - continue - } - //指定隐藏的文件或目录过滤 - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fileId) - if i < len(listSTring) && listSTring[i] == fileId { - continue - } - } - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - hide := false - for _, v := range listSTring { - f1 := strings.Split(v, ":")[0] - if f1 == fileId { - hide = true - break - } - } - if hide { - continue - } - } - fileType := GetMimeType(fileInfo.Name()) - // 实例化FileNode - file := entity.FileNode{ - FileId: fileId, - IsFolder: fileInfo.IsDir(), - FileName: fileInfo.Name(), - FileSize: int64(fileInfo.Size()), - SizeFmt: FormatFileSize(int64(fileInfo.Size())), - FileType: strings.TrimLeft(filepath.Ext(fileInfo.Name()), "."), - Path: PathJoin(path, fileInfo.Name()), - MediaType: fileType, - LastOpTime: time.Unix(fileInfo.ModTime().Unix(), 0).Format("2006-01-02 15:04:05"), - } - if fileInfo.IsDir() { - childList := FileSearch(rootPath, file.Path, key) - if len(childList) == 0 && !strings.Contains(fileInfo.Name(), key) { - continue - } - for _, fn := range childList { - list = append(list, fn) - } - - } - // 添加到切片中等待json序列化 - if fileInfo.IsDir() && !strings.Contains(fileInfo.Name(), key) { - continue - } - list = append(list, file) - - } - } - } - return list -} -func FileQuery(rootPath, path string, mt int) []entity.FileNode { - if path == "" { - path = "/" - } - list := []entity.FileNode{} - //列出文件夹相对路径 - fullPath := filepath.Join(rootPath, path) - if FileExist(fullPath) { - //是目录 - // 读取该文件夹下所有文件 - fileInfos, err := ioutil.ReadDir(fullPath) - if err != nil { - panic(err.Error()) - } else { - for _, fileInfo := range fileInfos { - fileId := filepath.Join(fullPath, fileInfo.Name()) - // 当前文件是隐藏文件(以.开头)则不显示 - if IsHiddenFile(fileInfo.Name()) { - continue - } - //指定隐藏的文件或目录过滤 - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fileId) - if i < len(listSTring) && listSTring[i] == fileId { - continue - } - } - fileType := GetMimeType(fileInfo.Name()) - // 实例化FileNode - file := entity.FileNode{ - FileId: fileId, - IsFolder: fileInfo.IsDir(), - FileName: fileInfo.Name(), - FileSize: int64(fileInfo.Size()), - SizeFmt: FormatFileSize(int64(fileInfo.Size())), - FileType: strings.TrimLeft(filepath.Ext(fileInfo.Name()), "."), - Path: PathJoin(path, fileInfo.Name()), - MediaType: fileType, - LastOpTime: time.Unix(fileInfo.ModTime().Unix(), 0).Format("2006-01-02 15:04:05"), - } - if !fileInfo.IsDir() { - if mt != -1 && file.MediaType == mt { - list = append(list, file) - } else if mt == -1 { - list = append(list, file) - } else { - continue - } - } - - } - } - } - return list -} -func Zip(dst, src string) (err error) { - // 创建准备写入的文件 - fw, err := os.Create(dst) - defer fw.Close() - if err != nil { - return err - } - - // 通过 fw 来创建 zip.Write - zw := zip.NewWriter(fw) - defer func() { - // 检测一下是否成功关闭 - if err := zw.Close(); err != nil { - log.Fatalln(err) - } - }() - - // 下面来将文件写入 zw ,因为有可能会有很多个目录及文件,所以递归处理 - return filepath.Walk(src, func(path string, fi os.FileInfo, errBack error) (err error) { - if errBack != nil { - return errBack - } - - // 通过文件信息,创建 zip 的文件信息 - fh, err := zip.FileInfoHeader(fi) - if err != nil { - return - } - - // 替换文件信息中的文件名 - fh.Name = strings.TrimPrefix(path, filepath.Dir(src)+string(filepath.Separator)) - // 这步开始没有加,会发现解压的时候说它不是个目录 - if fi.IsDir() { - fh.Name += "/" - } - // 写入文件信息,并返回一个 Write 结构 - w, err := zw.CreateHeader(fh) - if err != nil { - return - } - - // 检测,如果不是标准文件就只写入头信息,不写入文件数据到 w - // 如目录,也没有数据需要写 - if !fh.Mode().IsRegular() { - return nil - } - - // 打开要压缩的文件 - fr, err := os.Open(path) - defer fr.Close() - if err != nil { - return - } - - // 将打开的文件 Copy 到 w - n, err := io.Copy(w, fr) - if err != nil { - return - } - // 输出压缩的内容 - log.Debugf("成功压缩文件: %s, 共写入了 %d 个字符的数据\n", path, n) - return nil - }) -} -func PathJoin(path, fileName string) string { - if path == "/" { - return fmt.Sprintf("%s%s", path, fileName) - } else { - return fmt.Sprintf("%s/%s", path, fileName) - } -} -func TransformText(f *os.File) ([]byte, string) { - content, _ := ioutil.ReadAll(f) - contentType := http.DetectContentType(content) - if !utf8.Valid(content) { - rr := bytes.NewReader(content) - r := transform.NewReader(rr, simplifiedchinese.GBK.NewDecoder()) - b, _ := ioutil.ReadAll(r) - return b, contentType - } - return content, contentType -} -func TransformTextFromBytes(content []byte) ([]byte, string) { - contentType := http.DetectContentType(content) - if !utf8.Valid(content) { - rr := bytes.NewReader(content) - r := transform.NewReader(rr, simplifiedchinese.GBK.NewDecoder()) - b, _ := ioutil.ReadAll(r) - return b, contentType - } - return content, contentType -} -func TransformByte(reader io.ReadCloser) ([]byte, string) { - content := StreamToByte(reader) - contentType := http.DetectContentType(content) - if !utf8.Valid(content) { - rr := bytes.NewReader(content) - r := transform.NewReader(rr, simplifiedchinese.GBK.NewDecoder()) - b, _ := ioutil.ReadAll(r) - return b, contentType - } - return content, contentType -} - -func StreamToByte(stream io.Reader) []byte { - buf := new(bytes.Buffer) - buf.ReadFrom(stream) - return buf.Bytes() -} diff --git a/Util/GoogleDrive.go b/Util/GoogleDrive.go deleted file mode 100644 index fa65db6c..00000000 --- a/Util/GoogleDrive.go +++ /dev/null @@ -1,224 +0,0 @@ -package Util - -import ( - "PanIndex/entity" - "PanIndex/model" - "bytes" - "encoding/json" - "fmt" - jsoniter "github.com/json-iterator/go" - "github.com/libsgh/nic" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "strconv" - "strings" - "time" -) - -var GoogleDrives = map[string]entity.GoogleDriveAuthInfo{} - -const ( - Proxy = "socks5://127.0.0.1:1089" - PartSize = 1 * 1024 * 1024 -) - -func GDfreshToken(account entity.Account) string { - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - resp, _ := nic.Post("https://oauth2.googleapis.com/token", nic.H{ - Proxy: Proxy, - Headers: nic.KV{ - "content-type": "application/x-www-form-urlencoded", - }, - Data: nic.KV{ - "client_id": account.User, - "client_secret": account.Password, - "refresh_token": account.RefreshToken, - "redirect_uri": account.RedirectUri, - "grant_type": "refresh_token", - }, - }) - var auth entity.GoogleDriveAuthInfo - err := jsoniter.Unmarshal(resp.Bytes, &auth) - if err != nil { - panic(err.Error()) - return "" - } - GoogleDrives[account.Id] = auth - return account.RefreshToken -} - -//api: https://developers.google.com/drive/api/v3/reference/files/list -func GDGetFiles(accountId, fileId, p string, hide, hasPwd int, syncChild bool) { - gd := GoogleDrives[accountId] - auth := gd.TokenType + " " + gd.AccessToken - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - pageToken := "" - for { - fns := []entity.FileNode{} - url := fmt.Sprintf("https://www.googleapis.com/drive/v3/files?pageSize=%d&supportsAllDrives=true&includeItemsFromAllDrives=true&fields=%s&q=trashed = false and '%s' in parents&orderBy=%s&pageToken=%s", - 2, "nextPageToken, files(id,name,mimeType,parents,size,fileExtension,thumbnailLink,modifiedTime,createdTime,md5Checksum)", fileId, "folder,modifiedTime asc,name", pageToken) - resp, _ := nic.Get(url, nic.H{ - Proxy: Proxy, - Headers: nic.KV{ - "Authorization": auth, - }, - }) - pageToken = jsoniter.Get(resp.Bytes, "nextPageToken").ToString() - files := jsoniter.Get(resp.Bytes, "files").ToString() - var fs []map[string]interface{} - json.Unmarshal([]byte(files), &fs) - for _, item := range fs { - fn := entity.FileNode{ - Id: uuid.NewV4().String(), - AccountId: accountId, - Delete: 1, - CacheTime: time.Now().UnixNano(), - FileIdDigest: "", - IsFolder: true, - FileId: item["id"].(string), - FileName: item["name"].(string), - FileSize: 0, - SizeFmt: "-", - FileType: "", - MediaType: 0, - DownloadUrl: "", - CreateTime: UTCTimeFormat(item["createdTime"].(string)), - LastOpTime: UTCTimeFormat(item["modifiedTime"].(string)), - ParentId: fileId, - ParentPath: p, - } - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - FileNodeAuth(&fn, hide, hasPwd) - if item["mimeType"].(string) == "application/vnd.google-apps.folder" { - fn.IsFolder = true - } else { - size, _ := strconv.ParseInt(item["size"].(string), 10, 64) - fn.IsFolder = false - fn.FileType = item["fileExtension"].(string) - fn.FileSize = size - fn.SizeFmt = FormatFileSize(size) - fn.MediaType = GetMimeType(fn.FileName) - } - if fn.IsFolder == true { - //同步子目录&&子目录不为空 - if syncChild { - GDGetFiles(accountId, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fns = append(fns, fn) - } - model.SqliteDb.Create(&fns) - if pageToken == "" { - break - } - } -} -func GDGetDownUrl(accountId, fileId string) string { - gd := GoogleDrives[accountId] - auth := gd.TokenType + " " + gd.AccessToken - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - resp, _ := nic.Get("https://www.googleapis.com/drive/v3/files/"+fileId+"?fields=*", nic.H{ - Proxy: Proxy, - Headers: nic.KV{ - "Authorization": auth, - }, - }) - if resp != nil { - downUrl := jsoniter.Get(resp.Bytes, "webContentLink").ToString() - return downUrl - } - return "" -} -func GDUpload(accountId, parentId string, files []*multipart.FileHeader) bool { - gd := GoogleDrives[accountId] - auth := gd.TokenType + " " + gd.AccessToken - fmt.Println(auth) - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - for _, file := range files { - resp, _ := nic.Post("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable", nic.H{ - Proxy: Proxy, - Headers: nic.KV{ - "Authorization": auth, - "Content-Type": "application/json; charset=UTF-8", - }, - JSON: nic.KV{ - "name": file.Filename, - "parents": []string{parentId}, - }, - }) - uploadUrl := resp.Header.Get("location") - if uploadUrl == "" { - log.Debugf("文件上传失败:%s,上传地址为空", file.Filename) - return false - } - bfs := ReadBlock(file) - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - for _, bf := range bfs { - r, _ := http.NewRequest("PUT", uploadUrl, bytes.NewReader(bf.Content)) - r.Header.Add("Content-Length", strconv.FormatInt(file.Size, 10)) - r.Header.Add("Content-Range", bf.Name) - res, _ := http.DefaultClient.Do(r) - defer res.Body.Close() - body, _ := ioutil.ReadAll(res.Body) - log.Debugf("上传接口返回:%s", body) - } - } - return true -} -func GetGDContentReader(accountId, fileId, r string) (io.Reader, string) { - gd := GoogleDrives[accountId] - auth := gd.TokenType + " " + gd.AccessToken - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - rr := "" - cr := "" - if r != "" { - startStr := strings.ReplaceAll(strings.ReplaceAll(r, "bytes=", ""), "-", "") - start, _ := strconv.ParseInt(startStr, 10, 64) - if start+PartSize > 11269310 { - rr = fmt.Sprintf("bytes=%d-%d", start, 11269310-1) - cr = fmt.Sprintf("bytes %d-%d/%d", start, 11269310-1, 11269310) - } else { - rr = fmt.Sprintf("bytes=%d-%d", start, start+PartSize-1) - cr = fmt.Sprintf("bytes %d-%d/%d", start, start+PartSize-1, 11269310) - } - } - resp, _ := nic.Get("https://www.googleapis.com/drive/v3/files/"+fileId+"?alt=media", nic.H{ - Proxy: Proxy, - Headers: nic.KV{ - "Authorization": auth, - "Range": rr, - }, - }) - if resp != nil { - return bytes.NewReader(resp.Bytes), cr - } - return nil, "" -} diff --git a/Util/OneDrive.go b/Util/OneDrive.go deleted file mode 100644 index 0d879579..00000000 --- a/Util/OneDrive.go +++ /dev/null @@ -1,341 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "PanIndex/model" - "bytes" - "encoding/json" - "fmt" - jsoniter "github.com/json-iterator/go" - "github.com/libsgh/nic" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "io/ioutil" - "math" - "mime/multipart" - "net/http" - "path/filepath" - "sort" - "strconv" - "strings" - "time" -) - -var OneDrives = map[string]entity.OneDriveAuthInfo{} -var zones = map[string]entity.Zone{ - "onedrive": entity.Zone{ - Login: "https://login.microsoftonline.com", - Api: "https://graph.microsoft.com", - Desc: "国际版", - }, - "onedrive-cn": entity.Zone{ - Login: "https://login.chinacloudapi.cn", - Api: "https://microsoftgraph.chinacloudapi.cn", - Desc: "世纪互联", - }, -} - -func OneDriveRefreshToken(account entity.Account) string { - - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - - resp, _ := nic.Post(zones[account.Mode].Login+"/common/oauth2/v2.0/token", nic.H{ - Headers: nic.KV{ - "Content-Type": "application/x-www-form-urlencoded", - }, - Data: nic.KV{ - "client_id": account.User, - "redirect_uri": account.RedirectUri, - "client_secret": account.Password, - "refresh_token": account.RefreshToken, - "grant_type": "refresh_token", - }, - }) - var auth entity.OneDriveAuthInfo - err := jsoniter.Unmarshal(resp.Bytes, &auth) - if err != nil { - panic(err.Error()) - return "" - } - auth.Mode = account.Mode - OneDrives[account.Id] = auth - return auth.RefreshToken -} -func BuildODRequestUrl(mode, path, query string) string { - if path != "" && path != "/" { - path = fmt.Sprintf(":%s:/", path) - } - return zones[mode].Api + "/v1.0" + "/me/drive/root" + path + query -} -func OndriveGetFiles(url, accountId, fileId, p string, hide, hasPwd int, syncChild bool) { - od := OneDrives[accountId] - auth := od.TokenType + " " + od.AccessToken - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if url == "" { - url = BuildODRequestUrl(od.Mode, fileId, "children?select=id,name,size,folder,@microsoft.graph.downloadUrl,lastModifiedDateTime,file") - } - //limit := 100 - //nextMarker := "" - resp, err := nic.Get(url, nic.H{ - Headers: nic.KV{ - "Authorization": auth, - "Host": "graph.microsoft.com", - }, - }) - if err != nil { - panic(err.Error()) - } - byteFiles := []byte(resp.Text) - d := jsoniter.Get(byteFiles, "value") - //nextMarker = jsoniter.Get(byteFiles, "next_marker").ToString() - var m []map[string]interface{} - json.Unmarshal([]byte(d.ToString()), &m) - for _, item := range m { - fn := entity.FileNode{} - fn.AccountId = accountId - if fileId == "/" { - fn.FileId = fileId + item["name"].(string) - } else { - fn.FileId = fileId + "/" + item["name"].(string) - } - fn.FileName = item["name"].(string) - fn.FileIdDigest = "" - fn.CreateTime = "" - fn.LastOpTime = UTCTimeFormat(item["lastModifiedDateTime"].(string)) - fn.Delete = 1 - if item["folder"] == nil { - fn.FileType = GetFileType(fn.FileName) - fn.IsFolder = false - fn.FileSize = int64(item["size"].(float64)) - fn.SizeFmt = FormatFileSize(fn.FileSize) - category := GetCategory(item["file"].(map[string]interface{})["mimeType"].(string)) - if category == "image" { - //图片 - fn.MediaType = 1 - } else if category == "doc" { - //文本 - fn.MediaType = 4 - } else if category == "video" { - //视频 - fn.MediaType = 3 - } else if category == "audio" { - //音频 - fn.MediaType = 2 - } else { - //其他类型 - fn.MediaType = 0 - } - fn.DownloadUrl = item["@microsoft.graph.downloadUrl"].(string) - } else { - fn.FileType = "" - fn.IsFolder = true - fn.FileSize = 0 - fn.SizeFmt = "-" - fn.MediaType = 0 - fn.DownloadUrl = "" - } - fn.IsStarred = false - fn.ParentId = fileId - fn.Hide = 0 - fn.HasPwd = 0 - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - fn.ParentPath = p - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - if fn.IsFolder == true { - if syncChild { - OndriveGetFiles("", accountId, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fn.Id = uuid.NewV4().String() - fn.CacheTime = time.Now().UnixNano() - model.SqliteDb.Create(fn) - } - nextLink := jsoniter.Get(byteFiles, "@odata.nextLink").ToString() - if nextLink != "" { - OndriveGetFiles(nextLink, accountId, fileId, p, hide, hasPwd, syncChild) - } -} -func GetFileType(name string) string { - arr := strings.Split(name, ".") - if len(arr) > 1 { - return arr[len(arr)-1] - } else { - return "" - } -} -func GetCategory(mimeType string) string { - arr := strings.Split(mimeType, "/") - return arr[0] -} -func GetOneDriveDownloadUrl(accountId, fileId string) string { - od := OneDrives[accountId] - auth := od.TokenType + " " + od.AccessToken - resp, _ := nic.Get(zones[od.Mode].Api+"/v1.0/me/drive/root:"+fileId, nic.H{ - Headers: nic.KV{ - "Authorization": auth, - "Host": "graph.microsoft.com", - }, - }) - return jsoniter.Get(resp.Bytes, "@microsoft.graph.downloadUrl").ToString() -} - -func OneDriveUpload(accountId, parentId string, files []*multipart.FileHeader) bool { - for _, file := range files { - t1 := time.Now() - //bfs := ReadBlock(file, 16384000)327680 - bfs := ReadBlock(file) - uploadUrl := CreateUploadSession(accountId, filepath.Join(parentId, file.Filename)) - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - for _, bf := range bfs { - r, _ := http.NewRequest("PUT", uploadUrl, bytes.NewReader(bf.Content)) - r.Header.Add("Content-Length", strconv.FormatInt(file.Size, 10)) - r.Header.Add("Content-Range", bf.Name) - res, _ := http.DefaultClient.Do(r) - defer res.Body.Close() - body, _ := ioutil.ReadAll(res.Body) - log.Debugf("上传接口返回:%s", body) - } - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return false -} - -func ReadBlock(file *multipart.FileHeader) []BlockFile { - bfs := []BlockFile{} - FileHandle, err := file.Open() - if err != nil { - log.Error(err) - return bfs - } - defer FileHandle.Close() - const fileChunk = 16384000 //15.625MB - totalPartsNum := uint64(math.Ceil(float64(file.Size) / float64(fileChunk))) - log.Debugf("Spliting to %d pieces.\n", totalPartsNum) - totalSize := file.Size - off := int64(0) //起始点 - for i := uint64(0); i < totalPartsNum; i++ { - partSize := int64(math.Min(fileChunk, float64(file.Size-int64(i*fileChunk)))) - contentRange := fmt.Sprintf("bytes %d-%d/%d", off, off+partSize-1, totalSize) - contentRange2 := fmt.Sprintf("bytes=%d-%d", off, off+partSize-1) - partBuffer := make([]byte, partSize) - FileHandle.Read(partBuffer) - bfs = append(bfs, BlockFile{partBuffer, contentRange, contentRange2}) - off += partSize - } - return bfs -} - -type BlockFile struct { - Content []byte - Name string - Range2 string -} -type SplitFile struct { - File *multipart.FileHeader - FileName string - Length int64 - Size int64 - BlockSize int64 - blockpath []string -} - -func CreateUploadSession(accountId, filePath string) string { - od := OneDrives[accountId] - auth := od.TokenType + " " + od.AccessToken - resp, err := nic.Post(zones[od.Mode].Api+"/v1.0/me/drive/root:"+filePath+":/createUploadSession", nic.H{ - Headers: nic.KV{ - "Authorization": auth, - "Host": "graph.microsoft.com", - }, - }) - if err != nil { - log.Error(err) - return "" - } - if resp.StatusCode == 409 { - log.Debugf("被请求的资源的当前状态之间存在冲突,请求无法完成,重新提交上传请求") - return "" - } - log.Debugf("[OneDrive]获取上传url:%s", resp.Text) - return jsoniter.Get(resp.Bytes, "uploadUrl").ToString() -} -func OneExchangeToken(zone, clientId, redirectUri, clientSecret, code string) string { - if zone == "" { - zone = "onedrive" - } - resp, err := nic.Post(zones[zone].Login+"/common/oauth2/v2.0/token", nic.H{ - Headers: nic.KV{ - "Content-Type": "application/x-www-form-urlencoded", - }, - Data: nic.KV{ - "client_id": clientId, - "redirect_uri": redirectUri, - "client_secret": clientSecret, - "code": code, - "grant_type": "authorization_code", - }, - }) - if err != nil { - log.Error(err) - return "" - } - return resp.Text -} -func OneGetRefreshToken(zone, clientId, redirectUri, clientSecret, refreshToken string) string { - if zone == "" { - zone = "onedrive" - } - resp, err := nic.Post(zones[zone].Login+"/common/oauth2/v2.0/token", nic.H{ - Headers: nic.KV{ - "Content-Type": "application/x-www-form-urlencoded", - }, - Data: nic.KV{ - "client_id": clientId, - "redirect_uri": redirectUri, - "client_secret": clientSecret, - "refresh_token": refreshToken, - "grant_type": "refresh_token", - }, - }) - if err != nil { - log.Error(err) - return "" - } - return resp.Text -} diff --git a/Util/Teambition.go b/Util/Teambition.go deleted file mode 100755 index 9554e946..00000000 --- a/Util/Teambition.go +++ /dev/null @@ -1,627 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "PanIndex/model" - "bytes" - "encoding/json" - "fmt" - jsoniter "github.com/json-iterator/go" - "github.com/libsgh/nic" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "io/ioutil" - "mime/multipart" - "net/http" - "sort" - "strings" - "time" -) - -//var GloablOrgId string -//var GloablDriveId string -//var GloablSpaceId string -//var GloablRootId string -//var GloablProjectId string -//var IsPorject bool = false -//var TeambitionSession nic.Session -var TeambitionSessions = map[string]entity.Teambition{} - -//Teambition网盘登录 -func TeambitionLogin(accountId, user, password string) string { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - //0.登录-获取token - resp, err := TeambitionSession.Get("https://account.teambition.com/login/password", nil) - if err != nil { - panic(err.Error()) - } - token := GetBetweenStr(resp.Text, "TOKEN\":\"", "\"") - clientId := GetBetweenStr(resp.Text, "CLIENT_ID\":\"", "\"") - param := nic.KV{ - "client_id": clientId, - "token": token, - "password": password, - "response_type": "session", - } - //1.登录-用户名密码登录,获取cookie - if strings.Contains(user, "@") { - //邮箱登录 - param["email"] = user - resp, err = TeambitionSession.Post("https://account.teambition.com/api/login/email", nic.H{ - JSON: param, - AllowRedirect: false, - }) - if err != nil { - panic(err.Error()) - } - } else { - //手机号登录 - param["phone"] = user - resp, err = TeambitionSession.Post("https://account.teambition.com/api/login/phone", nic.H{ - JSON: param, - }) - if err != nil { - panic(err.Error()) - } - } - u := jsoniter.Get(resp.Bytes, "user") - if u == nil || u.Get("_id").ToString() == "" { - //登录失败 - Teambition.TeambitionSession = TeambitionSession - TeambitionSessions[accountId] = Teambition - return "4" - } - //2. 获orgId, memberId - resp, err = TeambitionSession.Get("https://www.teambition.com/api/organizations/personal", nil) - if err != nil { - panic(err.Error()) - } - Teambition.GloablOrgId = jsoniter.Get(resp.Bytes, "_id").ToString() - memberId := jsoniter.Get(resp.Bytes, "_creatorId").ToString() - //3.获取rootId、spaceId - resp, err = TeambitionSession.Get(fmt.Sprintf("https://pan.teambition.com/pan/api/spaces?orgId=%s&memberId=%s", Teambition.GloablOrgId, memberId), nil) - if err != nil { - panic(err.Error()) - } - Teambition.GloablRootId = jsoniter.Get(resp.Bytes, 0, "rootId").ToString() - Teambition.GloablSpaceId = jsoniter.Get(resp.Bytes, 0, "spaceId").ToString() - //4.获取driverId - resp, err = TeambitionSession.Get(fmt.Sprintf("https://pan.teambition.com/pan/api/orgs/%s?orgId=%s", Teambition.GloablOrgId, Teambition.GloablOrgId), nil) - if err != nil { - panic(err.Error()) - } - Teambition.GloablDriveId = jsoniter.Get(resp.Bytes, "data").Get("driveId").ToString() - Teambition.TeambitionSession = TeambitionSession - TeambitionSessions[accountId] = Teambition - return "success" -} - -//Teambition网盘登录 -func TeambitionUSLogin(accountId, user, password string) string { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - //0.登录-获取token - resp, err := TeambitionSession.Get("https://us-account.teambition.com/login/password", nil) - if err != nil { - panic(err.Error()) - } - token := GetBetweenStr(resp.Text, "TOKEN\":\"", "\"") - clientId := GetBetweenStr(resp.Text, "CLIENT_ID\":\"", "\"") - param := nic.KV{ - "client_id": clientId, - "token": token, - "password": password, - "response_type": "session", - } - //1.登录-用户名密码登录,获取cookie - if strings.Contains(user, "@") { - //邮箱登录 - param["email"] = user - resp, err = TeambitionSession.Post("https://us-account.teambition.com/api/login/email", nic.H{ - JSON: param, - AllowRedirect: false, - }) - if err != nil { - panic(err.Error()) - } - } else { - //手机号登录 - param["phone"] = user - resp, err = TeambitionSession.Post("https://us-account.teambition.com/api/login/phone", nic.H{ - JSON: param, - }) - if err != nil { - panic(err.Error()) - } - } - u := jsoniter.Get(resp.Bytes, "user") - if u != nil && u.Get("_id").ToString() != "" { - //登录成功 - Teambition.TeambitionSession = TeambitionSession - TeambitionSessions[accountId] = Teambition - return "success" - } - return "" -} - -func ProjectIdCheck(server, accountId, rootId string) string { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - resp, err := TeambitionSession.Get(fmt.Sprintf("https://%s.teambition.com/api/projects/%s", server, rootId), nil) - if err != nil { - panic(err.Error()) - } - if resp.StatusCode == 404 { - //项目id查询失败,可能是个人文件 - Teambition.IsPorject = false - return "" - } - Teambition.IsPorject = true - Teambition.GloablRootId = jsoniter.Get(resp.Bytes, "_rootCollectionId").ToString() - Teambition.GloablProjectId = rootId - Teambition.TeambitionSession = TeambitionSession - TeambitionSessions[accountId] = Teambition - return Teambition.GloablRootId -} - -//获取个人文件列表 -func TeambitionGetFiles(accountId, rootId, fileId, p string, hide, hasPwd int, syncChild bool) { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - if rootId == "" { - //如果没有设置rootId,这里使用全局的rootId - rootId = Teambition.GloablRootId - fileId = Teambition.GloablRootId - } - defer func() { - if p := recover(); p != nil { - log.Warningln(p) - } - }() - limit := 100 - nextMarker := "" - for { - url := fmt.Sprintf("https://pan.teambition.com/pan/api/nodes?orgId=%s&from=%s&limit=%d&orderBy=updated_at&orderDirection=DESC&driveId=%s&parentId=%s", Teambition.GloablOrgId, nextMarker, limit, Teambition.GloablDriveId, fileId) - resp, err := TeambitionSession.Get(url, nil) - if err != nil { - panic(err.Error()) - } - byteFiles := []byte(resp.Text) - d := jsoniter.Get(byteFiles, "data") - nextMarker = jsoniter.Get(byteFiles, "nextMarker").ToString() - var m []map[string]interface{} - json.Unmarshal([]byte(d.ToString()), &m) - for _, item := range m { - fn := entity.FileNode{} - fn.AccountId = accountId - fn.FileId = item["nodeId"].(string) - fn.FileName = item["name"].(string) - fn.FileIdDigest = "" - fn.CreateTime = UTCTimeFormat(item["created"].(string)) - fn.LastOpTime = UTCTimeFormat(item["updated"].(string)) - fn.Delete = 1 - kind := item["kind"].(string) - if kind == "file" { - if item["ext"] == nil { - fn.FileType = "" - } else { - fn.FileType = item["ext"].(string) - } - fn.IsFolder = false - fn.FileSize = int64(item["size"].(float64)) - fn.SizeFmt = FormatFileSize(fn.FileSize) - category := item["category"].(string) - if category == "image" { - //图片 - fn.MediaType = 1 - } else if category == "doc" { - //文本 - fn.MediaType = 4 - } else if category == "video" { - //视频 - fn.MediaType = 3 - } else if category == "audio" { - //音频 - fn.MediaType = 2 - } else { - //其他类型 - fn.MediaType = 0 - } - fn.DownloadUrl = item["downloadUrl"].(string) - } else { - fn.FileType = "" - fn.IsFolder = true - fn.FileSize = 0 - fn.SizeFmt = "-" - fn.MediaType = 0 - fn.DownloadUrl = "" - } - //天翼云网盘独有,这里随便定义一个 - fn.IsStarred = true - fn.ParentId = item["parentId"].(string) - fn.Hide = 0 - fn.HasPwd = 0 - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - fn.ParentPath = p - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - if fn.IsFolder == true { - if syncChild { - TeambitionGetFiles(accountId, rootId, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fn.Id = uuid.NewV4().String() - fn.CacheTime = time.Now().UnixNano() - model.SqliteDb.Create(fn) - } - if nextMarker == "" { - break - } - } -} - -func TeambitionGetProjectFiles(server, accountId, rootId, p string, hide, hasPwd int, syncChild bool) { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - defer func() { - if p := recover(); p != nil { - log.Warningln(p) - } - }() - limit := 100 - pageNum := 1 - for { - var m []map[string]interface{} - var n []map[string]interface{} - //先查询目录 - url := fmt.Sprintf("https://%s.teambition.com/api/collections?_parentId=%s&_projectId=%s&order=updatedDesc&count=%d&page=%d", server, rootId, Teambition.GloablProjectId, limit, pageNum) - resp, err := TeambitionSession.Get(url, nil) - if err != nil { - panic(err.Error()) - } - json.Unmarshal(resp.Bytes, &m) - url = fmt.Sprintf("https://%s.teambition.com/api/works?_parentId=%s&_projectId=%s&order=updatedDesc&count=%d&page=%d", server, rootId, Teambition.GloablProjectId, limit, pageNum) - resp, err = TeambitionSession.Get(url, nil) - if err != nil { - panic(err.Error()) - } - json.Unmarshal(resp.Bytes, &n) - m = append(m, n...) - //再查询文件 - if len(m) == 0 { - break - } - for _, item := range m { - fn := entity.FileNode{} - fn.AccountId = accountId - fn.FileId = item["_id"].(string) - fn.FileIdDigest = "" - fn.CreateTime = UTCTimeFormat(item["created"].(string)) - fn.LastOpTime = UTCTimeFormat(item["updated"].(string)) - fn.Delete = 1 - if item["title"] == nil { - fn.FileName = item["fileName"].(string) - fn.FileType = item["fileType"].(string) - fn.IsFolder = false - fn.FileSize = int64(item["fileSize"].(float64)) - fn.SizeFmt = FormatFileSize(fn.FileSize) - category := item["fileCategory"].(string) - if category == "image" { - //图片 - fn.MediaType = 1 - } else if category == "doc" { - //文本 - fn.MediaType = 4 - } else if category == "video" { - //视频 - fn.MediaType = 3 - } else if category == "audio" { - //音频 - fn.MediaType = 2 - } else { - //其他类型 - fn.MediaType = 0 - } - fn.DownloadUrl = item["downloadUrl"].(string) - } else { - fn.FileName = item["title"].(string) - fn.FileType = "" - fn.IsFolder = true - fn.FileSize = 0 - fn.SizeFmt = "-" - fn.MediaType = 0 - fn.DownloadUrl = "" - } - //天翼云网盘独有,这里随便定义一个 - fn.IsStarred = true - fn.ParentId = item["_parentId"].(string) - fn.Hide = 0 - fn.HasPwd = 0 - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - fn.ParentPath = p - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - if syncChild { - TeambitionGetProjectFiles(server, accountId, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - if fn.FileName != "" { - fn.Id = uuid.NewV4().String() - fn.CacheTime = time.Now().UnixNano() - model.SqliteDb.Create(fn) - } - } - pageNum++ - } -} - -func GetTeambitionDownUrl(accountId, nodeId string) string { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - url := fmt.Sprintf("https://pan.teambition.com/pan/api/nodes/%s?orgId=%s&driveId=%s", nodeId, Teambition.GloablOrgId, Teambition.GloablDriveId) - resp, err := TeambitionSession.Get(url, nil) - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if err != nil { - panic(err.Error()) - } - downUrl := jsoniter.Get(resp.Bytes, "downloadUrl").ToString() - if downUrl == "" { - log.Warningln("Teambition盘下载地址获取失败") - } - return downUrl -} -func GetTeambitionProDownUrl(server, accountId, nodeId string) string { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - url := fmt.Sprintf("https://%s.teambition.com/api/works/%s", server, nodeId) - resp, err := TeambitionSession.Get(url, nil) - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if err != nil { - panic(err.Error()) - } - downUrl := jsoniter.Get(resp.Bytes, "downloadUrl").ToString() - - if downUrl == "" { - log.Warningln("Teambition盘下载地址获取失败") - } - rs, _ := nic.Get(downUrl, nic.H{ - AllowRedirect: false, - }) - return rs.Header.Get("Location") -} - -func TeambitionUpload(accountId, parentId string, files []*multipart.FileHeader) bool { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - for _, file := range files { - t1 := time.Now() - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - fs := []nic.KV{nic.KV{ - "driveId": Teambition.GloablDriveId, - "chunkCount": 1, - "name": file.Filename, - "ccpParentId": parentId, - "contentType": "", - "size": file.Size, - "type": "file", - }} - resp, _ := TeambitionSession.Post("https://pan.teambition.com/pan/api/nodes/file", nic.H{ - JSON: nic.KV{ - "orgId": Teambition.GloablOrgId, - "spaceId": Teambition.GloablSpaceId, - "parentId": parentId, - "checkNameMode": "autoRename", - "infos": fs, - }, - }) - nodeId := jsoniter.Get(resp.Bytes, 0).Get("nodeId").ToString() - uploadId := jsoniter.Get(resp.Bytes, 0).Get("uploadId").ToString() - resp, _ = TeambitionSession.Post(fmt.Sprintf("https://pan.teambition.com/pan/api/nodes/%s/uploadUrl", nodeId), nic.H{ - JSON: nic.KV{ - "orgId": Teambition.GloablOrgId, - "driveId": Teambition.GloablDriveId, - "uploadId": uploadId, - "startPartNumber": 1, - "endPartNumber": 1, - }, - }) - fileId := jsoniter.Get(resp.Bytes, "fileId").ToString() - partInfoListString := jsoniter.Get(resp.Bytes, "partInfoList").ToString() - partInfoList := []entity.PartInfo{} - jsoniter.UnmarshalFromString(partInfoListString, &partInfoList) - log.Debugf("文件分片数:%d", len(partInfoList)) - for _, partInfo := range partInfoList { - fileContent, _ := file.Open() - byteContent, _ := ioutil.ReadAll(fileContent) - client := &http.Client{} - req, err := http.NewRequest(http.MethodPut, partInfo.UploadUrl, bytes.NewBuffer(byteContent)) - if err != nil { - log.Error("上传失败") - return false - } - client.Do(req) - } - resp, _ = TeambitionSession.Post("https://pan.teambition.com/pan/api/nodes/complete", nic.H{ - JSON: nic.KV{ - "orgId": Teambition.GloablOrgId, - "driveId": Teambition.GloablDriveId, - "uploadId": uploadId, - "nodeId": nodeId, - "ccpFileId": fileId, - }, - }) - log.Debugf("上传接口返回:%s", resp.Text) - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return true -} - -func TeambitionProUpload(server, accountId, parentId string, files []*multipart.FileHeader) bool { - Teambition := TeambitionSessions[accountId] - TeambitionSession := Teambition.TeambitionSession - prefix := "" - if server == "us" { - prefix = "us" - } else { - prefix = "www" - } - for _, file := range files { - t1 := time.Now() - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - resp, _ := TeambitionSession.Get(fmt.Sprintf("https://%s.teambition.com/projects", prefix), nil) - //0.准备文件 - fileContent, _ := file.Open() - byteContent, _ := ioutil.ReadAll(fileContent) - //1.获取jwt - jwt := GetCurBetweenStr(resp.Text, "strikerAuth":"", "","phoneForLogin") - //2.上传文件 - if server == "us" { - prefix = "us-" - } else { - prefix = "" - } - resp, _ = nic.Post(fmt.Sprintf("https://%stcs.teambition.net/upload", prefix), nic.H{ - Files: nic.KV{ - "file": nic.File( - file.Filename, byteContent), - }, - Headers: nic.KV{ - "Authorization": jwt, - }, - }) - fmt.Println(resp.Text) - fileKey := jsoniter.Get(resp.Bytes, "fileKey").ToString() - fileName := jsoniter.Get(resp.Bytes, "fileName").ToString() - fileType := jsoniter.Get(resp.Bytes, "fileType").ToString() - fileSize := jsoniter.Get(resp.Bytes, "fileSize").ToInt64() - fileCategory := jsoniter.Get(resp.Bytes, "fileCategory").ToString() - //imageWidth := jsoniter.Get(resp.Bytes, "imageWidth").ToString() - //imageHeight := jsoniter.Get(resp.Bytes, "imageHeight").ToString() - //3.完成上传 - if server == "us" { - prefix = "us" - } else { - prefix = "www" - } - resp, _ = TeambitionSession.Post(fmt.Sprintf("https://%s.teambition.com/api/works", prefix), nic.H{ - JSON: nic.KV{ - "works": []nic.KV{nic.KV{ - "fileKey": fileKey, - "fileName": fileName, - "fileType": fileType, - "fileSize": fileSize, - "fileCategory": fileCategory, - /*"imageWidth": imageWidth, - "imageHeight": imageHeight,*/ - "source": "tcs", - "visible": "members", - "_parentId": parentId, - }}, - "_parentId": parentId, - }, - }) - log.Debugf("上传接口返回:%s", resp.Text) - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return true -} -func TeambitionIsLogin(accountId string, isUs bool) bool { - if _, ok := TeambitionSessions[accountId]; ok { - TeambitionSession := TeambitionSessions[accountId].TeambitionSession - d := "" - if isUs { - d = "us-" - } - resp, _ := TeambitionSession.Get(fmt.Sprintf("https://%saccount.teambition.com/api/account", d), nil) - if resp.StatusCode == 401 { - return false - } else if resp.StatusCode == 200 { - id := jsoniter.Get(resp.Bytes, "_id").ToString() - if id != "" { - return true - } - } - } - return false -} -func UTCTimeFormat(timeStr string) string { - t, _ := time.Parse(time.RFC3339, timeStr) - timeUint := t.In(time.Local).Unix() - return time.Unix(timeUint, 0).Format("2006-01-02 15:04:05") -} diff --git a/Util/WebDav.go b/Util/WebDav.go deleted file mode 100644 index 5c5de4b0..00000000 --- a/Util/WebDav.go +++ /dev/null @@ -1,152 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "PanIndex/model" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "github.com/studio-b12/gowebdav" - "mime/multipart" - "path/filepath" - "sort" - "strings" - "time" -) - -func WebDavLogin(account entity.Account) string { - c := gowebdav.NewClient(account.ApiUrl, account.User, account.Password) - err := c.Connect() - if err != nil { - log.Errorf("WebDav服务器[%s]连接失败:%s", account.ApiUrl, err) - } else { - return "webdav server connect success" - } - return "" -} - -func WebDavGetFiles(account entity.Account, fileId, path string, hide, hasPwd int, syncChild bool) { - fileNodes := []entity.FileNode{} - c := gowebdav.NewClient(account.ApiUrl, account.User, account.Password) - err := c.Connect() - if err != nil { - log.Errorf("WebDav服务器[%s]连接失败:%s", account.ApiUrl, err) - } else { - files, err := c.ReadDir(fileId) - if err == nil { - for _, fileInfo := range files { - fileType := GetMimeType(fileInfo.Name()) - fn := entity.FileNode{ - Id: uuid.NewV4().String(), - AccountId: account.Id, - IsFolder: fileInfo.IsDir(), - FileName: fileInfo.Name(), - FileSize: int64(fileInfo.Size()), - SizeFmt: FormatFileSize(int64(fileInfo.Size())), - FileType: strings.TrimLeft(filepath.Ext(fileInfo.Name()), "."), - Path: path, - MediaType: fileType, - LastOpTime: time.Unix(fileInfo.ModTime().Unix(), 0).Format("2006-01-02 15:04:05"), - Hide: 0, - HasPwd: 0, - } - if path == "/" { - fn.Path = path + fn.FileName - } else { - fn.Path = path + "/" + fn.FileName - } - if fileId == "/" { - fn.FileId = fileId + fn.FileName - } else { - fn.FileId = fileId + "/" + fn.FileName - } - fn.ParentPath = path - fn.ParentId = fileId - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } - if fn.IsFolder == true { - if syncChild { - WebDavGetFiles(account, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fn.CacheTime = time.Now().UnixNano() - fn.Delete = 1 - model.SqliteDb.Create(fn) - fileNodes = append(fileNodes, fn) - } - } - } -} -func WebDavReadFileToBytes(account entity.Account, fileId string) []byte { - c := gowebdav.NewClient(account.ApiUrl, account.User, account.Password) - err := c.Connect() - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if err != nil { - log.Errorf("WebDav服务器[%s]连接失败:%s", account.ApiUrl, err) - } else { - buf, err := c.Read(fileId) - if err != nil { - panic(err) - } - return buf - } - return nil -} -func WebDavUpload(account entity.Account, fileId string, files []*multipart.FileHeader) bool { - c := gowebdav.NewClient(account.ApiUrl, account.User, account.Password) - err := c.Connect() - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - if err != nil { - log.Errorf("WebDav服务器[%s]连接失败:%s", account.ApiUrl, err) - } else { - for _, file := range files { - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - t1 := time.Now() - fileContent, _ := file.Open() - defer fileContent.Close() - filePath := "" - if fileId == "/" { - filePath = fileId + file.Filename - } else { - filePath = fileId + "/" + file.Filename - } - err := c.WriteStream(filePath, fileContent, 0644) - if err != nil { - panic(err) - } - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return true - } - return false -} diff --git a/Util/Yun139.go b/Util/Yun139.go deleted file mode 100644 index 0db91137..00000000 --- a/Util/Yun139.go +++ /dev/null @@ -1,353 +0,0 @@ -package Util - -import ( - "PanIndex/config" - "PanIndex/entity" - "PanIndex/model" - "bytes" - "crypto/md5" - "encoding/base64" - "encoding/json" - "fmt" - jsoniter "github.com/json-iterator/go" - "github.com/libsgh/nic" - uuid "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" - "io/ioutil" - "math/rand" - "mime/multipart" - "net/http" - "net/url" - "sort" - "strconv" - "strings" - "time" -) - -var Yun139Credentials = map[string]entity.Yun139{} - -func Yun139Login(account entity.Account) string { - if Yun139LoginCheck(account) { - Yun139Credentials[account.Id] = entity.Yun139{ - account.Password, - account.User, - } - return account.Password - } - return "" -} -func Yun139LoginCheck(account entity.Account) bool { - Yun139Credentials[account.Id] = entity.Yun139{ - account.Password, - account.User, - } - body := nic.KV{ - "qryUserExternInfoReq": nic.KV{ - "commonAccountInfo": nic.KV{ - "account": account.User, - "accountType": 1, - }, - }, - } - resp, _ := nic.Post("https://yun.139.com/orchestration/personalCloud/user/v1.0/qryUserExternInfo", nic.H{ - Headers: createHeaders(body, account.Password), - JSON: body, - }) - if resp != nil && jsoniter.Get(resp.Bytes, "success").ToBool() { - nicName := jsoniter.Get(resp.Bytes, "data").Get("qryUserExternInfoRsp").Get("nickName").ToString() - if nicName != "" { - return true - } - } - return false -} - -func Yun139GetFiles(accountId, fileId, p string, hide, hasPwd int, syncChild bool) { - yun139Credential := Yun139Credentials[accountId] - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - offset := 0 - size := 200 - for { - body := nic.KV{ - "catalogID": fileId, - "sortDirection": 1, - "filterType": 0, - "catalogSortType": 0, - "contentSortType": 0, - "startNumber": offset + 1, - "endNumber": offset + size, - "commonAccountInfo": nic.KV{"account": yun139Credential.Mobile, "accountType": 1}, - } - resp, _ := nic.Post("https://yun.139.com/orchestration/personalCloud/catalog/v1.0/getDisk", nic.H{ - Headers: createHeaders(body, yun139Credential.Cookie), - JSON: body, - }) - status := jsoniter.Get(resp.Bytes, "success").ToBool() - isCompleted := jsoniter.Get(resp.Bytes, "data").Get("getDiskResult").Get("isCompleted").ToInt() - fns := []entity.FileNode{} - if status { - diskResults := jsoniter.Get(resp.Bytes, "data").Get("getDiskResult") - floderList := diskResults.Get("catalogList") - if floderList != nil { - var ls []map[string]interface{} - json.Unmarshal([]byte(floderList.ToString()), &ls) - for _, item := range ls { - fn := entity.FileNode{ - Id: uuid.NewV4().String(), - AccountId: accountId, - Delete: 1, - CacheTime: time.Now().UnixNano(), - FileIdDigest: "", - IsFolder: true, - FileId: item["catalogID"].(string), - FileName: item["catalogName"].(string), - FileSize: 0, - SizeFmt: "-", - FileType: "", - MediaType: 0, - DownloadUrl: "", - CreateTime: TimeFormat139(item["createTime"].(string)), - LastOpTime: TimeFormat139(item["updateTime"].(string)), - ParentId: fileId, - ParentPath: p, - } - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - FileNodeAuth(&fn, hide, hasPwd) - if fn.IsFolder == true { - //同步子目录&&子目录不为空 - if syncChild { - Yun139GetFiles(accountId, fn.FileId, fn.Path, fn.Hide, fn.HasPwd, syncChild) - } - } - fns = append(fns, fn) - } - } - fileList := diskResults.Get("contentList") - if fileList != nil { - var fs []map[string]interface{} - json.Unmarshal([]byte(fileList.ToString()), &fs) - for _, item := range fs { - fn := entity.FileNode{ - Id: uuid.NewV4().String(), - AccountId: accountId, - Delete: 1, - CacheTime: time.Now().UnixNano(), - FileIdDigest: "", - IsFolder: false, - FileId: item["contentID"].(string), - FileName: item["contentName"].(string), - FileSize: int64(item["contentSize"].(float64)), - SizeFmt: FormatFileSize(int64(item["contentSize"].(float64))), - FileType: item["contentSuffix"].(string), - MediaType: int(item["contentType"].(float64)), - DownloadUrl: "", - CreateTime: TimeFormat139(item["uploadTime"].(string)), - LastOpTime: TimeFormat139(item["updateTime"].(string)), - ParentId: fileId, - ParentPath: p, - } - if p == "/" { - fn.Path = p + fn.FileName - } else { - fn.Path = p + "/" + fn.FileName - } - FileNodeAuth(&fn, hide, hasPwd) - fns = append(fns, fn) - } - } - model.SqliteDb.Create(&fns) - } - if isCompleted != 1 { - //获取下一页 - offset = offset + size - } else { - break - } - } -} -func FileNodeAuth(fn *entity.FileNode, hide, hasPwd int) { - if hide == 1 { - fn.Hide = hide - } else { - if config.GloablConfig.HideFileId != "" { - listSTring := strings.Split(config.GloablConfig.HideFileId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && listSTring[i] == fn.FileId { - fn.Hide = 1 - } - } - } - if hasPwd == 1 { - fn.HasPwd = hasPwd - } else { - if config.GloablConfig.PwdDirId != "" { - listSTring := strings.Split(config.GloablConfig.PwdDirId, ",") - sort.Strings(listSTring) - i := sort.SearchStrings(listSTring, fn.FileId) - if i < len(listSTring) && strings.Split(listSTring[i], ":")[0] == fn.FileId { - fn.HasPwd = 1 - } - } - } -} -func GetYun139DownUrl(accountId, fileId string) string { - yun139Credential := Yun139Credentials[accountId] - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - body := nic.KV{ - "appName": "", - "contentID": fileId, - "commonAccountInfo": nic.KV{"account": yun139Credential.Mobile, "accountType": 1}, - } - resp, _ := nic.Post("https://yun.139.com/orchestration/personalCloud/uploadAndDownload/v1.0/downloadRequest", nic.H{ - Headers: createHeaders(body, yun139Credential.Cookie), - JSON: body, - }) - status := jsoniter.Get(resp.Bytes, "success").ToBool() - if status { - return jsoniter.Get(resp.Bytes, "data").Get("downloadURL").ToString() - } - return "" -} -func Yun139Upload(accountId, parentId string, files []*multipart.FileHeader) bool { - yun139Credential := Yun139Credentials[accountId] - defer func() { - if p := recover(); p != nil { - log.Errorln(p) - } - }() - for _, file := range files { - t1 := time.Now() - log.Debugf("开始上传文件:%s,大小:%d", file.Filename, file.Size) - f, _ := file.Open() - fileBytes, _ := ioutil.ReadAll(f) - textQuoted := strconv.QuoteToASCII(file.Filename) - textUnquoted := textQuoted[1 : len(textQuoted)-1] - digest := fmt.Sprintf("%x", md5.Sum(fileBytes)) - body := nic.KV{ - "fileCount": 1, - "parentCatalogID": parentId, - "manualRename": 2, - "newCatalogName": "", - "operation": 0, - "totalSize": file.Size, - "commonAccountInfo": nic.KV{"account": yun139Credential.Mobile, "accountType": 1}, - "uploadContentList": []nic.KV{nic.KV{ - "contentName": file.Filename, - "contentSize": file.Size, - "digest": digest, - }}, - } - resp, _ := nic.Post("https://yun.139.com/orchestration/personalCloud/uploadAndDownload/v1.0/pcUploadFileRequest", nic.H{ - Headers: createHeaders(body, yun139Credential.Cookie), - JSON: body, - }) - status := jsoniter.Get(resp.Bytes, "success").ToBool() - if status { - isNeedUpload := jsoniter.Get(resp.Bytes, "data"). - Get("uploadResult"). - Get("newContentIDList"). - Get(0). - Get("isNeedUpload").ToInt() - if isNeedUpload == 1 { - //需要上传 - uploadUrl := jsoniter.Get(resp.Bytes, "data"). - Get("uploadResult"). - Get("redirectionUrl").ToString() - uploadTaskID := jsoniter.Get(resp.Bytes, "data"). - Get("uploadResult"). - Get("uploadTaskID").ToString() - bfs := ReadBlock(file) - for _, bf := range bfs { - r, _ := http.NewRequest("POST", uploadUrl, bytes.NewReader(bf.Content)) - r.Header.Add("uploadtaskID", uploadTaskID) - r.Header.Add("rangeType", "0") - r.Header.Add("Range", bf.Range2) - r.Header.Add("Content-Type", "text/plain;name="+textUnquoted) - r.Header.Add("contentSize", strconv.FormatInt(file.Size, 10)) - r.Header.Add("Content-Length", strconv.FormatInt(file.Size, 10)) - r.Header.Add("Referer", "https://yun.139.com/") - r.Header.Add("x-SvcType", "1") - r.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36") - res, _ := http.DefaultClient.Do(r) - defer res.Body.Close() - b, _ := ioutil.ReadAll(res.Body) - log.Debugf("上传接口返回:%s", b) - } - } - } - log.Debugf("上传请求接口返回:%s", resp.Text) - log.Debugf("文件:%s,上传成功,耗时:%s", file.Filename, ShortDur(time.Now().Sub(t1))) - } - return true -} -func createHeaders(body nic.KV, cookie string) nic.KV { - timestamp := time.Now().Format("2006-01-02 15:04:05") - key := getRandomStr(16) - json, _ := jsoniter.MarshalToString(body) - sign := getSign(timestamp, key, json) - headers := nic.KV{ - "x-huawei-channelSrc": "10000034", - "x-inner-ntwk": "2", - "mcloud-channel": "1000101", - "mcloud-client": "10701", - "mcloud-sign": fmt.Sprintf("%s,%s,%s", timestamp, key, sign), - "content-type": "application/json;charset=UTF-8", - "caller": "web", - "CMS-DEVICE": "default", - "x-DeviceInfo": "||9|6.5.2|chrome|95.0.4638.17|||linux unknow||zh-CN|||", - "x-SvcType": "1", - "referer": "https://yun.139.com/w/", - "Cookie": cookie, - } - return headers -} -func getSign(timestamp, key, json string) string { - //去除多余空格 - json = strings.TrimSpace(json) - json = encodeURIComponent(json) - c := strings.Split(json, "") - sort.Strings(c) - json = strings.Join(c, "") - s1 := Md5(base64.StdEncoding.EncodeToString([]byte(json))) - s2 := Md5(timestamp + ":" + key) - return strings.ToUpper(Md5(s1 + s2)) -} -func getRandomStr(n int) string { - letters := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") - b := make([]rune, n) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] - } - return string(b) -} -func Md5(data string) string { - return fmt.Sprintf("%x", md5.Sum([]byte(data))) -} -func TimeFormat139(timeStr string) string { - t, _ := time.ParseInLocation("20060102150405", timeStr, time.Local) - timeFormat := time.Unix(t.Unix(), 0).Format("2006-01-02 15:04:05") - return timeFormat -} -func encodeURIComponent(str string) string { - r := url.QueryEscape(str) - r = strings.Replace(r, "+", "%20", -1) - r = strings.Replace(r, "%21", "!", -1) - r = strings.Replace(r, "%27", "'", -1) - r = strings.Replace(r, "%28", "(", -1) - r = strings.Replace(r, "%29", ")", -1) - r = strings.Replace(r, "%2A", "*", -1) - return r -} diff --git a/app.json b/app.json deleted file mode 100755 index 7596be47..00000000 --- a/app.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "PanIndex", - "description": "简易的网盘目录列表", - "keywords": [ - "PanIndex", "cloud.189.cn", "teambition" - ], - "env": { - "TZ": { - "description": "时区", - "value": "Asia/Shanghai" - }, - "LANG": { - "description": "编码格式", - "value": "en_US.UTF-8" - }, - "PAN_INDEX_VERSION": { - "description": "PanIndex版本,默认为最新版,查看:https://github.com/libsgh/PanIndex/releases", - "required": false, - "value": "" - }, - "PAN_INDEX_CONFIG": { - "description": "程序配置,json格式,从后台获取复制到这里", - "required": false, - "value": "" - }, - "PAN_INDEX_DEBUG": { - "description": "调试模式,设置为true将输出更多日志", - "value": "false" - } - }, - "website": "http://github.com/libsgh/PanIndex", - "repository": "http://github.com/libsgh/PanIndex", - "stack": "container", - "features": [ - "runtime-dyno-metadata" - ] -} \ No newline at end of file diff --git a/boot/Init.go b/boot/Init.go deleted file mode 100644 index 4e845536..00000000 --- a/boot/Init.go +++ /dev/null @@ -1,183 +0,0 @@ -package boot - -import ( - "PanIndex/jobs" - "PanIndex/model" - "PanIndex/service" - "encoding/json" - "fmt" - "github.com/banzaicloud/logrus-runtime-formatter" - "github.com/gin-gonic/gin" - log "github.com/sirupsen/logrus" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "gorm.io/gorm/logger" - "gorm.io/gorm/schema" - "io/ioutil" - "net/http" - "os" - "strconv" - "strings" -) - -var ( - VERSION string - GO_VERSION string - BUILD_TIME string - GIT_COMMIT_SHA string -) - -func Start(host, port string, debug bool, dataPath string) { - if os.Getenv("PAN_INDEX_DEBUG") != "" { - if os.Getenv("PAN_INDEX_DEBUG") == "true" { - debug = true - } else if os.Getenv("PAN_INDEX_DEBUG") == "false" { - debug = false - } - } - //初始化日志设置 - InitLog(debug) - //打印asc - PrintAsc() - //打印版本信息 - PrintVersion() - //检查新版本 - go CheckUpdate() - //初始化数据库 - model.InitDb(host, port, dataPath, debug) - //初始化配置 - //从环境变量写入到config - service.EnvToConfig() - service.GetConfig() - //系统定时任务初始化 - jobs.Run() - //网盘定时缓存任务初始化 - jobs.AutoCacheRun() - //刷新cookie和目录缓存 - go jobs.StartInit() -} - -func PrintAsc() { - fmt.Println(` - ____ __ _ _ ____ _ _ ____ ____ _ _ -( _ \ /__\ ( \( )(_ _)( \( )( _ \( ___)( \/ ) - )___//(__)\ ) ( _)(_ ) ( )(_) ))__) ) ( -(__) (__)(__)(_)\_)(____)(_)\_)(____/(____)(_/\_) -`) -} - -// boot logrus -func InitLog(debug bool) { - if debug { - log.SetLevel(log.DebugLevel) - gin.SetMode(gin.DebugMode) - } else { - gin.SetMode(gin.ReleaseMode) - } - formatter := runtime.Formatter{ChildFormatter: &log.TextFormatter{ - ForceColors: true, - EnvironmentOverrideColors: true, - TimestampFormat: "2006-01-02 15:04:05", - FullTimestamp: true, - }} - formatter.Line = true - log.SetFormatter(&formatter) -} - -func PrintVersion() { - GO_VERSION = strings.ReplaceAll(GO_VERSION, "go version ", "") - log.Printf("Git Commit Hash: %s \n", GIT_COMMIT_SHA) - log.Printf("Version: %s \n", VERSION) - log.Printf("Go Version: %s \n", GO_VERSION) - log.Printf("Build TimeStamp: %s \n", BUILD_TIME) -} - -// check updtae -func CheckUpdate() { - log.Infof("检查更新...") - url := "https://api.github.com/repos/libsgh/PanIndex/releases/latest" - resp, err := http.Get(url) - if err != nil { - log.Warnf("检查更新失败:%s", err.Error()) - return - } - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Warnf("读取更新内容失败:%s", err.Error()) - return - } - if strings.Contains(string(body), "API rate limit") { - log.Warnf("检查更新失败: API rate limit") - return - } - var release GithubRelease - err = json.Unmarshal(body, &release) - if err != nil { - log.Warnf("解析更新失败:%s", err.Error()) - return - } - lasted := release.TagName[1:] - now := VERSION - if IsLastVersion(lasted, now) { - log.Infof("当前已是最新版本:%s", VERSION) - } else { - log.Infof("发现新版本:%s", release.TagName) - log.Infof("请至'%s'获取更新.", release.HtmlUrl) - } -} - -func IsLastVersion(lasted string, now string) bool { - if now != "" { - lasted = strings.ReplaceAll(lasted, "v", "") - lasted = strings.ReplaceAll(lasted, ".", "") - lasted = strings.ReplaceAll(lasted, "BETA", "") - lastedV, _ := strconv.Atoi(lasted) - now = strings.ReplaceAll(now, "v", "") - now = strings.ReplaceAll(now, ".", "") - now = strings.ReplaceAll(now, "BETA", "") - nowV, _ := strconv.Atoi(now) - if lastedV > nowV { - return false - } - } - return true -} - -type GithubRelease struct { - TagName string `json:"tag_name"` - HtmlUrl string `json:"html_url"` - Body string `json:"body"` -} - -func PrintConfig(dataPath, cq string) bool { - c := "" - if cq == "" { - return false - } - if cq == "version" { - c = VERSION - fmt.Print(VERSION) - return true - } - if os.Getenv("PAN_INDEX_DATA_PATH") != "" { - dataPath = os.Getenv("PAN_INDEX_DATA_PATH") - } - if dataPath == "" { - dataPath = "data" - } - if _, err := os.Stat(dataPath); os.IsNotExist(err) { - os.Mkdir(dataPath, os.ModePerm) - } - SqliteDb, err := gorm.Open(sqlite.Open(dataPath+"/data.db"), &gorm.Config{ - Logger: logger.Default.LogMode(0 + 1), - NamingStrategy: schema.NamingStrategy{ - SingularTable: true, - }, - }) - if err != nil { - panic(fmt.Sprintf("Got error when connect database, the error is '%v'", err)) - } - SqliteDb.Raw("select v from config_item where k=? limit 1", cq).First(&c) - fmt.Print(c) - return true -} diff --git a/boot/boot.go b/boot/boot.go new file mode 100644 index 00000000..537f72fc --- /dev/null +++ b/boot/boot.go @@ -0,0 +1,285 @@ +package boot + +import ( + "embed" + "flag" + "fmt" + runtime "github.com/banzaicloud/logrus-runtime-formatter" + "github.com/gin-gonic/gin" + jsoniter "github.com/json-iterator/go" + "github.com/libsgh/PanIndex/dao" + "github.com/libsgh/PanIndex/jobs" + "github.com/libsgh/PanIndex/module" + "github.com/libsgh/PanIndex/util" + log "github.com/sirupsen/logrus" + "github.com/unrolled/secure" + "html/template" + "io/ioutil" + "net/http" + "os" + "path" + "path/filepath" + "strconv" + "strings" +) + +func Init() BootConfig { + //load config + config := LoadConfig() + //Create data dir + config = CreatDataDir(config) + //int log level + InitLog(config.LogLevel) + //print asc + PrintAsc() + //print version + PrintVersion() + //init dao + InitDb(config) + // init global config + dao.InitGlobalConfig() + //init accounts auth login + for _, account := range module.GloablConfig.Accounts { + dao.SyncAccountStatus(account) + } + //init all jobs + jobs.Run() + return config +} + +func CreatDataDir(config BootConfig) BootConfig { + dataPath := config.DataPath + if config.DataPath == "" { + ex, err := os.Executable() + if err != nil { + log.Fatal(err) + } + dataPath = filepath.Join(filepath.Dir(ex), "data") + } + err := os.MkdirAll(dataPath, os.ModePerm) + if err != nil { + log.Fatal(err) + } + config.DataPath = dataPath + return config +} + +func InitDb(config BootConfig) { + driver := "sqlite" + dsn := filepath.FromSlash(path.Join(config.DataPath, "data.db")) + if config.DbType != "" { + driver = config.DbType + } + if config.Dsn != "" { + dsn = config.Dsn + } + d, _ := dao.GetDb(driver) + d.CreateDb(dsn) +} + +//config.json > env > flag +func LoadConfig() BootConfig { + var Config = flag.String("c", "config.json", "config.json") + var Host = flag.String("host", "0.0.0.0", "bind host, default 0.0.0.0") + var Port = flag.Int("port", 5238, "bind port, default 5238") + var LogLevel = flag.String("log_level", "info", "log level: debug, info") + var DataPath = flag.String("data_path", "", "data storage directory, default program sibling directory") + var CertFile = flag.String("cert_file", "", "https cert file, /path/to/test.pem") + var KeyFile = flag.String("key_file", "", "https key file, /path/to/test.key") + var ConfigQueryOld = flag.String("cq", "", "config query old version, e.g. port") + var ConfigQuery = flag.String("config_query", "", "config query new version, e.g. port") + var DbType = flag.String("db_type", "sqlite", "dao type, e.g. sqlite,mysql,postgres...") + var Dsn = flag.String("dsn", "", "database connection url") + flag.Parse() + config, err := LoadFromFile(*Config) + if err == nil { + return *config + } + config.Host = LoadFromEnv("HOST", *Host) + port, _ := strconv.Atoi(LoadFromEnv("PORT", fmt.Sprintf("%d", *Port))) + config.Port = port + config.LogLevel = LoadFromEnv("LOG_LEVEL", *LogLevel) + config.DataPath = LoadFromEnv("PAN_INDEX_DATA_PATH", *DataPath) + config.CertFile = LoadFromEnv("CERT_FILE", *CertFile) + config.KeyFile = LoadFromEnv("KEY_FILE", *KeyFile) + config.DbType = LoadFromEnv("DB_TYPE", *DbType) + config.Dsn = LoadFromEnv("DSN", *Dsn) + config.ConfigQuery = *ConfigQuery + if *ConfigQueryOld != "" { + config.ConfigQuery = *ConfigQueryOld + } + return *config +} + +func LoadFromEnv(key string, def string) string { + value := os.Getenv(key) + if value != "" { + return value + } + return def +} + +func LoadFromFile(path string) (*BootConfig, error) { + config := new(BootConfig) + configFile, err := os.Open(path) + if err != nil { + return config, fmt.Errorf("Unable to read configuration file %s", path) + } + decoder := jsoniter.NewDecoder(configFile) + err = decoder.Decode(&config) + if err != nil { + return config, fmt.Errorf("Unable to parse configuration file %s", path) + } + return config, nil +} +func PrintAsc() { + fmt.Println(` + ____ __ _ _ ____ _ _ ____ ____ _ _ +( _ \ /__\ ( \( )(_ _)( \( )( _ \( ___)( \/ ) + )___//(__)\ ) ( _)(_ ) ( )(_) ))__) ) ( +(__) (__)(__)(_)\_)(____)(_)\_)(____/(____)(_/\_) +`) +} + +func PrintVersion() { + module.GO_VERSION = strings.ReplaceAll(module.GO_VERSION, "go version ", "") + log.Printf("Git Commit Hash: %s", module.GIT_COMMIT_SHA) + log.Printf("Version: %s", module.VERSION) + log.Printf("Go Version: %s", module.GO_VERSION) + log.Printf("Build TimeStamp: %s", module.BUILD_TIME) +} + +func TlsHandler(port int) gin.HandlerFunc { + return func(c *gin.Context) { + secureMiddleware := secure.New(secure.Options{ + SSLRedirect: true, + SSLHost: ":" + strconv.Itoa(port), + }) + err := secureMiddleware.Process(c.Writer, c.Request) + if err != nil { + return + } + c.Next() + } +} + +// logrus config +func InitLog(lvl string) error { + level, err := log.ParseLevel(lvl) + if err != nil { + return err + } + log.SetLevel(level) + if lvl == "debug" { + gin.SetMode(gin.DebugMode) + } else { + gin.SetMode(gin.ReleaseMode) + } + formatter := runtime.Formatter{ChildFormatter: &log.TextFormatter{ + ForceColors: true, + EnvironmentOverrideColors: true, + TimestampFormat: "2006-01-02 15:04:05", + FullTimestamp: true, + }} + formatter.Line = true + log.SetFormatter(&formatter) + return nil +} + +func InitStaticBox(r *gin.Engine, fs embed.FS) { + if util.FileExist("./static") { + r.Static("/static", "./static") + } else { + r.StaticFS("/static", http.FS(fs)) + } +} + +func Templates(fs embed.FS) *template.Template { + themes := [6]string{"mdui", "mdui-light", "mdui-dark", "classic", "bootstrap", "materialdesign"} + tmpl := template.New("") + templatesFileNames := []string{"base", "appearance", "common", "disk", "hide", "login", "pwd", "safety", "view", "bypass", "cache", "webdav"} + addTemplatesFromFolder("admin", tmpl, fs, templatesFileNames) + for _, theme := range themes { + tmpName := strings.Join([]string{"templates/pan/", "/index.html"}, theme) + tmpFile := strings.ReplaceAll(tmpName, "-dark", "") + tmpFile = strings.ReplaceAll(tmpFile, "-light", "") + dataBuf, _ := fs.ReadFile(tmpFile) + data := string(dataBuf) + if util.FileExist("./templates/" + tmpFile) { + s, _ := ioutil.ReadFile("./templates/" + tmpFile) + data = string(s) + } + tmpl.New(tmpName).Funcs(template.FuncMap{ + "unescaped": unescaped, + "contains": strings.Contains, + "iconclass": iconclass, + "FormateName": FormateName, + }).Parse(data) + } + //添加详情模板 + viewTemplates := [10]string{"base", "img", "audio", "video", "code", "office", "ns", "pdf", "md", "epub"} + for _, vt := range viewTemplates { + tmpName := fmt.Sprintf("templates/pan/%s/view-%s.html", "mdui", vt) + dataBuf, _ := fs.ReadFile(tmpName) + data := string(dataBuf) + if util.FileExist("./templates/" + tmpName) { + s, _ := ioutil.ReadFile("./templates/" + tmpName) + data = string(s) + } + tmpl.New(tmpName).Funcs(template.FuncMap{ + "unescaped": unescaped, + "contains": strings.Contains, + "iconclass": iconclass, + "FormateName": FormateName, + }).Parse(data) + } + return tmpl +} + +func addTemplatesFromFolder(folder string, tmpl *template.Template, fs embed.FS, templatesFileNames []string) { + for _, vt := range templatesFileNames { + tmpName := fmt.Sprintf("templates/pan/%s/%s.html", folder, vt) + dataBuf, _ := fs.ReadFile(tmpName) + data := string(dataBuf) + if util.FileExist("./templates/" + tmpName) { + s, _ := ioutil.ReadFile("./templates/" + tmpName) + data = string(s) + } + tmpl.New(tmpName).Funcs(template.FuncMap{ + "unescaped": unescaped, + "contains": strings.Contains, + "iconclass": iconclass, + "isLast": isLast, + "FormateName": FormateName, + }).Parse(data) + } +} + +type BootConfig struct { + Host string `json:"host"` + Port int `json:"port"` + LogLevel string `json:"log_level"` + DataPath string `json:"data_path"` + CertFile string `json:"cert_file"` + KeyFile string `json:"key_file"` + ConfigQuery string `json:"config_query"` + DbType string `json:"db_type"` //dao type:sqlite,mysql,postgres + Dsn string `json:"dsn"` //dao dsn +} + +func unescaped(x string) interface{} { return template.HTML(x) } + +func isLast(index int, len int) bool { + return index+1 == len +} + +func iconclass(isFolder bool, fileType string) string { + return util.GetIcon(isFolder, fileType) +} + +func FormateName(filename string) string { + filenameAll := path.Base(filename) + fileSuffix := path.Ext(filename) + filePrefix := filenameAll[0 : len(filenameAll)-len(fileSuffix)] + return filePrefix +} diff --git a/config.json b/config.json new file mode 100644 index 00000000..b9cb16cc --- /dev/null +++ b/config.json @@ -0,0 +1,11 @@ +{ + "host": "0.0.0.0", + "port": 5238, + "log_level": "info", + "data_path": "", + "cert_file": "", + "key_file": "", + "config_query": "", + "db_type": "postgres", + "dsn": "host=localhost user=postgres password=1234 dbname=pan-index port=5432 sslmode=disable TimeZone=Asia/Shanghai" +} \ No newline at end of file diff --git a/config/config.go b/config/config.go deleted file mode 100755 index 66cbef81..00000000 --- a/config/config.go +++ /dev/null @@ -1,52 +0,0 @@ -package config - -import ( - "PanIndex/entity" - "os" -) - -var GloablConfig entity.Config - -func PathExists(path string) (bool, error) { - _, err := os.Stat(path) - if err == nil { - return true, nil - } - if os.IsNotExist(err) { - return false, nil - } - return false, err -} - -type CommonConfig struct { - Host string `json:"host"` - Port int `json:"port"` - Mode string `json:"mode"` //网盘模式,native(本地模式),cloud189(默认,天翼云网盘),teambition(阿里teambition网盘) - User string `json:"user"` - Password string `json:"password"` - RootId string `json:"root_id"` - PwdDirId []PwdDirId `json:"pwd_dir_id"` - HideFileId string `json:"hide_file_id"` - HerokuAppUrl string `json:"heroku_app_url"` - ApiToken string `json:"api_token"` - Theme string `json:"theme"` - Damagou Damagou `json:"damagou"` - OnlyReferer []string `json:"only_referrer"` - CronExps CronExps `json:"cron_exps"` -} - -type CronExps struct { - RefreshCookie string `json:"refresh_cookie"` - UpdateFolderCache string `json:"update_folder_cache"` - HerokuKeepAlive string `json:"heroku_keep_alive"` -} - -type PwdDirId struct { - Id string `json:"id"` - Pwd string `json:"pwd"` -} - -type Damagou struct { - Username string `json:"username"` - Password string `json:"password"` -} diff --git a/config/config.json b/config/config.json deleted file mode 100755 index 76c44960..00000000 --- a/config/config.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "host": "0.0.0.0", - "port": 8080, - "accounts": [ - { - "id": "fbfd8891-f9ed-4889-9ae4-6c2cb0e51b43", - "name": "Index of", - "mode": "native", - "user": "", - "password": "", - "refresh_token": "", - "access_token": "", - "root_id": "/opt/share", - "default": 1, - "files_count": 0, - "status": 3, - "time_span": "0s", - "last_op_time": "2021-05-07 17:46:53" - }, - { - "id": "b0d8774e-9cdc-4b3a-b6fa-1bdfb5ecdd2e", - "name": "teambition项目盘", - "mode": "teambition", - "user": "182********", - "password": "******", - "refresh_token": "", - "access_token": "", - "root_id": "6049bbea997fc9a15fc38b3f", - "default": 0, - "files_count": 13, - "status": 2, - "time_span": "7.8s", - "last_op_time": "2021-05-07 17:47:03" - } - ], - "pwd_dir_id": "/opt/share:1234,5149631198973335:1234", - "hide_file_id": "234vsdr2342,/opt/share/hide", - "heroku_app_url": "", - "api_token": "1234", - "theme": "mdui", - "admin_password": "1234", - "damagou": { - "username": "", - "password": "" - }, - "only_referrer": "baidu.com,google.com", - "refresh_cookie": "0 0 8 1/1 * ?", - "update_folder_cache": "", - "heroku_keep_alive": "", - "footer": "" -} \ No newline at end of file diff --git a/control/admin.go b/control/admin.go new file mode 100644 index 00000000..7242be1b --- /dev/null +++ b/control/admin.go @@ -0,0 +1,237 @@ +package control + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/control/middleware" + "github.com/libsgh/PanIndex/dao" + "github.com/libsgh/PanIndex/module" + "github.com/libsgh/PanIndex/pan" + "github.com/libsgh/PanIndex/service" + "github.com/libsgh/PanIndex/util" + "net/http" + "net/url" + "strings" +) + +func AdminIndex(c *gin.Context) { + c.Redirect(http.StatusFound, module.GloablConfig.AdminPath+"/common") +} + +//admin config managent +func ConfigManagent(c *gin.Context) { + middleware.ThemeCheck(c) + theme := c.GetString("theme") + fullPath := c.Request.URL.Path + adminModule := strings.Split(fullPath, "/")[2] + var cacheData []module.Cache + searchKey := "" + if adminModule == "cache" { + path := c.Query("path") + pathEsc, _ := url.QueryUnescape(path) + cacheData = service.GetCacheData(pathEsc) + searchKey = path + } + template := fmt.Sprintf("templates/pan/admin/%s.html", adminModule) + configData := module.GloablConfig + c.HTML(http.StatusOK, template, gin.H{ + "config": configData, + "cache": cacheData, + "search_key": searchKey, + "redirect_url": adminModule, + "version": module.VERSION, + "theme": theme, + }) +} + +// admin save config +func SaveConfig(c *gin.Context) { + configMap := make(map[string]string) + c.BindJSON(&configMap) + dao.UpdateConfig(configMap) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "配置已更新,部分配置重启后生效!"}) +} + +// admin get config +func GetConfig(c *gin.Context) { + c.JSON(http.StatusOK, module.GloablConfig) +} + +// admin get account +func GetAccount(c *gin.Context) { + id := c.Query("id") + c.JSON(http.StatusOK, dao.GetAccountById(id)) +} + +// admin del accounts +func DeleteAccounts(c *gin.Context) { + delIds := []string{} + c.BindJSON(&delIds) + dao.DeleteAccounts(delIds) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "删除成功!"}) +} + +// admin sort accounts +func SortAccounts(c *gin.Context) { + sortIds := []string{} + c.BindJSON(&sortIds) + dao.SortAccounts(sortIds) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "排序完成!"}) +} + +// admin update cache +func UpdateCache(c *gin.Context) { + accountId := c.PostForm("accountId") + cachePath := c.PostForm("cachePath") + account := dao.GetAccountById(accountId) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": service.UpdateCache(account, cachePath)}) +} + +// admin refresh login status +func RefreshLogin(c *gin.Context) { + id := c.Query("id") + account := dao.GetAccountById(id) + if account.CookieStatus != -1 { + go dao.SyncAccountStatus(account) + } + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "登录状态刷新中,请稍后查看结果"}) +} + +// admin upload file +func Upload(c *gin.Context) { + accountId := c.PostForm("uploadAccount") + path := c.PostForm("uploadPath") + t := c.PostForm("type") + msg := "" + if t == "0" { + msg = service.Upload(accountId, path, c) + } else if t == "1" { + service.Async(accountId, path) + msg = "刷新缓存成功" + } else if t == "2" { + service.Upload(accountId, path, c) + service.Async(accountId, path) + msg = "上传并刷新成功" + } + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": msg}) +} + +//add hide file +func Hide(c *gin.Context) { + data := gin.H{} + c.BindJSON(&data) + dao.SaveHideFile(data["hide_path"].(string)) + parentPath := util.GetParentPath(data["hide_path"].(string)) + service.ClearFileCache(parentPath) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "添加成功!"}) +} + +//del hide file by path +func DelHide(c *gin.Context) { + delPaths := []string{} + c.BindJSON(&delPaths) + dao.DeleteHideFiles(delPaths) + for _, p := range delPaths { + parentPath := util.GetParentPath(p) + service.ClearFileCache(parentPath) + } + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "删除成功!"}) +} + +//save pwd file +func PwdFile(c *gin.Context) { + pwdFiles := module.PwdFiles{} + c.BindJSON(&pwdFiles) + dao.SavePwdFile(pwdFiles) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "保存成功!"}) +} + +//del hide file by path +func DelPwdFile(c *gin.Context) { + delPaths := []string{} + c.BindJSON(&delPaths) + dao.DeletePwdFiles(delPaths) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "删除成功!"}) +} + +//save bypass +func Bypass(c *gin.Context) { + bypass := module.Bypass{} + c.BindJSON(&bypass) + msg := dao.SaveBypass(bypass) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": msg}) +} + +//del bypass +func DelBypass(c *gin.Context) { + delIds := []string{} + c.BindJSON(&delIds) + dao.DeleteBypass(delIds) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "删除成功!"}) +} + +//get file cache +func GetCache(c *gin.Context) { + path := c.Query("path") + pathEsc, _ := url.QueryUnescape(path) + if path == "" { + c.JSON(http.StatusOK, gin.H{"status": 400, "msg": "缺少路径参数!"}) + } else { + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": service.GetCacheByPath(pathEsc)}) + } +} + +//get file cache +func CacheClear(c *gin.Context) { + data := gin.H{} + c.BindJSON(&data) + path := data["path"].(string) + isLoopChildren := data["is_loop_children"].(string) + pathEsc, _ := url.QueryUnescape(path) + if path == "" { + c.JSON(http.StatusOK, gin.H{"status": 400, "msg": "缺少路径参数!"}) + } else { + service.CacheClear(pathEsc, isLoopChildren) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "清理成功"}) + } +} + +//get bypass by account +func GetBypass(c *gin.Context) { + accountId := c.Query("account_id") + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "成功", "data": service.GetBypassByAccountId(accountId)}) +} + +func CacheConfig(c *gin.Context) { + data := module.Account{} + c.BindJSON(&data) + dao.UpdateCacheConfig(data) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": "配置成功!"}) +} + +func AliQrcode(c *gin.Context) { + qr, data := pan.QrcodeGen() + c.JSON(http.StatusOK, gin.H{ + "qr": qr, + "param": data, + }) +} + +func AliQrcodeCheck(c *gin.Context) { + t := c.PostForm("t") + codeContent := c.PostForm("codeContent") + ck := c.PostForm("ck") + resultCode := c.PostForm("resultCode") + qrCodeStatus, refreshToken := pan.QrcodeCheck(t, codeContent, ck, resultCode) + c.JSON(http.StatusOK, gin.H{ + "qrCodeStatus": qrCodeStatus, + "refreshToken": refreshToken, + }) +} + +func SaveAccount(c *gin.Context) { + data := module.Account{} + c.BindJSON(&data) + msg := dao.SaveAccount(data) + c.JSON(http.StatusOK, gin.H{"status": 0, "msg": msg}) +} diff --git a/control/dav.go b/control/dav.go new file mode 100644 index 00000000..b3f5ebd6 --- /dev/null +++ b/control/dav.go @@ -0,0 +1,59 @@ +package control + +import ( + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/control/middleware" + "github.com/libsgh/PanIndex/control/webdav" + "github.com/libsgh/PanIndex/module" + "net/http" +) + +func WebDAVAuth() gin.HandlerFunc { + return func(c *gin.Context) { + if module.GloablConfig.EnableDav == "0" { + c.Status(http.StatusUnauthorized) + c.Abort() + return + } + if module.GloablConfig.DavMode == "0" && (c.Request.Method == http.MethodPut || + c.Request.Method == http.MethodDelete || + c.Request.Method == "COPY" || + c.Request.Method == "MOVE") { + c.Status(http.StatusUnauthorized) + c.Abort() + return + } + if c.Request.Method == "OPTIONS" { + c.Next() + return + } + username, password, ok := c.Request.BasicAuth() + if !ok { + c.Writer.Header()["WWW-Authenticate"] = []string{`Basic realm="PanIndex"`} + c.Status(http.StatusUnauthorized) + c.Abort() + return + } + if username != module.GloablConfig.DavUser || password != module.GloablConfig.DavPassword { + c.Status(http.StatusUnauthorized) + c.Abort() + return + } + c.Next() + } +} + +func ServeWebDAV(c *gin.Context) { + //not support bypass + p := c.Param("path") + account, fullPath, path, _ := middleware.ParseFullPath(p) + handler := &webdav.Handler{ + Prefix: "/", + FileSystem: webdav.FileSystem{}, + LockSystem: webdav.NewMemLS(), + Account: account, + FullPath: fullPath, + Path: path, + } + handler.ServeHTTP(c.Writer, c.Request) +} diff --git a/control/index.go b/control/index.go new file mode 100644 index 00000000..db992b80 --- /dev/null +++ b/control/index.go @@ -0,0 +1,170 @@ +package control + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/control/middleware" + "github.com/libsgh/PanIndex/module" + "github.com/libsgh/PanIndex/pan" + "github.com/libsgh/PanIndex/service" + "github.com/libsgh/PanIndex/util" + "net/http" + "net/url" + "strings" +) + +func index(c *gin.Context) { + var fns []module.FileNode + var isFile bool + tmpFile := strings.Join([]string{"templates/pan/", "/index.html"}, module.GloablConfig.Theme) + account, _ := c.Get("account") + sortColumn := c.GetString("sort_column") + sortOrder := c.GetString("sort_order") + ac := account.(module.Account) + path := c.GetString("path") + fullPath := c.GetString("full_path") + theme := c.GetString("theme") + bypassName := c.GetString("bypass_name") + pwdPath := c.GetString("pwd_path") + layout := c.GetString("layout") + _, isView := c.GetQuery("v") + searchKey, isSearch := c.GetQuery("search") + var lastFile, nextFile = "", "" + if isSearch { + fns = service.Search(searchKey) + } else { + if module.GloablConfig.AccountChoose == "display" && fullPath == "/" { + //返回账号列表 + fns = service.AccountsToNodes() + } else { + fns, isFile, lastFile, nextFile = service.Index(ac, path, fullPath, sortColumn, sortOrder, isView) + } + if isFile { + if isView { + view(&tmpFile, fns[0].ViewType) + } else { + download(ac, fns[0], c) + c.Abort() + return + } + } + } + hasParent, parentPath := service.HasParent(fullPath) + c.HTML(http.StatusOK, tmpFile, gin.H{ + "title": CurrentTitle(ac, module.GloablConfig, bypassName), + "path": path, + "full_path": fullPath, + "account": ac, + "accounts": service.GetAccounts(), + "config": module.GloablConfig, + "pwd_err_msg": c.GetString("pwd_err_msg"), + "has_pwd": c.GetBool("has_pwd"), + "pwd_path": pwdPath, + "has_parent": hasParent, + "parent_path": parentPath, + "account_path": CurrentAccountPath(ac.Name, bypassName), + "search_key": searchKey, + "pre_paths": util.GetPrePath(fullPath), + "fns": fns, + "theme": theme, + "version": module.VERSION, + "layout": layout, + "last_file": lastFile, + "next_file": nextFile, + }) +} + +func CurrentTitle(ac module.Account, config module.Config, bypassName string) string { + if config.SiteName != "" { + return config.SiteName + } + if bypassName != "" { + return bypassName + } + return ac.Name +} + +func CurrentAccountPath(accountName, bypassName string) string { + if bypassName != "" { + return "/" + bypassName + } + return "/" + accountName +} + +func download(ac module.Account, fileNode module.FileNode, c *gin.Context) { + isForbidden := middleware.CheckReferer(c) + if isForbidden { + c.String(http.StatusForbidden, "403 Hotlink Forbidden") + c.Abort() + return + } + downUrl := service.GetDownloadUrl(ac, fileNode.FileId) + if strings.HasPrefix(downUrl, "http") { + if ac.DownTransfer == 1 { + if ac.TransferDomain != "" { + u, _ := url.Parse(downUrl) + domain := util.GetTransferDomain(ac.TransferDomain, u.Host) + u.Host = domain + downUrl = u.String() + c.Redirect(http.StatusFound, downUrl) + } else { + DataRroxy(ac, downUrl, fileNode.FileName, c) + } + } else { + c.Redirect(http.StatusFound, downUrl) + } + } else { + if ac.Mode == "native" { + c.FileAttachment(downUrl, fileNode.FileName) + } else if ac.Mode == "ftp" { + service.FtpDownload(ac, downUrl, fileNode, c) + } else if ac.Mode == "webdav" { + service.WebDavDownload(ac, downUrl, fileNode, c) + } + } +} + +func DataRroxy(ac module.Account, downUrl, fileName string, c *gin.Context) { + client := util.GetClient(20) + req, err := http.NewRequest("GET", downUrl, nil) + req.Header.Add("Range", c.GetHeader("Range")) + if ac.Mode == "googledrive" { + req.Header.Add("Authorization", "Bearer "+pan.GoogleDrives[ac.Id].AccessToken) + } + response, err := client.Do(req) + defer response.Body.Close() + if err != nil { + c.Status(http.StatusServiceUnavailable) + return + } + reader := response.Body + contentLength := response.ContentLength + contentType := response.Header.Get("Content-Type") + fileName = url.QueryEscape(fileName) + extraHeaders := map[string]string{ + "Content-Disposition": `attachment; filename="` + fileName + `"`, + "Accept-Ranges": "bytes", + "Content-Range": response.Header.Get("Content-Range"), + } + c.DataFromReader(response.StatusCode, contentLength, contentType, reader, extraHeaders) +} + +func view(tmpFile *string, viewType string) { + theme := strings.ReplaceAll(module.GloablConfig.Theme, "-dark", "") + theme = strings.ReplaceAll(theme, "-light", "") + *tmpFile = fmt.Sprintf("templates/pan/%s/view-%s.html", theme, viewType) +} + +func ShortRedirect(c *gin.Context) { + pathName := c.Request.URL.Path + //_, isView := c.GetQuery("v") + if pathName != "/" && pathName[len(pathName)-1:] == "/" { + pathName = pathName[0 : len(pathName)-1] + } + paths := strings.Split(pathName, "/") + if len(paths) == 3 && paths[1] == "s" { + redirectUri := service.GetRedirectUri(paths[2]) + c.Redirect(http.StatusFound, redirectUri) + } + c.Abort() +} diff --git a/control/middleware/Referer.go b/control/middleware/Referer.go new file mode 100644 index 00000000..71a26a74 --- /dev/null +++ b/control/middleware/Referer.go @@ -0,0 +1,61 @@ +package middleware + +import ( + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/module" + log "github.com/sirupsen/logrus" + "net/url" + "regexp" + "strings" +) + +//防盗链检测 +func CheckReferer(c *gin.Context) bool { + isForbidden := true + if module.GloablConfig.EnableSafetyLink == "0" { + //开启了防盗链 + isForbidden = false + } else { + host := c.Request.Host + referer, err := url.Parse(c.Request.Referer()) + if err != nil { + log.Warningln(err) + } + if referer != nil && referer.Host != "" { + if referer.Host == host { + //站内,自动通过 + isForbidden = false + } else if referer.Host != host && len(module.GloablConfig.OnlyReferrer) > 0 { + //外部引用,并且设置了防盗链,需要进行判断 + for _, rf := range strings.Split(module.GloablConfig.OnlyReferrer, ",") { + match, _ := regexp.MatchString(rf, referer.Host) + if rf == referer.Host || match { + isForbidden = false + break + } + } + } else { + isForbidden = false + } + } else { + if module.GloablConfig.IsNullReferrer == "1" { + isForbidden = false + } else { + isForbidden = true + } + } + } + return isForbidden +} + +func RequestCancelRecover() gin.HandlerFunc { + return func(c *gin.Context) { + defer func() { + if err := recover(); err != nil { + log.Debug("client cancel the request...") + c.Request.Context().Done() + } + }() + c.Next() + } +} diff --git a/control/middleware/jwt.go b/control/middleware/jwt.go new file mode 100644 index 00000000..304885d0 --- /dev/null +++ b/control/middleware/jwt.go @@ -0,0 +1,122 @@ +package middleware + +import ( + "errors" + jwt "github.com/appleboy/gin-jwt/v2" + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/module" + log "github.com/sirupsen/logrus" + "net/http" + "strings" + "time" +) + +const ( + LoginTimeOut = 24 * 365 + identityKey = "id" +) + +func JWTMiddlewar() (*jwt.GinJWTMiddleware, error) { + authMiddleware, err := jwt.New(&jwt.GinJWTMiddleware{ + Realm: "PanIndex Zone", + Key: []byte("PanIndex"), + Timeout: (time.Duration(LoginTimeOut)) * time.Hour, + MaxRefresh: (time.Duration(LoginTimeOut)) * time.Hour, + IdentityKey: identityKey, + PayloadFunc: func(data interface{}) jwt.MapClaims { + if v, ok := data.(*User); ok { + return jwt.MapClaims{ + identityKey: v.UserName, + } + } + return jwt.MapClaims{} + }, + IdentityHandler: func(c *gin.Context) interface{} { + claims := jwt.ExtractClaims(c) + return &User{ + UserName: claims[identityKey].(string), + } + }, + Authenticator: func(c *gin.Context) (interface{}, error) { + var loginVals Login + if err := c.ShouldBind(&loginVals); err != nil { + return "", jwt.ErrMissingLoginValues + } + password := loginVals.Password + if password == module.GloablConfig.AdminPassword { + return &User{ + UserName: "admin", + }, nil + } + + return nil, errors.New("密码错误!请重试") + }, + Authorizator: func(data interface{}, c *gin.Context) bool { + if v, ok := data.(*User); ok && v.UserName == "admin" { + return true + } + return false + }, + LoginResponse: func(c *gin.Context, code int, token string, expire time.Time) { + c.Redirect(http.StatusFound, module.GloablConfig.AdminPath+"/common") + }, + LogoutResponse: func(c *gin.Context, code int) { + c.HTML(http.StatusOK, "templates/pan/admin/login.html", gin.H{ + "error": true, + "msg": "退出成功", + "redirect_url": "login", + "config": module.GloablConfig, + }) + }, + Unauthorized: func(c *gin.Context, code int, message string) { + path := c.Request.RequestURI + if strings.HasPrefix(path, "/api") { + //api return json + c.JSON(code, gin.H{ + "status": code, + "msg": message, + }) + } else { + //return to login + data := gin.H{ + "error": true, + "msg": message, + "redirect_url": "login", + "config": module.GloablConfig, + "theme": module.GloablConfig.Theme, + } + if message == "cookie token is empty" { + data["error"] = false + data["msg"] = "" + } + c.HTML(http.StatusOK, "templates/pan/admin/login.html", data) + } + }, + SendCookie: true, + SecureCookie: false, //non HTTPS dev environments + CookieHTTPOnly: true, // JS can't modify + CookieName: "token", // default jwt + TokenLookup: "header: Authorization, cookie: token", + CookieSameSite: http.SameSiteDefaultMode, //SameSiteDefaultMode, SameSiteLaxMode, SameSiteStrictMode, SameSiteNoneMode + TokenHeadName: "Bearer", + // TimeFunc provides the current time. You can override it to use another time value. This is useful for testing or if your server uses a different time zone than your tokens. + TimeFunc: time.Now, + }) + errInit := authMiddleware.MiddlewareInit() + + if errInit != nil { + log.Fatal("authMiddleware.MiddlewareInit() Error:" + errInit.Error()) + } + + if err != nil { + log.Fatal("JWT Error:" + err.Error()) + } + return authMiddleware, err +} + +type Login struct { + Password string `form:"password" json:"password" binding:"required"` +} +type User struct { + UserName string +} diff --git a/control/middleware/pwd.go b/control/middleware/pwd.go new file mode 100644 index 00000000..dbebd1ed --- /dev/null +++ b/control/middleware/pwd.go @@ -0,0 +1,177 @@ +package middleware + +import ( + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/module" + "github.com/libsgh/PanIndex/util" + log "github.com/sirupsen/logrus" + "net/http" + "net/url" + "strings" +) + +func Check(c *gin.Context) { + fullPath := c.Request.URL.Path + account, fullPath, path, bypassName := ParseFullPath(fullPath) + c.Set("account", account) + c.Set("path", path) + c.Set("full_path", fullPath) + c.Set("bypass_name", bypassName) + PwdCheck(c, fullPath) + SortCheck(c) + ThemeCheck(c) + LayoutCheck(c) + if len(module.GloablConfig.Accounts) == 0 { + c.Redirect(http.StatusFound, module.GloablConfig.AdminPath) + } + c.Next() +} + +func SortCheck(c *gin.Context) { + sColumn := "" + sColumnCookie, err := c.Request.Cookie("sort_column") + if err != nil { + sColumn = module.GloablConfig.SColumn + } else { + sColumn = sColumnCookie.Value + } + c.Set("sort_column", sColumn) + sOrder := "" + sOrderCookie, err := c.Request.Cookie("sort_order") + if err != nil { + sOrder = module.GloablConfig.SOrder + } else { + sOrder = sOrderCookie.Value + } + c.Set("sort_order", sOrder) +} + +func PwdCheck(c *gin.Context, fullPath string) { + filePwd, ok := util.GetPwdFromPath(fullPath) + if ok { + pwdCookie, err := c.Request.Cookie("file_pwd") + if err != nil { + //redirect input pwd + c.Set("pwd_err_msg", "") + c.Set("has_pwd", true) + } else { + result, msg := VerifyPwd(filePwd.Password, filePwd.FilePath, pwdCookie.Value) + c.Set("pwd_err_msg", msg) + c.Set("has_pwd", result) + } + c.Set("pwd_path", filePwd.FilePath) + } else { + c.Set("pwd_err_msg", "") + c.Set("has_pwd", false) + c.Set("pwd_path", "") + } +} + +func VerifyPwd(pwd, path, cookiepwd string) (bool, string) { + inputPwd := GetPwdFromCookie(cookiepwd, path) + if inputPwd == "" { + return true, "" + } else if inputPwd != pwd { + return true, "密码错误" + } else { + return false, "" + } +} + +func ThemeCheck(c *gin.Context) { + theme, err := c.Request.Cookie("theme") + if err != nil { + c.Set("theme", "mdui") + } else { + c.Set("theme", theme.Value) + } +} + +func LayoutCheck(c *gin.Context) { + layout, err := c.Request.Cookie("layout") + if err != nil { + c.Set("layout", "view_comfy") + } else { + c.Set("layout", layout.Value) + } +} + +func GetPwdFromCookie(pwd, fullPath string) string { + pathMd5 := util.Md5(fullPath) + decodedValue, _ := url.QueryUnescape(pwd) + s := strings.Split(decodedValue, ",") + if len(s) > 0 { + for _, v := range s { + if strings.Split(v, ":")[0] == pathMd5 { + return strings.Split(v, ":")[1] + } + } + } + return "" +} + +func ParseFullPath(path string) (module.Account, string, string, string) { + if path == "" { + path = "/" + } + if path == "/" && module.GloablConfig.AccountChoose == "default" && len(module.GloablConfig.BypassList) > 0 { + path = "/" + module.GloablConfig.BypassList[0].Name + } else { + if path == "/" && module.GloablConfig.AccountChoose == "default" && len(module.GloablConfig.Accounts) > 0 { + path = "/" + module.GloablConfig.Accounts[0].Name + } + } + fullPath := path + if path != "/" && path[len(path)-1:] == "/" { + path = path[0 : len(path)-1] + } + paths := strings.Split(path, "/") + accountName := paths[1] + account, bypassName := GetCurrentAccount(accountName) + path = strings.Join(paths[2:], "/") + path = "/" + path + if fullPath != "/" && fullPath[len(fullPath)-1:] == "/" { + fullPath = fullPath[0 : len(fullPath)-1] + } + return account, fullPath, path, bypassName +} + +func GetCurrentAccount(name string) (module.Account, string) { + //get account from bypass + var bypass module.Bypass + if len(module.GloablConfig.BypassList) > 0 { + if name == "" { + bypass = module.GloablConfig.BypassList[0] + } else { + for _, item := range module.GloablConfig.BypassList { + if item.Name == name { + bypass = item + break + } + } + } + if bypass.Name != "" { + //get round robin account + bypassAccount := bypass.Rw.Next().(module.Account) + log.Debugf("access bypass account: %s", bypassAccount.Name) + return bypassAccount, bypass.Name + } + } + //get account from accounts + var account module.Account + if name == "" { + if len(module.GloablConfig.Accounts) > 0 { + account = module.GloablConfig.Accounts[0] + } else { + account = module.Account{} + } + } else { + for _, ac := range module.GloablConfig.Accounts { + if ac.Name == name { + account = ac + break + } + } + } + return account, bypass.Name +} diff --git a/control/public.go b/control/public.go new file mode 100644 index 00000000..e81c1511 --- /dev/null +++ b/control/public.go @@ -0,0 +1,107 @@ +package control + +import ( + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/control/middleware" + "github.com/libsgh/PanIndex/dao" + "github.com/libsgh/PanIndex/pan" + "github.com/libsgh/PanIndex/service" + "github.com/libsgh/PanIndex/util" + "net/http" + "strings" +) + +func ExchangeToken(c *gin.Context) { + /*clientId := c.PostForm("client_id") + clientSecret := c.PostForm("client_secret") + code := c.PostForm("code") + redirectUri := c.PostForm("redirect_uri") + zone := c.PostForm("zone") + tokenInfo := Util.OneExchangeToken(zone, clientId, redirectUri, clientSecret, code) + c.String(http.StatusOK, tokenInfo)*/ +} + +//short url & qrcode +func ShortInfo(c *gin.Context) { + accountId := c.PostForm("accountId") + path := c.PostForm("path") + prefix := c.PostForm("prefix") + isFile := c.PostForm("isFile") + url, qrCode, msg := service.ShortInfo(accountId, path, prefix, isFile) + c.JSON(http.StatusOK, gin.H{ + "short_url": url, + "qr_code": qrCode, + "msg": msg, + }) +} + +//aliyundrive transcode +func AliTranscode(c *gin.Context) { + accountId := c.Query("accountId") + fileId := c.Query("fileId") + account := dao.GetAccountById(accountId) + p, _ := pan.GetPan(account.Mode) + result, _ := p.(*pan.Ali).Transcode(account, fileId) + c.String(http.StatusOK, result) + c.Abort() +} + +func Raw(c *gin.Context) { + p := c.Param("path") + hasPwd := c.GetBool("has_pwd") + if hasPwd { + CommonResp(c, "unauthorized", 401, nil) + return + } + account, fullpath, path, _ := middleware.ParseFullPath(p) + fileName := util.GetFileName(fullpath) + fileId := service.GetFileIdByPath(account, path, fullpath) + downloadUrl := service.GetDownloadUrl(account, fileId) + if fileId == "" || downloadUrl == "" { + CommonResp(c, "file not found", 404, nil) + return + } + if strings.HasPrefix(downloadUrl, "http") { + DataRroxy(account, downloadUrl, fileName, c) + } else { + pa, _ := pan.GetPan(account.Mode) + fileNode, _ := pa.File(account, fileId, fullpath) + if account.Mode == "ftp" { + service.FtpDownload(account, downloadUrl, fileNode, c) + } else if account.Mode == "webdav" { + service.WebDavDownload(account, downloadUrl, fileNode, c) + } else { + c.FileAttachment(downloadUrl, fileName) + } + + } + +} + +func Files(c *gin.Context) { + hasPwd := c.GetBool("has_pwd") + if hasPwd { + CommonResp(c, "unauthorized", 401, nil) + return + } + path := c.PostForm("path") + viewType := c.PostForm("viewType") + sColumn := c.PostForm("sortColumn") + sOrder := c.PostForm("sortOrder") + account, fullPath, p, _ := middleware.ParseFullPath(path) + files := service.GetFiles(account, p, fullPath, sColumn, sOrder, viewType) + c.JSON(http.StatusOK, gin.H{ + "message": "success", + "status": 0, + "data": files, + }) +} + +func CommonResp(c *gin.Context, msg string, code int, data interface{}) { + c.JSON(http.StatusOK, gin.H{ + "status": code, + "msg": msg, + "data": data, + }) + c.Abort() +} diff --git a/control/router.go b/control/router.go new file mode 100644 index 00000000..108100c0 --- /dev/null +++ b/control/router.go @@ -0,0 +1,83 @@ +package control + +import ( + "github.com/gin-gonic/gin" + "github.com/libsgh/PanIndex/control/middleware" + "github.com/libsgh/PanIndex/module" +) + +func SetRouters(r *gin.Engine) { + jwt, _ := middleware.JWTMiddlewar() + api := r.Group("/api/v3") + public := api.Group("/public") + { + public.GET("/download/folder") //download folder + public.POST("/files", middleware.Check, Files) //flie list by path + public.GET("/file", func(c *gin.Context) { + c.String(200, "api file") + }) //flie by path + public.POST("/transcode", AliTranscode) //ali transcode stream + public.POST("/shortInfo", ShortInfo) //short url && qrcode + public.POST("/onedrive/exchangeToken", ExchangeToken) //onedrive exchange token + public.POST("/onedrive/refreshToken") //onedrive refresh token + public.GET("/raw/*path", middleware.Check, Raw) //file original content + } + adminApi := api.Group(module.GloablConfig.AdminPath, jwt.MiddlewareFunc()) + { + adminApi.POST("/config", SaveConfig) //save config + adminApi.GET("/config", GetConfig) //get config info + adminApi.GET("/account", GetAccount) //get account info + adminApi.POST("/account", SaveAccount) //save account info + adminApi.DELETE("/accounts", DeleteAccounts) //del accounts + adminApi.POST("/accounts/sort", SortAccounts) //sort accounts + adminApi.POST("/cache/update", UpdateCache) //update cache + adminApi.POST("/refresh/login", RefreshLogin) //refresh login status + adminApi.POST("/upload", Upload) //simple upload file + adminApi.POST("/hide/file", Hide) //add hide file + adminApi.DELETE("/hide/file", DelHide) //del hide file by path + adminApi.POST("/password/file", PwdFile) //add pwd file + adminApi.DELETE("/password/file", DelPwdFile) //del pwd file by path + adminApi.POST("/bypass", Bypass) //save bypass config + adminApi.DELETE("/bypass", DelBypass) //del bypass config + adminApi.GET("/bypass", GetBypass) //get bypass by account + adminApi.GET("/cache", GetCache) //get file cache data + adminApi.POST("/cache/clear", CacheClear) //clear file cache + adminApi.POST("/cache/config", CacheConfig) //save cache config + adminApi.GET("/ali/qrcode", AliQrcode) //ali qrcode + adminApi.POST("/ali/qrcode/check", AliQrcodeCheck) //ali qrcode check + } + + admin := r.Group(module.GloablConfig.AdminPath) + { + admin.POST("/login", jwt.LoginHandler) //login + admin.GET("/logout", jwt.LogoutHandler) //logout + auth := admin.Use(jwt.MiddlewareFunc()) + auth.GET("/", AdminIndex) + auth.GET("/common", ConfigManagent) //base config + auth.GET("/appearance", ConfigManagent) //appearance + auth.GET("/view", ConfigManagent) //view config + auth.GET("/pwd", ConfigManagent) //pwd file config + auth.GET("/hide", ConfigManagent) //hide file config + auth.GET("/safety", ConfigManagent) //safety + auth.GET("/disk", ConfigManagent) //bind net disk + auth.GET("/bypass", ConfigManagent) //bypass download + auth.GET("/cache", ConfigManagent) //cache + auth.GET("/webdav", ConfigManagent) //webdav + } + r.GET("/s/*shortCode", ShortRedirect) + dav := r.Group(module.GloablConfig.DavPath) + { + dav.Use(WebDAVAuth()) + dav.Any("/*path", ServeWebDAV) + dav.Handle("PROPFIND", "/*path", ServeWebDAV) + dav.Handle("PROPFIND", "", ServeWebDAV) + dav.Handle("MKCOL", "/*path", ServeWebDAV) + dav.Handle("LOCK", "/*path", ServeWebDAV) + dav.Handle("UNLOCK", "/*path", ServeWebDAV) + dav.Handle("PROPPATCH", "/*path", ServeWebDAV) + dav.Handle("COPY", "/*path", ServeWebDAV) + dav.Handle("MOVE", "/*path", ServeWebDAV) + } + r.NoRoute(middleware.Check, index) + +} diff --git a/control/webdav/file.go b/control/webdav/file.go new file mode 100644 index 00000000..84e8574d --- /dev/null +++ b/control/webdav/file.go @@ -0,0 +1,215 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package webdav + +import ( + "github.com/libsgh/PanIndex/control/middleware" + "github.com/libsgh/PanIndex/module" + "github.com/libsgh/PanIndex/pan" + "github.com/libsgh/PanIndex/service" + "github.com/libsgh/PanIndex/util" + log "github.com/sirupsen/logrus" + "golang.org/x/net/context" + "io/ioutil" + "net/http" + "path" + "path/filepath" + "strings" + "time" +) + +type FileSystem struct{} + +func (fs *FileSystem) File(account module.Account, path, fullPath string) (module.FileNode, bool) { + if module.GloablConfig.AccountChoose == "display" && fullPath == "/" { + //accounts list + return module.FileNode{ + FileId: "root", + FileName: "root", + FileSize: 0, + IsFolder: true, + Path: "/", + LastOpTime: time.Now().Format("2006-01-02 15:04:05"), + }, true + } else { + fn, err := service.File(account, path, fullPath) + if err != nil { + log.Error(err) + } + if fn.FileId != "" { + return fn, true + } + return module.FileNode{}, false + } +} + +func (fs *FileSystem) Files(account module.Account, path, fullPath string) []module.FileNode { + if module.GloablConfig.AccountChoose == "display" && fullPath == "/" { + return service.AccountsToNodes() + } else { + fns := service.Files(account, path, fullPath) + return fns + } +} + +func (fs *FileSystem) Delete(account module.Account, path, fullPath string) error { + return service.DeleteFile(account, path, fullPath) +} + +func (fs *FileSystem) Upload(account module.Account, req *http.Request, path, fullPath, fileId string, overwrite bool) error { + _, fileName := util.ParsePath(path) + content, err := ioutil.ReadAll(req.Body) + if err != nil { + return err + } + files := []*module.UploadInfo{{ + FileName: fileName, + FileSize: req.ContentLength, + ContentType: req.Header.Get("Content-Type"), + Content: content, + }} + p, _ := pan.GetPan(account.Mode) + ok, _, err := p.UploadFiles(account, fileId, files, overwrite) + log.Debugf("[webdav] Upload '%s', result: %v", fullPath, ok) + if ok && err == nil && account.CachePolicy != "nc" { + go UploadCall(account, path, fullPath, overwrite) + } + return err +} + +func UploadCall(account module.Account, path, fullPath string, overwrite bool) { + //upload success + p, _ := pan.GetPan(account.Mode) + fId := service.GetFileIdByPath(account, path, fullPath) + log.Debug("Upload file id: ", fId, " start callback:") + fn, _ := p.File(account, fId, fullPath) + service.UploadCall(account, fn, overwrite) +} + +func (fs *FileSystem) Mkdir(account module.Account, path string, fullPath string) error { + if account.Id == "" { + return ErrNotImplemented + } + p, _ := pan.GetPan(account.Mode) + filePath, fileName := util.ParsePath(path) + fileFullPath, _ := util.ParsePath(fullPath) + parentFileId := service.GetFileIdByPath(account, filePath, fileFullPath) + ok, _, err := p.Mkdir(account, parentFileId, fileName) + log.Debugf("[webdav] Mkdir '%s', result: %v", fullPath, ok) + if ok && err == nil && account.CachePolicy != "nc" { + fileId := service.GetFileIdFromApi(account, path) + fn, _ := p.File(account, fileId, fullPath) + service.MkdirCall(account, fn) + } + return err +} + +func (fs *FileSystem) Copy(src string, dst string, overwrite bool) (int, error) { + srcAccount, srcFullPath, srcPath, _ := middleware.ParseFullPath(src) + dstAccount, dstFullPath, dstPath, _ := middleware.ParseFullPath(dst) + if srcAccount.Id != dstAccount.Id { + return http.StatusMethodNotAllowed, ErrNotImplemented + } + srcFileId := service.GetFileIdByPath(srcAccount, srcPath, srcFullPath) + targetFileId := service.GetFileIdByPath(dstAccount, dstPath, dstFullPath) + p, _ := pan.GetPan(srcAccount.Mode) + ok, _, err := p.Copy(srcAccount, srcFileId, targetFileId, overwrite) + if ok { + return http.StatusCreated, nil + } else { + return http.StatusInternalServerError, err + } + return http.StatusNoContent, nil +} + +func (fs *FileSystem) Move(src string, dst string, overwrite bool) (int, error) { + i := strings.Index(src, module.GloablConfig.DavPath) + len(module.GloablConfig.DavPath) + src = src[i:] + dst = dst[i:] + srcAccount, srcFullPath, srcPath, _ := middleware.ParseFullPath(src) + dstAccount, dstFullPath, dstPath, _ := middleware.ParseFullPath(dst) + if srcAccount.Id != dstAccount.Id { + return http.StatusMethodNotAllowed, ErrNotImplemented + } + srcParentPath := util.GetParentPath(srcPath) + dstParentPath, fileName := util.ParsePath(dstPath) + p, _ := pan.GetPan(srcAccount.Mode) + srcFileId := service.GetFileIdByPath(srcAccount, srcPath, srcFullPath) + var ok bool + var err error + if srcParentPath == dstParentPath { + //rename + ok, _, err = p.Rename(srcAccount, srcFileId, fileName) + } else { + targetFileId := service.GetFileIdByPath(dstAccount, dstParentPath, util.GetParentPath(dstFullPath)) + ok, _, err = p.Move(srcAccount, srcFileId, targetFileId, overwrite) + } + if ok { + service.MoveCall(srcAccount, srcFileId, srcFullPath, dstFullPath) + } + return http.StatusNoContent, err + +} + +func (fs *FileSystem) GetSpace(account module.Account, fullPath string) (int64, int64) { + accounts := module.GloablConfig.Accounts + if len(accounts) > 0 && module.GloablConfig.AccountChoose == "display" && fullPath == "/" { + var total int64 + var used int64 + for _, ac := range accounts { + disk, _ := pan.GetPan(ac.Mode) + oneTotal, oneUsed := disk.GetSpaceSzie(ac) + total += oneTotal + used += oneUsed + } + return total, used + } else { + disk, _ := pan.GetPan(account.Mode) + return disk.GetSpaceSzie(account) + } +} + +type WalkFunc func(path string, account module.Account, p, fullPath string, info module.FileNode, err error) error + +// walkFS traverses filesystem fs starting at name up to depth levels. +// +// Allowed values for depth are 0, 1 or infiniteDepth. For each visited node, +// walkFS calls walkFn. If a visited file system node is a directory and +// walkFn returns filepath.SkipDir, walkFS will skip traversal of this node. +func walkFS(ctx context.Context, fs FileSystem, depth int, name string, account module.Account, p, fullPath string, info module.FileNode, walkFn WalkFunc) error { + // This implementation is based on Walk's code in the standard path/filepath package. + err := walkFn(name, account, p, fullPath, info, nil) + if err != nil { + if info.IsFolder && err == filepath.SkipDir { + return nil + } + return err + } + if !info.IsFolder || depth == 0 { + return nil + } + if depth == 1 { + depth = 0 + } + files := fs.Files(account, p, fullPath) + for _, file := range files { + pathName := path.Join(p, file.FileName) + fullPathName := path.Join(fullPath, file.FileName) + err = walkFS(ctx, fs, depth, file.FileName, account, pathName, fullPathName, file, walkFn) + if err != nil { + if !file.IsFolder || err != filepath.SkipDir { + return err + } + } + } + return nil +} + +func slashClean(name string) string { + if name == "" || name[0] != '/' { + name = "/" + name + } + return path.Clean(name) +} diff --git a/control/webdav/if.go b/control/webdav/if.go new file mode 100644 index 00000000..416e81cd --- /dev/null +++ b/control/webdav/if.go @@ -0,0 +1,173 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package webdav + +// The If header is covered by Section 10.4. +// http://www.webdav.org/specs/rfc4918.html#HEADER_If + +import ( + "strings" +) + +// ifHeader is a disjunction (OR) of ifLists. +type ifHeader struct { + lists []ifList +} + +// ifList is a conjunction (AND) of Conditions, and an optional resource tag. +type ifList struct { + resourceTag string + conditions []Condition +} + +// parseIfHeader parses the "If: foo bar" HTTP header. The httpHeader string +// should omit the "If:" prefix and have any "\r\n"s collapsed to a " ", as is +// returned by req.Header.Get("If") for a http.Request req. +func parseIfHeader(httpHeader string) (h ifHeader, ok bool) { + s := strings.TrimSpace(httpHeader) + switch tokenType, _, _ := lex(s); tokenType { + case '(': + return parseNoTagLists(s) + case angleTokenType: + return parseTaggedLists(s) + default: + return ifHeader{}, false + } +} + +func parseNoTagLists(s string) (h ifHeader, ok bool) { + for { + l, remaining, ok := parseList(s) + if !ok { + return ifHeader{}, false + } + h.lists = append(h.lists, l) + if remaining == "" { + return h, true + } + s = remaining + } +} + +func parseTaggedLists(s string) (h ifHeader, ok bool) { + resourceTag, n := "", 0 + for first := true; ; first = false { + tokenType, tokenStr, remaining := lex(s) + switch tokenType { + case angleTokenType: + if !first && n == 0 { + return ifHeader{}, false + } + resourceTag, n = tokenStr, 0 + s = remaining + case '(': + n++ + l, remaining, ok := parseList(s) + if !ok { + return ifHeader{}, false + } + l.resourceTag = resourceTag + h.lists = append(h.lists, l) + if remaining == "" { + return h, true + } + s = remaining + default: + return ifHeader{}, false + } + } +} + +func parseList(s string) (l ifList, remaining string, ok bool) { + tokenType, _, s := lex(s) + if tokenType != '(' { + return ifList{}, "", false + } + for { + tokenType, _, remaining = lex(s) + if tokenType == ')' { + if len(l.conditions) == 0 { + return ifList{}, "", false + } + return l, remaining, true + } + c, remaining, ok := parseCondition(s) + if !ok { + return ifList{}, "", false + } + l.conditions = append(l.conditions, c) + s = remaining + } +} + +func parseCondition(s string) (c Condition, remaining string, ok bool) { + tokenType, tokenStr, s := lex(s) + if tokenType == notTokenType { + c.Not = true + tokenType, tokenStr, s = lex(s) + } + switch tokenType { + case strTokenType, angleTokenType: + c.Token = tokenStr + case squareTokenType: + c.ETag = tokenStr + default: + return Condition{}, "", false + } + return c, s, true +} + +// Single-rune tokens like '(' or ')' have a token type equal to their rune. +// All other tokens have a negative token type. +const ( + errTokenType = rune(-1) + eofTokenType = rune(-2) + strTokenType = rune(-3) + notTokenType = rune(-4) + angleTokenType = rune(-5) + squareTokenType = rune(-6) +) + +func lex(s string) (tokenType rune, tokenStr string, remaining string) { + // The net/textproto Reader that parses the HTTP header will collapse + // Linear White Space that spans multiple "\r\n" lines to a single " ", + // so we don't need to look for '\r' or '\n'. + for len(s) > 0 && (s[0] == '\t' || s[0] == ' ') { + s = s[1:] + } + if len(s) == 0 { + return eofTokenType, "", "" + } + i := 0 +loop: + for ; i < len(s); i++ { + switch s[i] { + case '\t', ' ', '(', ')', '<', '>', '[', ']': + break loop + } + } + + if i != 0 { + tokenStr, remaining = s[:i], s[i:] + if tokenStr == "Not" { + return notTokenType, "", remaining + } + return strTokenType, tokenStr, remaining + } + + j := 0 + switch s[0] { + case '<': + j, tokenType = strings.IndexByte(s, '>'), angleTokenType + case '[': + j, tokenType = strings.IndexByte(s, ']'), squareTokenType + default: + return rune(s[0]), "", s[1:] + } + if j < 0 { + return errTokenType, "", "" + } + return tokenType, s[1:j], s[j+1:] +} diff --git a/control/webdav/internal/xml/README b/control/webdav/internal/xml/README new file mode 100644 index 00000000..89656f48 --- /dev/null +++ b/control/webdav/internal/xml/README @@ -0,0 +1,11 @@ +This is a fork of the encoding/xml package at ca1d6c4, the last commit before +https://go.googlesource.com/go/+/c0d6d33 "encoding/xml: restore Go 1.4 name +space behavior" made late in the lead-up to the Go 1.5 release. + +The list of encoding/xml changes is at +https://go.googlesource.com/go/+log/master/src/encoding/xml + +This fork is temporary, and I (nigeltao) expect to revert it after Go 1.6 is +released. + +See http://golang.org/issue/11841 diff --git a/control/webdav/internal/xml/marshal.go b/control/webdav/internal/xml/marshal.go new file mode 100644 index 00000000..cb82ec21 --- /dev/null +++ b/control/webdav/internal/xml/marshal.go @@ -0,0 +1,1223 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xml + +import ( + "bufio" + "bytes" + "encoding" + "fmt" + "io" + "reflect" + "strconv" + "strings" +) + +const ( + // A generic XML header suitable for use with the output of Marshal. + // This is not automatically added to any output of this package, + // it is provided as a convenience. + Header = `` + "\n" +) + +// Marshal returns the XML encoding of v. +// +// Marshal handles an array or slice by marshalling each of the elements. +// Marshal handles a pointer by marshalling the value it points at or, if the +// pointer is nil, by writing nothing. Marshal handles an interface value by +// marshalling the value it contains or, if the interface value is nil, by +// writing nothing. Marshal handles all other data by writing one or more XML +// elements containing the data. +// +// The name for the XML elements is taken from, in order of preference: +// - the tag on the XMLName field, if the data is a struct +// - the value of the XMLName field of type xml.Name +// - the tag of the struct field used to obtain the data +// - the name of the struct field used to obtain the data +// - the name of the marshalled type +// +// The XML element for a struct contains marshalled elements for each of the +// exported fields of the struct, with these exceptions: +// - the XMLName field, described above, is omitted. +// - a field with tag "-" is omitted. +// - a field with tag "name,attr" becomes an attribute with +// the given name in the XML element. +// - a field with tag ",attr" becomes an attribute with the +// field name in the XML element. +// - a field with tag ",chardata" is written as character data, +// not as an XML element. +// - a field with tag ",innerxml" is written verbatim, not subject +// to the usual marshalling procedure. +// - a field with tag ",comment" is written as an XML comment, not +// subject to the usual marshalling procedure. It must not contain +// the "--" string within it. +// - a field with a tag including the "omitempty" option is omitted +// if the field value is empty. The empty values are false, 0, any +// nil pointer or interface value, and any array, slice, map, or +// string of length zero. +// - an anonymous struct field is handled as if the fields of its +// value were part of the outer struct. +// +// If a field uses a tag "a>b>c", then the element c will be nested inside +// parent elements a and b. Fields that appear next to each other that name +// the same parent will be enclosed in one XML element. +// +// See MarshalIndent for an example. +// +// Marshal will return an error if asked to marshal a channel, function, or map. +func Marshal(v interface{}) ([]byte, error) { + var b bytes.Buffer + if err := NewEncoder(&b).Encode(v); err != nil { + return nil, err + } + return b.Bytes(), nil +} + +// Marshaler is the interface implemented by objects that can marshal +// themselves into valid XML elements. +// +// MarshalXML encodes the receiver as zero or more XML elements. +// By convention, arrays or slices are typically encoded as a sequence +// of elements, one per entry. +// Using start as the element tag is not required, but doing so +// will enable Unmarshal to match the XML elements to the correct +// struct field. +// One common implementation strategy is to construct a separate +// value with a layout corresponding to the desired XML and then +// to encode it using e.EncodeElement. +// Another common strategy is to use repeated calls to e.EncodeToken +// to generate the XML output one token at a time. +// The sequence of encoded tokens must make up zero or more valid +// XML elements. +type Marshaler interface { + MarshalXML(e *Encoder, start StartElement) error +} + +// MarshalerAttr is the interface implemented by objects that can marshal +// themselves into valid XML attributes. +// +// MarshalXMLAttr returns an XML attribute with the encoded value of the receiver. +// Using name as the attribute name is not required, but doing so +// will enable Unmarshal to match the attribute to the correct +// struct field. +// If MarshalXMLAttr returns the zero attribute Attr{}, no attribute +// will be generated in the output. +// MarshalXMLAttr is used only for struct fields with the +// "attr" option in the field tag. +type MarshalerAttr interface { + MarshalXMLAttr(name Name) (Attr, error) +} + +// MarshalIndent works like Marshal, but each XML element begins on a new +// indented line that starts with prefix and is followed by one or more +// copies of indent according to the nesting depth. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + var b bytes.Buffer + enc := NewEncoder(&b) + enc.Indent(prefix, indent) + if err := enc.Encode(v); err != nil { + return nil, err + } + return b.Bytes(), nil +} + +// An Encoder writes XML data to an output stream. +type Encoder struct { + p printer +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + e := &Encoder{printer{Writer: bufio.NewWriter(w)}} + e.p.encoder = e + return e +} + +// Indent sets the encoder to generate XML in which each element +// begins on a new indented line that starts with prefix and is followed by +// one or more copies of indent according to the nesting depth. +func (enc *Encoder) Indent(prefix, indent string) { + enc.p.prefix = prefix + enc.p.indent = indent +} + +// Encode writes the XML encoding of v to the stream. +// +// See the documentation for Marshal for details about the conversion +// of Go values to XML. +// +// Encode calls Flush before returning. +func (enc *Encoder) Encode(v interface{}) error { + err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil) + if err != nil { + return err + } + return enc.p.Flush() +} + +// EncodeElement writes the XML encoding of v to the stream, +// using start as the outermost tag in the encoding. +// +// See the documentation for Marshal for details about the conversion +// of Go values to XML. +// +// EncodeElement calls Flush before returning. +func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error { + err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start) + if err != nil { + return err + } + return enc.p.Flush() +} + +var ( + begComment = []byte("") + endProcInst = []byte("?>") + endDirective = []byte(">") +) + +// EncodeToken writes the given XML token to the stream. +// It returns an error if StartElement and EndElement tokens are not +// properly matched. +// +// EncodeToken does not call Flush, because usually it is part of a +// larger operation such as Encode or EncodeElement (or a custom +// Marshaler's MarshalXML invoked during those), and those will call +// Flush when finished. Callers that create an Encoder and then invoke +// EncodeToken directly, without using Encode or EncodeElement, need to +// call Flush when finished to ensure that the XML is written to the +// underlying writer. +// +// EncodeToken allows writing a ProcInst with Target set to "xml" only +// as the first token in the stream. +// +// When encoding a StartElement holding an XML namespace prefix +// declaration for a prefix that is not already declared, contained +// elements (including the StartElement itself) will use the declared +// prefix when encoding names with matching namespace URIs. +func (enc *Encoder) EncodeToken(t Token) error { + + p := &enc.p + switch t := t.(type) { + case StartElement: + if err := p.writeStart(&t); err != nil { + return err + } + case EndElement: + if err := p.writeEnd(t.Name); err != nil { + return err + } + case CharData: + escapeText(p, t, false) + case Comment: + if bytes.Contains(t, endComment) { + return fmt.Errorf("xml: EncodeToken of Comment containing --> marker") + } + p.WriteString("") + return p.cachedWriteError() + case ProcInst: + // First token to be encoded which is also a ProcInst with target of xml + // is the xml declaration. The only ProcInst where target of xml is allowed. + if t.Target == "xml" && p.Buffered() != 0 { + return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded") + } + if !isNameString(t.Target) { + return fmt.Errorf("xml: EncodeToken of ProcInst with invalid Target") + } + if bytes.Contains(t.Inst, endProcInst) { + return fmt.Errorf("xml: EncodeToken of ProcInst containing ?> marker") + } + p.WriteString(" 0 { + p.WriteByte(' ') + p.Write(t.Inst) + } + p.WriteString("?>") + case Directive: + if !isValidDirective(t) { + return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers") + } + p.WriteString("") + default: + return fmt.Errorf("xml: EncodeToken of invalid token type") + + } + return p.cachedWriteError() +} + +// isValidDirective reports whether dir is a valid directive text, +// meaning angle brackets are matched, ignoring comments and strings. +func isValidDirective(dir Directive) bool { + var ( + depth int + inquote uint8 + incomment bool + ) + for i, c := range dir { + switch { + case incomment: + if c == '>' { + if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) { + incomment = false + } + } + // Just ignore anything in comment + case inquote != 0: + if c == inquote { + inquote = 0 + } + // Just ignore anything within quotes + case c == '\'' || c == '"': + inquote = c + case c == '<': + if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) { + incomment = true + } else { + depth++ + } + case c == '>': + if depth == 0 { + return false + } + depth-- + } + } + return depth == 0 && inquote == 0 && !incomment +} + +// Flush flushes any buffered XML to the underlying writer. +// See the EncodeToken documentation for details about when it is necessary. +func (enc *Encoder) Flush() error { + return enc.p.Flush() +} + +type printer struct { + *bufio.Writer + encoder *Encoder + seq int + indent string + prefix string + depth int + indentedIn bool + putNewline bool + defaultNS string + attrNS map[string]string // map prefix -> name space + attrPrefix map[string]string // map name space -> prefix + prefixes []printerPrefix + tags []Name +} + +// printerPrefix holds a namespace undo record. +// When an element is popped, the prefix record +// is set back to the recorded URL. The empty +// prefix records the URL for the default name space. +// +// The start of an element is recorded with an element +// that has mark=true. +type printerPrefix struct { + prefix string + url string + mark bool +} + +func (p *printer) prefixForNS(url string, isAttr bool) string { + // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml" + // and must be referred to that way. + // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns", + // but users should not be trying to use that one directly - that's our job.) + if url == xmlURL { + return "xml" + } + if !isAttr && url == p.defaultNS { + // We can use the default name space. + return "" + } + return p.attrPrefix[url] +} + +// defineNS pushes any namespace definition found in the given attribute. +// If ignoreNonEmptyDefault is true, an xmlns="nonempty" +// attribute will be ignored. +func (p *printer) defineNS(attr Attr, ignoreNonEmptyDefault bool) error { + var prefix string + if attr.Name.Local == "xmlns" { + if attr.Name.Space != "" && attr.Name.Space != "xml" && attr.Name.Space != xmlURL { + return fmt.Errorf("xml: cannot redefine xmlns attribute prefix") + } + } else if attr.Name.Space == "xmlns" && attr.Name.Local != "" { + prefix = attr.Name.Local + if attr.Value == "" { + // Technically, an empty XML namespace is allowed for an attribute. + // From http://www.w3.org/TR/xml-names11/#scoping-defaulting: + // + // The attribute value in a namespace declaration for a prefix may be + // empty. This has the effect, within the scope of the declaration, of removing + // any association of the prefix with a namespace name. + // + // However our namespace prefixes here are used only as hints. There's + // no need to respect the removal of a namespace prefix, so we ignore it. + return nil + } + } else { + // Ignore: it's not a namespace definition + return nil + } + if prefix == "" { + if attr.Value == p.defaultNS { + // No need for redefinition. + return nil + } + if attr.Value != "" && ignoreNonEmptyDefault { + // We have an xmlns="..." value but + // it can't define a name space in this context, + // probably because the element has an empty + // name space. In this case, we just ignore + // the name space declaration. + return nil + } + } else if _, ok := p.attrPrefix[attr.Value]; ok { + // There's already a prefix for the given name space, + // so use that. This prevents us from + // having two prefixes for the same name space + // so attrNS and attrPrefix can remain bijective. + return nil + } + p.pushPrefix(prefix, attr.Value) + return nil +} + +// createNSPrefix creates a name space prefix attribute +// to use for the given name space, defining a new prefix +// if necessary. +// If isAttr is true, the prefix is to be created for an attribute +// prefix, which means that the default name space cannot +// be used. +func (p *printer) createNSPrefix(url string, isAttr bool) { + if _, ok := p.attrPrefix[url]; ok { + // We already have a prefix for the given URL. + return + } + switch { + case !isAttr && url == p.defaultNS: + // We can use the default name space. + return + case url == "": + // The only way we can encode names in the empty + // name space is by using the default name space, + // so we must use that. + if p.defaultNS != "" { + // The default namespace is non-empty, so we + // need to set it to empty. + p.pushPrefix("", "") + } + return + case url == xmlURL: + return + } + // TODO If the URL is an existing prefix, we could + // use it as is. That would enable the + // marshaling of elements that had been unmarshaled + // and with a name space prefix that was not found. + // although technically it would be incorrect. + + // Pick a name. We try to use the final element of the path + // but fall back to _. + prefix := strings.TrimRight(url, "/") + if i := strings.LastIndex(prefix, "/"); i >= 0 { + prefix = prefix[i+1:] + } + if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") { + prefix = "_" + } + if strings.HasPrefix(prefix, "xml") { + // xmlanything is reserved. + prefix = "_" + prefix + } + if p.attrNS[prefix] != "" { + // Name is taken. Find a better one. + for p.seq++; ; p.seq++ { + if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" { + prefix = id + break + } + } + } + + p.pushPrefix(prefix, url) +} + +// writeNamespaces writes xmlns attributes for all the +// namespace prefixes that have been defined in +// the current element. +func (p *printer) writeNamespaces() { + for i := len(p.prefixes) - 1; i >= 0; i-- { + prefix := p.prefixes[i] + if prefix.mark { + return + } + p.WriteString(" ") + if prefix.prefix == "" { + // Default name space. + p.WriteString(`xmlns="`) + } else { + p.WriteString("xmlns:") + p.WriteString(prefix.prefix) + p.WriteString(`="`) + } + EscapeText(p, []byte(p.nsForPrefix(prefix.prefix))) + p.WriteString(`"`) + } +} + +// pushPrefix pushes a new prefix on the prefix stack +// without checking to see if it is already defined. +func (p *printer) pushPrefix(prefix, url string) { + p.prefixes = append(p.prefixes, printerPrefix{ + prefix: prefix, + url: p.nsForPrefix(prefix), + }) + p.setAttrPrefix(prefix, url) +} + +// nsForPrefix returns the name space for the given +// prefix. Note that this is not valid for the +// empty attribute prefix, which always has an empty +// name space. +func (p *printer) nsForPrefix(prefix string) string { + if prefix == "" { + return p.defaultNS + } + return p.attrNS[prefix] +} + +// markPrefix marks the start of an element on the prefix +// stack. +func (p *printer) markPrefix() { + p.prefixes = append(p.prefixes, printerPrefix{ + mark: true, + }) +} + +// popPrefix pops all defined prefixes for the current +// element. +func (p *printer) popPrefix() { + for len(p.prefixes) > 0 { + prefix := p.prefixes[len(p.prefixes)-1] + p.prefixes = p.prefixes[:len(p.prefixes)-1] + if prefix.mark { + break + } + p.setAttrPrefix(prefix.prefix, prefix.url) + } +} + +// setAttrPrefix sets an attribute name space prefix. +// If url is empty, the attribute is removed. +// If prefix is empty, the default name space is set. +func (p *printer) setAttrPrefix(prefix, url string) { + if prefix == "" { + p.defaultNS = url + return + } + if url == "" { + delete(p.attrPrefix, p.attrNS[prefix]) + delete(p.attrNS, prefix) + return + } + if p.attrPrefix == nil { + // Need to define a new name space. + p.attrPrefix = make(map[string]string) + p.attrNS = make(map[string]string) + } + // Remove any old prefix value. This is OK because we maintain a + // strict one-to-one mapping between prefix and URL (see + // defineNS) + delete(p.attrPrefix, p.attrNS[prefix]) + p.attrPrefix[url] = prefix + p.attrNS[prefix] = url +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() + marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem() + textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() +) + +// marshalValue writes one or more XML elements representing val. +// If val was obtained from a struct field, finfo must have its details. +func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplate *StartElement) error { + if startTemplate != nil && startTemplate.Name.Local == "" { + return fmt.Errorf("xml: EncodeElement of StartElement with missing name") + } + + if !val.IsValid() { + return nil + } + if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) { + return nil + } + + // Drill into interfaces and pointers. + // This can turn into an infinite loop given a cyclic chain, + // but it matches the Go 1 behavior. + for val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr { + if val.IsNil() { + return nil + } + val = val.Elem() + } + + kind := val.Kind() + typ := val.Type() + + // Check for marshaler. + if val.CanInterface() && typ.Implements(marshalerType) { + return p.marshalInterface(val.Interface().(Marshaler), p.defaultStart(typ, finfo, startTemplate)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(marshalerType) { + return p.marshalInterface(pv.Interface().(Marshaler), p.defaultStart(pv.Type(), finfo, startTemplate)) + } + } + + // Check for text marshaler. + if val.CanInterface() && typ.Implements(textMarshalerType) { + return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), p.defaultStart(typ, finfo, startTemplate)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), p.defaultStart(pv.Type(), finfo, startTemplate)) + } + } + + // Slices and arrays iterate over the elements. They do not have an enclosing tag. + if (kind == reflect.Slice || kind == reflect.Array) && typ.Elem().Kind() != reflect.Uint8 { + for i, n := 0, val.Len(); i < n; i++ { + if err := p.marshalValue(val.Index(i), finfo, startTemplate); err != nil { + return err + } + } + return nil + } + + tinfo, err := getTypeInfo(typ) + if err != nil { + return err + } + + // Create start element. + // Precedence for the XML element name is: + // 0. startTemplate + // 1. XMLName field in underlying struct; + // 2. field name/tag in the struct field; and + // 3. type name + var start StartElement + + // explicitNS records whether the element's name space has been + // explicitly set (for example an XMLName field). + explicitNS := false + + if startTemplate != nil { + start.Name = startTemplate.Name + explicitNS = true + start.Attr = append(start.Attr, startTemplate.Attr...) + } else if tinfo.xmlname != nil { + xmlname := tinfo.xmlname + if xmlname.name != "" { + start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name + } else if v, ok := xmlname.value(val).Interface().(Name); ok && v.Local != "" { + start.Name = v + } + explicitNS = true + } + if start.Name.Local == "" && finfo != nil { + start.Name.Local = finfo.name + if finfo.xmlns != "" { + start.Name.Space = finfo.xmlns + explicitNS = true + } + } + if start.Name.Local == "" { + name := typ.Name() + if name == "" { + return &UnsupportedTypeError{typ} + } + start.Name.Local = name + } + + // defaultNS records the default name space as set by a xmlns="..." + // attribute. We don't set p.defaultNS because we want to let + // the attribute writing code (in p.defineNS) be solely responsible + // for maintaining that. + defaultNS := p.defaultNS + + // Attributes + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fAttr == 0 { + continue + } + attr, err := p.fieldAttr(finfo, val) + if err != nil { + return err + } + if attr.Name.Local == "" { + continue + } + start.Attr = append(start.Attr, attr) + if attr.Name.Space == "" && attr.Name.Local == "xmlns" { + defaultNS = attr.Value + } + } + if !explicitNS { + // Historic behavior: elements use the default name space + // they are contained in by default. + start.Name.Space = defaultNS + } + // Historic behaviour: an element that's in a namespace sets + // the default namespace for all elements contained within it. + start.setDefaultNamespace() + + if err := p.writeStart(&start); err != nil { + return err + } + + if val.Kind() == reflect.Struct { + err = p.marshalStruct(tinfo, val) + } else { + s, b, err1 := p.marshalSimple(typ, val) + if err1 != nil { + err = err1 + } else if b != nil { + EscapeText(p, b) + } else { + p.EscapeString(s) + } + } + if err != nil { + return err + } + + if err := p.writeEnd(start.Name); err != nil { + return err + } + + return p.cachedWriteError() +} + +// fieldAttr returns the attribute of the given field. +// If the returned attribute has an empty Name.Local, +// it should not be used. +// The given value holds the value containing the field. +func (p *printer) fieldAttr(finfo *fieldInfo, val reflect.Value) (Attr, error) { + fv := finfo.value(val) + name := Name{Space: finfo.xmlns, Local: finfo.name} + if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { + return Attr{}, nil + } + if fv.Kind() == reflect.Interface && fv.IsNil() { + return Attr{}, nil + } + if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) { + attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name) + return attr, err + } + if fv.CanAddr() { + pv := fv.Addr() + if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) { + attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name) + return attr, err + } + } + if fv.CanInterface() && fv.Type().Implements(textMarshalerType) { + text, err := fv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return Attr{}, err + } + return Attr{name, string(text)}, nil + } + if fv.CanAddr() { + pv := fv.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + text, err := pv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return Attr{}, err + } + return Attr{name, string(text)}, nil + } + } + // Dereference or skip nil pointer, interface values. + switch fv.Kind() { + case reflect.Ptr, reflect.Interface: + if fv.IsNil() { + return Attr{}, nil + } + fv = fv.Elem() + } + s, b, err := p.marshalSimple(fv.Type(), fv) + if err != nil { + return Attr{}, err + } + if b != nil { + s = string(b) + } + return Attr{name, s}, nil +} + +// defaultStart returns the default start element to use, +// given the reflect type, field info, and start template. +func (p *printer) defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement { + var start StartElement + // Precedence for the XML element name is as above, + // except that we do not look inside structs for the first field. + if startTemplate != nil { + start.Name = startTemplate.Name + start.Attr = append(start.Attr, startTemplate.Attr...) + } else if finfo != nil && finfo.name != "" { + start.Name.Local = finfo.name + start.Name.Space = finfo.xmlns + } else if typ.Name() != "" { + start.Name.Local = typ.Name() + } else { + // Must be a pointer to a named type, + // since it has the Marshaler methods. + start.Name.Local = typ.Elem().Name() + } + // Historic behaviour: elements use the name space of + // the element they are contained in by default. + if start.Name.Space == "" { + start.Name.Space = p.defaultNS + } + start.setDefaultNamespace() + return start +} + +// marshalInterface marshals a Marshaler interface value. +func (p *printer) marshalInterface(val Marshaler, start StartElement) error { + // Push a marker onto the tag stack so that MarshalXML + // cannot close the XML tags that it did not open. + p.tags = append(p.tags, Name{}) + n := len(p.tags) + + err := val.MarshalXML(p.encoder, start) + if err != nil { + return err + } + + // Make sure MarshalXML closed all its tags. p.tags[n-1] is the mark. + if len(p.tags) > n { + return fmt.Errorf("xml: %s.MarshalXML wrote invalid XML: <%s> not closed", receiverType(val), p.tags[len(p.tags)-1].Local) + } + p.tags = p.tags[:n-1] + return nil +} + +// marshalTextInterface marshals a TextMarshaler interface value. +func (p *printer) marshalTextInterface(val encoding.TextMarshaler, start StartElement) error { + if err := p.writeStart(&start); err != nil { + return err + } + text, err := val.MarshalText() + if err != nil { + return err + } + EscapeText(p, text) + return p.writeEnd(start.Name) +} + +// writeStart writes the given start element. +func (p *printer) writeStart(start *StartElement) error { + if start.Name.Local == "" { + return fmt.Errorf("xml: start tag with no name") + } + + p.tags = append(p.tags, start.Name) + p.markPrefix() + // Define any name spaces explicitly declared in the attributes. + // We do this as a separate pass so that explicitly declared prefixes + // will take precedence over implicitly declared prefixes + // regardless of the order of the attributes. + ignoreNonEmptyDefault := start.Name.Space == "" + for _, attr := range start.Attr { + if err := p.defineNS(attr, ignoreNonEmptyDefault); err != nil { + return err + } + } + // Define any new name spaces implied by the attributes. + for _, attr := range start.Attr { + name := attr.Name + // From http://www.w3.org/TR/xml-names11/#defaulting + // "Default namespace declarations do not apply directly + // to attribute names; the interpretation of unprefixed + // attributes is determined by the element on which they + // appear." + // This means we don't need to create a new namespace + // when an attribute name space is empty. + if name.Space != "" && !name.isNamespace() { + p.createNSPrefix(name.Space, true) + } + } + p.createNSPrefix(start.Name.Space, false) + + p.writeIndent(1) + p.WriteByte('<') + p.writeName(start.Name, false) + p.writeNamespaces() + for _, attr := range start.Attr { + name := attr.Name + if name.Local == "" || name.isNamespace() { + // Namespaces have already been written by writeNamespaces above. + continue + } + p.WriteByte(' ') + p.writeName(name, true) + p.WriteString(`="`) + p.EscapeString(attr.Value) + p.WriteByte('"') + } + p.WriteByte('>') + return nil +} + +// writeName writes the given name. It assumes +// that p.createNSPrefix(name) has already been called. +func (p *printer) writeName(name Name, isAttr bool) { + if prefix := p.prefixForNS(name.Space, isAttr); prefix != "" { + p.WriteString(prefix) + p.WriteByte(':') + } + p.WriteString(name.Local) +} + +func (p *printer) writeEnd(name Name) error { + if name.Local == "" { + return fmt.Errorf("xml: end tag with no name") + } + if len(p.tags) == 0 || p.tags[len(p.tags)-1].Local == "" { + return fmt.Errorf("xml: end tag without start tag", name.Local) + } + if top := p.tags[len(p.tags)-1]; top != name { + if top.Local != name.Local { + return fmt.Errorf("xml: end tag does not match start tag <%s>", name.Local, top.Local) + } + return fmt.Errorf("xml: end tag in namespace %s does not match start tag <%s> in namespace %s", name.Local, name.Space, top.Local, top.Space) + } + p.tags = p.tags[:len(p.tags)-1] + + p.writeIndent(-1) + p.WriteByte('<') + p.WriteByte('/') + p.writeName(name, false) + p.WriteByte('>') + p.popPrefix() + return nil +} + +func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) { + switch val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(val.Int(), 10), nil, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(val.Uint(), 10), nil, nil + case reflect.Float32, reflect.Float64: + return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil + case reflect.String: + return val.String(), nil, nil + case reflect.Bool: + return strconv.FormatBool(val.Bool()), nil, nil + case reflect.Array: + if typ.Elem().Kind() != reflect.Uint8 { + break + } + // [...]byte + var bytes []byte + if val.CanAddr() { + bytes = val.Slice(0, val.Len()).Bytes() + } else { + bytes = make([]byte, val.Len()) + reflect.Copy(reflect.ValueOf(bytes), val) + } + return "", bytes, nil + case reflect.Slice: + if typ.Elem().Kind() != reflect.Uint8 { + break + } + // []byte + return "", val.Bytes(), nil + } + return "", nil, &UnsupportedTypeError{typ} +} + +var ddBytes = []byte("--") + +func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { + s := parentStack{p: p} + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fAttr != 0 { + continue + } + vf := finfo.value(val) + + // Dereference or skip nil pointer, interface values. + switch vf.Kind() { + case reflect.Ptr, reflect.Interface: + if !vf.IsNil() { + vf = vf.Elem() + } + } + + switch finfo.flags & fMode { + case fCharData: + if err := s.setParents(&noField, reflect.Value{}); err != nil { + return err + } + if vf.CanInterface() && vf.Type().Implements(textMarshalerType) { + data, err := vf.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + Escape(p, data) + continue + } + if vf.CanAddr() { + pv := vf.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + data, err := pv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + Escape(p, data) + continue + } + } + var scratch [64]byte + switch vf.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + Escape(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + Escape(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10)) + case reflect.Float32, reflect.Float64: + Escape(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits())) + case reflect.Bool: + Escape(p, strconv.AppendBool(scratch[:0], vf.Bool())) + case reflect.String: + if err := EscapeText(p, []byte(vf.String())); err != nil { + return err + } + case reflect.Slice: + if elem, ok := vf.Interface().([]byte); ok { + if err := EscapeText(p, elem); err != nil { + return err + } + } + } + continue + + case fComment: + if err := s.setParents(&noField, reflect.Value{}); err != nil { + return err + } + k := vf.Kind() + if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) { + return fmt.Errorf("xml: bad type for comment field of %s", val.Type()) + } + if vf.Len() == 0 { + continue + } + p.writeIndent(0) + p.WriteString("" is invalid grammar. Make it "- -->" + p.WriteByte(' ') + } + p.WriteString("-->") + continue + + case fInnerXml: + iface := vf.Interface() + switch raw := iface.(type) { + case []byte: + p.Write(raw) + continue + case string: + p.WriteString(raw) + continue + } + + case fElement, fElement | fAny: + if err := s.setParents(finfo, vf); err != nil { + return err + } + } + if err := p.marshalValue(vf, finfo, nil); err != nil { + return err + } + } + if err := s.setParents(&noField, reflect.Value{}); err != nil { + return err + } + return p.cachedWriteError() +} + +var noField fieldInfo + +// return the bufio Writer's cached write error +func (p *printer) cachedWriteError() error { + _, err := p.Write(nil) + return err +} + +func (p *printer) writeIndent(depthDelta int) { + if len(p.prefix) == 0 && len(p.indent) == 0 { + return + } + if depthDelta < 0 { + p.depth-- + if p.indentedIn { + p.indentedIn = false + return + } + p.indentedIn = false + } + if p.putNewline { + p.WriteByte('\n') + } else { + p.putNewline = true + } + if len(p.prefix) > 0 { + p.WriteString(p.prefix) + } + if len(p.indent) > 0 { + for i := 0; i < p.depth; i++ { + p.WriteString(p.indent) + } + } + if depthDelta > 0 { + p.depth++ + p.indentedIn = true + } +} + +type parentStack struct { + p *printer + xmlns string + parents []string +} + +// setParents sets the stack of current parents to those found in finfo. +// It only writes the start elements if vf holds a non-nil value. +// If finfo is &noField, it pops all elements. +func (s *parentStack) setParents(finfo *fieldInfo, vf reflect.Value) error { + xmlns := s.p.defaultNS + if finfo.xmlns != "" { + xmlns = finfo.xmlns + } + commonParents := 0 + if xmlns == s.xmlns { + for ; commonParents < len(finfo.parents) && commonParents < len(s.parents); commonParents++ { + if finfo.parents[commonParents] != s.parents[commonParents] { + break + } + } + } + // Pop off any parents that aren't in common with the previous field. + for i := len(s.parents) - 1; i >= commonParents; i-- { + if err := s.p.writeEnd(Name{ + Space: s.xmlns, + Local: s.parents[i], + }); err != nil { + return err + } + } + s.parents = finfo.parents + s.xmlns = xmlns + if commonParents >= len(s.parents) { + // No new elements to push. + return nil + } + if (vf.Kind() == reflect.Ptr || vf.Kind() == reflect.Interface) && vf.IsNil() { + // The element is nil, so no need for the start elements. + s.parents = s.parents[:commonParents] + return nil + } + // Push any new parents required. + for _, name := range s.parents[commonParents:] { + start := &StartElement{ + Name: Name{ + Space: s.xmlns, + Local: name, + }, + } + // Set the default name space for parent elements + // to match what we do with other elements. + if s.xmlns != s.p.defaultNS { + start.setDefaultNamespace() + } + if err := s.p.writeStart(start); err != nil { + return err + } + } + return nil +} + +// A MarshalXMLError is returned when Marshal encounters a type +// that cannot be converted into XML. +type UnsupportedTypeError struct { + Type reflect.Type +} + +func (e *UnsupportedTypeError) Error() string { + return "xml: unsupported type: " + e.Type.String() +} + +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} diff --git a/control/webdav/internal/xml/read.go b/control/webdav/internal/xml/read.go new file mode 100644 index 00000000..4089056a --- /dev/null +++ b/control/webdav/internal/xml/read.go @@ -0,0 +1,692 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xml + +import ( + "bytes" + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" +) + +// BUG(rsc): Mapping between XML elements and data structures is inherently flawed: +// an XML element is an order-dependent collection of anonymous +// values, while a data structure is an order-independent collection +// of named values. +// See package json for a textual representation more suitable +// to data structures. + +// Unmarshal parses the XML-encoded data and stores the result in +// the value pointed to by v, which must be an arbitrary struct, +// slice, or string. Well-formed data that does not fit into v is +// discarded. +// +// Because Unmarshal uses the reflect package, it can only assign +// to exported (upper case) fields. Unmarshal uses a case-sensitive +// comparison to match XML element names to tag values and struct +// field names. +// +// Unmarshal maps an XML element to a struct using the following rules. +// In the rules, the tag of a field refers to the value associated with the +// key 'xml' in the struct field's tag (see the example above). +// +// * If the struct has a field of type []byte or string with tag +// ",innerxml", Unmarshal accumulates the raw XML nested inside the +// element in that field. The rest of the rules still apply. +// +// * If the struct has a field named XMLName of type xml.Name, +// Unmarshal records the element name in that field. +// +// * If the XMLName field has an associated tag of the form +// "name" or "namespace-URL name", the XML element must have +// the given name (and, optionally, name space) or else Unmarshal +// returns an error. +// +// * If the XML element has an attribute whose name matches a +// struct field name with an associated tag containing ",attr" or +// the explicit name in a struct field tag of the form "name,attr", +// Unmarshal records the attribute value in that field. +// +// * If the XML element contains character data, that data is +// accumulated in the first struct field that has tag ",chardata". +// The struct field may have type []byte or string. +// If there is no such field, the character data is discarded. +// +// * If the XML element contains comments, they are accumulated in +// the first struct field that has tag ",comment". The struct +// field may have type []byte or string. If there is no such +// field, the comments are discarded. +// +// * If the XML element contains a sub-element whose name matches +// the prefix of a tag formatted as "a" or "a>b>c", unmarshal +// will descend into the XML structure looking for elements with the +// given names, and will map the innermost elements to that struct +// field. A tag starting with ">" is equivalent to one starting +// with the field name followed by ">". +// +// * If the XML element contains a sub-element whose name matches +// a struct field's XMLName tag and the struct field has no +// explicit name tag as per the previous rule, unmarshal maps +// the sub-element to that struct field. +// +// * If the XML element contains a sub-element whose name matches a +// field without any mode flags (",attr", ",chardata", etc), Unmarshal +// maps the sub-element to that struct field. +// +// * If the XML element contains a sub-element that hasn't matched any +// of the above rules and the struct has a field with tag ",any", +// unmarshal maps the sub-element to that struct field. +// +// * An anonymous struct field is handled as if the fields of its +// value were part of the outer struct. +// +// * A struct field with tag "-" is never unmarshalled into. +// +// Unmarshal maps an XML element to a string or []byte by saving the +// concatenation of that element's character data in the string or +// []byte. The saved []byte is never nil. +// +// Unmarshal maps an attribute value to a string or []byte by saving +// the value in the string or slice. +// +// Unmarshal maps an XML element to a slice by extending the length of +// the slice and mapping the element to the newly created value. +// +// Unmarshal maps an XML element or attribute value to a bool by +// setting it to the boolean value represented by the string. +// +// Unmarshal maps an XML element or attribute value to an integer or +// floating-point field by setting the field to the result of +// interpreting the string value in decimal. There is no check for +// overflow. +// +// Unmarshal maps an XML element to an xml.Name by recording the +// element name. +// +// Unmarshal maps an XML element to a pointer by setting the pointer +// to a freshly allocated value and then mapping the element to that value. +// +func Unmarshal(data []byte, v interface{}) error { + return NewDecoder(bytes.NewReader(data)).Decode(v) +} + +// Decode works like xml.Unmarshal, except it reads the decoder +// stream to find the start element. +func (d *Decoder) Decode(v interface{}) error { + return d.DecodeElement(v, nil) +} + +// DecodeElement works like xml.Unmarshal except that it takes +// a pointer to the start XML element to decode into v. +// It is useful when a client reads some raw XML tokens itself +// but also wants to defer to Unmarshal for some elements. +func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error { + val := reflect.ValueOf(v) + if val.Kind() != reflect.Ptr { + return errors.New("non-pointer passed to Unmarshal") + } + return d.unmarshal(val.Elem(), start) +} + +// An UnmarshalError represents an error in the unmarshalling process. +type UnmarshalError string + +func (e UnmarshalError) Error() string { return string(e) } + +// Unmarshaler is the interface implemented by objects that can unmarshal +// an XML element description of themselves. +// +// UnmarshalXML decodes a single XML element +// beginning with the given start element. +// If it returns an error, the outer call to Unmarshal stops and +// returns that error. +// UnmarshalXML must consume exactly one XML element. +// One common implementation strategy is to unmarshal into +// a separate value with a layout matching the expected XML +// using d.DecodeElement, and then to copy the data from +// that value into the receiver. +// Another common strategy is to use d.Token to process the +// XML object one token at a time. +// UnmarshalXML may not use d.RawToken. +type Unmarshaler interface { + UnmarshalXML(d *Decoder, start StartElement) error +} + +// UnmarshalerAttr is the interface implemented by objects that can unmarshal +// an XML attribute description of themselves. +// +// UnmarshalXMLAttr decodes a single XML attribute. +// If it returns an error, the outer call to Unmarshal stops and +// returns that error. +// UnmarshalXMLAttr is used only for struct fields with the +// "attr" option in the field tag. +type UnmarshalerAttr interface { + UnmarshalXMLAttr(attr Attr) error +} + +// receiverType returns the receiver type to use in an expression like "%s.MethodName". +func receiverType(val interface{}) string { + t := reflect.TypeOf(val) + if t.Name() != "" { + return t.String() + } + return "(" + t.String() + ")" +} + +// unmarshalInterface unmarshals a single XML element into val. +// start is the opening tag of the element. +func (p *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error { + // Record that decoder must stop at end tag corresponding to start. + p.pushEOF() + + p.unmarshalDepth++ + err := val.UnmarshalXML(p, *start) + p.unmarshalDepth-- + if err != nil { + p.popEOF() + return err + } + + if !p.popEOF() { + return fmt.Errorf("xml: %s.UnmarshalXML did not consume entire <%s> element", receiverType(val), start.Name.Local) + } + + return nil +} + +// unmarshalTextInterface unmarshals a single XML element into val. +// The chardata contained in the element (but not its children) +// is passed to the text unmarshaler. +func (p *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler, start *StartElement) error { + var buf []byte + depth := 1 + for depth > 0 { + t, err := p.Token() + if err != nil { + return err + } + switch t := t.(type) { + case CharData: + if depth == 1 { + buf = append(buf, t...) + } + case StartElement: + depth++ + case EndElement: + depth-- + } + } + return val.UnmarshalText(buf) +} + +// unmarshalAttr unmarshals a single XML attribute into val. +func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error { + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + + if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) { + return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) + } + } + + // Not an UnmarshalerAttr; try encoding.TextUnmarshaler. + if val.CanInterface() && val.Type().Implements(textUnmarshalerType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) + } + } + + copyValue(val, []byte(attr.Value)) + return nil +} + +var ( + unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() + unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) + +// Unmarshal a single XML element into val. +func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error { + // Find start element if we need it. + if start == nil { + for { + tok, err := p.Token() + if err != nil { + return err + } + if t, ok := tok.(StartElement); ok { + start = &t + break + } + } + } + + // Load value from interface, but only if the result will be + // usefully addressable. + if val.Kind() == reflect.Interface && !val.IsNil() { + e := val.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() { + val = e + } + } + + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + + if val.CanInterface() && val.Type().Implements(unmarshalerType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return p.unmarshalInterface(val.Interface().(Unmarshaler), start) + } + + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(unmarshalerType) { + return p.unmarshalInterface(pv.Interface().(Unmarshaler), start) + } + } + + if val.CanInterface() && val.Type().Implements(textUnmarshalerType) { + return p.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler), start) + } + + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + return p.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler), start) + } + } + + var ( + data []byte + saveData reflect.Value + comment []byte + saveComment reflect.Value + saveXML reflect.Value + saveXMLIndex int + saveXMLData []byte + saveAny reflect.Value + sv reflect.Value + tinfo *typeInfo + err error + ) + + switch v := val; v.Kind() { + default: + return errors.New("unknown type " + v.Type().String()) + + case reflect.Interface: + // TODO: For now, simply ignore the field. In the near + // future we may choose to unmarshal the start + // element on it, if not nil. + return p.Skip() + + case reflect.Slice: + typ := v.Type() + if typ.Elem().Kind() == reflect.Uint8 { + // []byte + saveData = v + break + } + + // Slice of element values. + // Grow slice. + n := v.Len() + if n >= v.Cap() { + ncap := 2 * n + if ncap < 4 { + ncap = 4 + } + new := reflect.MakeSlice(typ, n, ncap) + reflect.Copy(new, v) + v.Set(new) + } + v.SetLen(n + 1) + + // Recur to read element into slice. + if err := p.unmarshal(v.Index(n), start); err != nil { + v.SetLen(n) + return err + } + return nil + + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.String: + saveData = v + + case reflect.Struct: + typ := v.Type() + if typ == nameType { + v.Set(reflect.ValueOf(start.Name)) + break + } + + sv = v + tinfo, err = getTypeInfo(typ) + if err != nil { + return err + } + + // Validate and assign element name. + if tinfo.xmlname != nil { + finfo := tinfo.xmlname + if finfo.name != "" && finfo.name != start.Name.Local { + return UnmarshalError("expected element type <" + finfo.name + "> but have <" + start.Name.Local + ">") + } + if finfo.xmlns != "" && finfo.xmlns != start.Name.Space { + e := "expected element <" + finfo.name + "> in name space " + finfo.xmlns + " but have " + if start.Name.Space == "" { + e += "no name space" + } else { + e += start.Name.Space + } + return UnmarshalError(e) + } + fv := finfo.value(sv) + if _, ok := fv.Interface().(Name); ok { + fv.Set(reflect.ValueOf(start.Name)) + } + } + + // Assign attributes. + // Also, determine whether we need to save character data or comments. + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + switch finfo.flags & fMode { + case fAttr: + strv := finfo.value(sv) + // Look for attribute. + for _, a := range start.Attr { + if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) { + if err := p.unmarshalAttr(strv, a); err != nil { + return err + } + break + } + } + + case fCharData: + if !saveData.IsValid() { + saveData = finfo.value(sv) + } + + case fComment: + if !saveComment.IsValid() { + saveComment = finfo.value(sv) + } + + case fAny, fAny | fElement: + if !saveAny.IsValid() { + saveAny = finfo.value(sv) + } + + case fInnerXml: + if !saveXML.IsValid() { + saveXML = finfo.value(sv) + if p.saved == nil { + saveXMLIndex = 0 + p.saved = new(bytes.Buffer) + } else { + saveXMLIndex = p.savedOffset() + } + } + } + } + } + + // Find end element. + // Process sub-elements along the way. +Loop: + for { + var savedOffset int + if saveXML.IsValid() { + savedOffset = p.savedOffset() + } + tok, err := p.Token() + if err != nil { + return err + } + switch t := tok.(type) { + case StartElement: + consumed := false + if sv.IsValid() { + consumed, err = p.unmarshalPath(tinfo, sv, nil, &t) + if err != nil { + return err + } + if !consumed && saveAny.IsValid() { + consumed = true + if err := p.unmarshal(saveAny, &t); err != nil { + return err + } + } + } + if !consumed { + if err := p.Skip(); err != nil { + return err + } + } + + case EndElement: + if saveXML.IsValid() { + saveXMLData = p.saved.Bytes()[saveXMLIndex:savedOffset] + if saveXMLIndex == 0 { + p.saved = nil + } + } + break Loop + + case CharData: + if saveData.IsValid() { + data = append(data, t...) + } + + case Comment: + if saveComment.IsValid() { + comment = append(comment, t...) + } + } + } + + if saveData.IsValid() && saveData.CanInterface() && saveData.Type().Implements(textUnmarshalerType) { + if err := saveData.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return err + } + saveData = reflect.Value{} + } + + if saveData.IsValid() && saveData.CanAddr() { + pv := saveData.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + if err := pv.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return err + } + saveData = reflect.Value{} + } + } + + if err := copyValue(saveData, data); err != nil { + return err + } + + switch t := saveComment; t.Kind() { + case reflect.String: + t.SetString(string(comment)) + case reflect.Slice: + t.Set(reflect.ValueOf(comment)) + } + + switch t := saveXML; t.Kind() { + case reflect.String: + t.SetString(string(saveXMLData)) + case reflect.Slice: + t.Set(reflect.ValueOf(saveXMLData)) + } + + return nil +} + +func copyValue(dst reflect.Value, src []byte) (err error) { + dst0 := dst + + if dst.Kind() == reflect.Ptr { + if dst.IsNil() { + dst.Set(reflect.New(dst.Type().Elem())) + } + dst = dst.Elem() + } + + // Save accumulated data. + switch dst.Kind() { + case reflect.Invalid: + // Probably a comment. + default: + return errors.New("cannot unmarshal into " + dst0.Type().String()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits()) + if err != nil { + return err + } + dst.SetInt(itmp) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + utmp, err := strconv.ParseUint(string(src), 10, dst.Type().Bits()) + if err != nil { + return err + } + dst.SetUint(utmp) + case reflect.Float32, reflect.Float64: + ftmp, err := strconv.ParseFloat(string(src), dst.Type().Bits()) + if err != nil { + return err + } + dst.SetFloat(ftmp) + case reflect.Bool: + value, err := strconv.ParseBool(strings.TrimSpace(string(src))) + if err != nil { + return err + } + dst.SetBool(value) + case reflect.String: + dst.SetString(string(src)) + case reflect.Slice: + if len(src) == 0 { + // non-nil to flag presence + src = []byte{} + } + dst.SetBytes(src) + } + return nil +} + +// unmarshalPath walks down an XML structure looking for wanted +// paths, and calls unmarshal on them. +// The consumed result tells whether XML elements have been consumed +// from the Decoder until start's matching end element, or if it's +// still untouched because start is uninteresting for sv's fields. +func (p *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) { + recurse := false +Loop: + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) || finfo.xmlns != "" && finfo.xmlns != start.Name.Space { + continue + } + for j := range parents { + if parents[j] != finfo.parents[j] { + continue Loop + } + } + if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local { + // It's a perfect match, unmarshal the field. + return true, p.unmarshal(finfo.value(sv), start) + } + if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local { + // It's a prefix for the field. Break and recurse + // since it's not ok for one field path to be itself + // the prefix for another field path. + recurse = true + + // We can reuse the same slice as long as we + // don't try to append to it. + parents = finfo.parents[:len(parents)+1] + break + } + } + if !recurse { + // We have no business with this element. + return false, nil + } + // The element is not a perfect match for any field, but one + // or more fields have the path to this element as a parent + // prefix. Recurse and attempt to match these. + for { + var tok Token + tok, err = p.Token() + if err != nil { + return true, err + } + switch t := tok.(type) { + case StartElement: + consumed2, err := p.unmarshalPath(tinfo, sv, parents, &t) + if err != nil { + return true, err + } + if !consumed2 { + if err := p.Skip(); err != nil { + return true, err + } + } + case EndElement: + return true, nil + } + } +} + +// Skip reads tokens until it has consumed the end element +// matching the most recent start element already consumed. +// It recurs if it encounters a start element, so it can be used to +// skip nested structures. +// It returns nil if it finds an end element matching the start +// element; otherwise it returns an error describing the problem. +func (d *Decoder) Skip() error { + for { + tok, err := d.Token() + if err != nil { + return err + } + switch tok.(type) { + case StartElement: + if err := d.Skip(); err != nil { + return err + } + case EndElement: + return nil + } + } +} diff --git a/control/webdav/internal/xml/typeinfo.go b/control/webdav/internal/xml/typeinfo.go new file mode 100644 index 00000000..fdde288b --- /dev/null +++ b/control/webdav/internal/xml/typeinfo.go @@ -0,0 +1,371 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xml + +import ( + "fmt" + "reflect" + "strings" + "sync" +) + +// typeInfo holds details for the xml representation of a type. +type typeInfo struct { + xmlname *fieldInfo + fields []fieldInfo +} + +// fieldInfo holds details for the xml representation of a single field. +type fieldInfo struct { + idx []int + name string + xmlns string + flags fieldFlags + parents []string +} + +type fieldFlags int + +const ( + fElement fieldFlags = 1 << iota + fAttr + fCharData + fInnerXml + fComment + fAny + + fOmitEmpty + + fMode = fElement | fAttr | fCharData | fInnerXml | fComment | fAny +) + +var tinfoMap = make(map[reflect.Type]*typeInfo) +var tinfoLock sync.RWMutex + +var nameType = reflect.TypeOf(Name{}) + +// getTypeInfo returns the typeInfo structure with details necessary +// for marshalling and unmarshalling typ. +func getTypeInfo(typ reflect.Type) (*typeInfo, error) { + tinfoLock.RLock() + tinfo, ok := tinfoMap[typ] + tinfoLock.RUnlock() + if ok { + return tinfo, nil + } + tinfo = &typeInfo{} + if typ.Kind() == reflect.Struct && typ != nameType { + n := typ.NumField() + for i := 0; i < n; i++ { + f := typ.Field(i) + if f.PkgPath != "" || f.Tag.Get("xml") == "-" { + continue // Private field + } + + // For embedded structs, embed its fields. + if f.Anonymous { + t := f.Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.Kind() == reflect.Struct { + inner, err := getTypeInfo(t) + if err != nil { + return nil, err + } + if tinfo.xmlname == nil { + tinfo.xmlname = inner.xmlname + } + for _, finfo := range inner.fields { + finfo.idx = append([]int{i}, finfo.idx...) + if err := addFieldInfo(typ, tinfo, &finfo); err != nil { + return nil, err + } + } + continue + } + } + + finfo, err := structFieldInfo(typ, &f) + if err != nil { + return nil, err + } + + if f.Name == "XMLName" { + tinfo.xmlname = finfo + continue + } + + // Add the field if it doesn't conflict with other fields. + if err := addFieldInfo(typ, tinfo, finfo); err != nil { + return nil, err + } + } + } + tinfoLock.Lock() + tinfoMap[typ] = tinfo + tinfoLock.Unlock() + return tinfo, nil +} + +// structFieldInfo builds and returns a fieldInfo for f. +func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, error) { + finfo := &fieldInfo{idx: f.Index} + + // Split the tag from the xml namespace if necessary. + tag := f.Tag.Get("xml") + if i := strings.Index(tag, " "); i >= 0 { + finfo.xmlns, tag = tag[:i], tag[i+1:] + } + + // Parse flags. + tokens := strings.Split(tag, ",") + if len(tokens) == 1 { + finfo.flags = fElement + } else { + tag = tokens[0] + for _, flag := range tokens[1:] { + switch flag { + case "attr": + finfo.flags |= fAttr + case "chardata": + finfo.flags |= fCharData + case "innerxml": + finfo.flags |= fInnerXml + case "comment": + finfo.flags |= fComment + case "any": + finfo.flags |= fAny + case "omitempty": + finfo.flags |= fOmitEmpty + } + } + + // Validate the flags used. + valid := true + switch mode := finfo.flags & fMode; mode { + case 0: + finfo.flags |= fElement + case fAttr, fCharData, fInnerXml, fComment, fAny: + if f.Name == "XMLName" || tag != "" && mode != fAttr { + valid = false + } + default: + // This will also catch multiple modes in a single field. + valid = false + } + if finfo.flags&fMode == fAny { + finfo.flags |= fElement + } + if finfo.flags&fOmitEmpty != 0 && finfo.flags&(fElement|fAttr) == 0 { + valid = false + } + if !valid { + return nil, fmt.Errorf("xml: invalid tag in field %s of type %s: %q", + f.Name, typ, f.Tag.Get("xml")) + } + } + + // Use of xmlns without a name is not allowed. + if finfo.xmlns != "" && tag == "" { + return nil, fmt.Errorf("xml: namespace without name in field %s of type %s: %q", + f.Name, typ, f.Tag.Get("xml")) + } + + if f.Name == "XMLName" { + // The XMLName field records the XML element name. Don't + // process it as usual because its name should default to + // empty rather than to the field name. + finfo.name = tag + return finfo, nil + } + + if tag == "" { + // If the name part of the tag is completely empty, get + // default from XMLName of underlying struct if feasible, + // or field name otherwise. + if xmlname := lookupXMLName(f.Type); xmlname != nil { + finfo.xmlns, finfo.name = xmlname.xmlns, xmlname.name + } else { + finfo.name = f.Name + } + return finfo, nil + } + + if finfo.xmlns == "" && finfo.flags&fAttr == 0 { + // If it's an element no namespace specified, get the default + // from the XMLName of enclosing struct if possible. + if xmlname := lookupXMLName(typ); xmlname != nil { + finfo.xmlns = xmlname.xmlns + } + } + + // Prepare field name and parents. + parents := strings.Split(tag, ">") + if parents[0] == "" { + parents[0] = f.Name + } + if parents[len(parents)-1] == "" { + return nil, fmt.Errorf("xml: trailing '>' in field %s of type %s", f.Name, typ) + } + finfo.name = parents[len(parents)-1] + if len(parents) > 1 { + if (finfo.flags & fElement) == 0 { + return nil, fmt.Errorf("xml: %s chain not valid with %s flag", tag, strings.Join(tokens[1:], ",")) + } + finfo.parents = parents[:len(parents)-1] + } + + // If the field type has an XMLName field, the names must match + // so that the behavior of both marshalling and unmarshalling + // is straightforward and unambiguous. + if finfo.flags&fElement != 0 { + ftyp := f.Type + xmlname := lookupXMLName(ftyp) + if xmlname != nil && xmlname.name != finfo.name { + return nil, fmt.Errorf("xml: name %q in tag of %s.%s conflicts with name %q in %s.XMLName", + finfo.name, typ, f.Name, xmlname.name, ftyp) + } + } + return finfo, nil +} + +// lookupXMLName returns the fieldInfo for typ's XMLName field +// in case it exists and has a valid xml field tag, otherwise +// it returns nil. +func lookupXMLName(typ reflect.Type) (xmlname *fieldInfo) { + for typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + if typ.Kind() != reflect.Struct { + return nil + } + for i, n := 0, typ.NumField(); i < n; i++ { + f := typ.Field(i) + if f.Name != "XMLName" { + continue + } + finfo, err := structFieldInfo(typ, &f) + if finfo.name != "" && err == nil { + return finfo + } + // Also consider errors as a non-existent field tag + // and let getTypeInfo itself report the error. + break + } + return nil +} + +func min(a, b int) int { + if a <= b { + return a + } + return b +} + +// addFieldInfo adds finfo to tinfo.fields if there are no +// conflicts, or if conflicts arise from previous fields that were +// obtained from deeper embedded structures than finfo. In the latter +// case, the conflicting entries are dropped. +// A conflict occurs when the path (parent + name) to a field is +// itself a prefix of another path, or when two paths match exactly. +// It is okay for field paths to share a common, shorter prefix. +func addFieldInfo(typ reflect.Type, tinfo *typeInfo, newf *fieldInfo) error { + var conflicts []int +Loop: + // First, figure all conflicts. Most working code will have none. + for i := range tinfo.fields { + oldf := &tinfo.fields[i] + if oldf.flags&fMode != newf.flags&fMode { + continue + } + if oldf.xmlns != "" && newf.xmlns != "" && oldf.xmlns != newf.xmlns { + continue + } + minl := min(len(newf.parents), len(oldf.parents)) + for p := 0; p < minl; p++ { + if oldf.parents[p] != newf.parents[p] { + continue Loop + } + } + if len(oldf.parents) > len(newf.parents) { + if oldf.parents[len(newf.parents)] == newf.name { + conflicts = append(conflicts, i) + } + } else if len(oldf.parents) < len(newf.parents) { + if newf.parents[len(oldf.parents)] == oldf.name { + conflicts = append(conflicts, i) + } + } else { + if newf.name == oldf.name { + conflicts = append(conflicts, i) + } + } + } + // Without conflicts, add the new field and return. + if conflicts == nil { + tinfo.fields = append(tinfo.fields, *newf) + return nil + } + + // If any conflict is shallower, ignore the new field. + // This matches the Go field resolution on embedding. + for _, i := range conflicts { + if len(tinfo.fields[i].idx) < len(newf.idx) { + return nil + } + } + + // Otherwise, if any of them is at the same depth level, it's an error. + for _, i := range conflicts { + oldf := &tinfo.fields[i] + if len(oldf.idx) == len(newf.idx) { + f1 := typ.FieldByIndex(oldf.idx) + f2 := typ.FieldByIndex(newf.idx) + return &TagPathError{typ, f1.Name, f1.Tag.Get("xml"), f2.Name, f2.Tag.Get("xml")} + } + } + + // Otherwise, the new field is shallower, and thus takes precedence, + // so drop the conflicting fields from tinfo and append the new one. + for c := len(conflicts) - 1; c >= 0; c-- { + i := conflicts[c] + copy(tinfo.fields[i:], tinfo.fields[i+1:]) + tinfo.fields = tinfo.fields[:len(tinfo.fields)-1] + } + tinfo.fields = append(tinfo.fields, *newf) + return nil +} + +// A TagPathError represents an error in the unmarshalling process +// caused by the use of field tags with conflicting paths. +type TagPathError struct { + Struct reflect.Type + Field1, Tag1 string + Field2, Tag2 string +} + +func (e *TagPathError) Error() string { + return fmt.Sprintf("%s field %q with tag %q conflicts with field %q with tag %q", e.Struct, e.Field1, e.Tag1, e.Field2, e.Tag2) +} + +// value returns v's field value corresponding to finfo. +// It's equivalent to v.FieldByIndex(finfo.idx), but initializes +// and dereferences pointers as necessary. +func (finfo *fieldInfo) value(v reflect.Value) reflect.Value { + for i, x := range finfo.idx { + if i > 0 { + t := v.Type() + if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + } + v = v.Field(x) + } + return v +} diff --git a/control/webdav/internal/xml/xml.go b/control/webdav/internal/xml/xml.go new file mode 100644 index 00000000..7d88dac7 --- /dev/null +++ b/control/webdav/internal/xml/xml.go @@ -0,0 +1,1998 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xml implements a simple XML 1.0 parser that +// understands XML name spaces. +package xml + +// References: +// Annotated XML spec: http://www.xml.com/axml/testaxml.htm +// XML name spaces: http://www.w3.org/TR/REC-xml-names/ + +// TODO(rsc): +// Test error handling. + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// A SyntaxError represents a syntax error in the XML input stream. +type SyntaxError struct { + Msg string + Line int +} + +func (e *SyntaxError) Error() string { + return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg +} + +// A Name represents an XML name (Local) annotated with a name space +// identifier (Space). In tokens returned by Decoder.Token, the Space +// identifier is given as a canonical URL, not the short prefix used in +// the document being parsed. +// +// As a special case, XML namespace declarations will use the literal +// string "xmlns" for the Space field instead of the fully resolved URL. +// See Encoder.EncodeToken for more information on namespace encoding +// behaviour. +type Name struct { + Space, Local string +} + +// isNamespace reports whether the name is a namespace-defining name. +func (name Name) isNamespace() bool { + return name.Local == "xmlns" || name.Space == "xmlns" +} + +// An Attr represents an attribute in an XML element (Name=Value). +type Attr struct { + Name Name + Value string +} + +// A Token is an interface holding one of the token types: +// StartElement, EndElement, CharData, Comment, ProcInst, or Directive. +type Token interface{} + +// A StartElement represents an XML start element. +type StartElement struct { + Name Name + Attr []Attr +} + +func (e StartElement) Copy() StartElement { + attrs := make([]Attr, len(e.Attr)) + copy(attrs, e.Attr) + e.Attr = attrs + return e +} + +// End returns the corresponding XML end element. +func (e StartElement) End() EndElement { + return EndElement{e.Name} +} + +// setDefaultNamespace sets the namespace of the element +// as the default for all elements contained within it. +func (e *StartElement) setDefaultNamespace() { + if e.Name.Space == "" { + // If there's no namespace on the element, don't + // set the default. Strictly speaking this might be wrong, as + // we can't tell if the element had no namespace set + // or was just using the default namespace. + return + } + // Don't add a default name space if there's already one set. + for _, attr := range e.Attr { + if attr.Name.Space == "" && attr.Name.Local == "xmlns" { + return + } + } + e.Attr = append(e.Attr, Attr{ + Name: Name{ + Local: "xmlns", + }, + Value: e.Name.Space, + }) +} + +// An EndElement represents an XML end element. +type EndElement struct { + Name Name +} + +// A CharData represents XML character data (raw text), +// in which XML escape sequences have been replaced by +// the characters they represent. +type CharData []byte + +func makeCopy(b []byte) []byte { + b1 := make([]byte, len(b)) + copy(b1, b) + return b1 +} + +func (c CharData) Copy() CharData { return CharData(makeCopy(c)) } + +// A Comment represents an XML comment of the form . +// The bytes do not include the comment markers. +type Comment []byte + +func (c Comment) Copy() Comment { return Comment(makeCopy(c)) } + +// A ProcInst represents an XML processing instruction of the form +type ProcInst struct { + Target string + Inst []byte +} + +func (p ProcInst) Copy() ProcInst { + p.Inst = makeCopy(p.Inst) + return p +} + +// A Directive represents an XML directive of the form . +// The bytes do not include the markers. +type Directive []byte + +func (d Directive) Copy() Directive { return Directive(makeCopy(d)) } + +// CopyToken returns a copy of a Token. +func CopyToken(t Token) Token { + switch v := t.(type) { + case CharData: + return v.Copy() + case Comment: + return v.Copy() + case Directive: + return v.Copy() + case ProcInst: + return v.Copy() + case StartElement: + return v.Copy() + } + return t +} + +// A Decoder represents an XML parser reading a particular input stream. +// The parser assumes that its input is encoded in UTF-8. +type Decoder struct { + // Strict defaults to true, enforcing the requirements + // of the XML specification. + // If set to false, the parser allows input containing common + // mistakes: + // * If an element is missing an end tag, the parser invents + // end tags as necessary to keep the return values from Token + // properly balanced. + // * In attribute values and character data, unknown or malformed + // character entities (sequences beginning with &) are left alone. + // + // Setting: + // + // d.Strict = false; + // d.AutoClose = HTMLAutoClose; + // d.Entity = HTMLEntity + // + // creates a parser that can handle typical HTML. + // + // Strict mode does not enforce the requirements of the XML name spaces TR. + // In particular it does not reject name space tags using undefined prefixes. + // Such tags are recorded with the unknown prefix as the name space URL. + Strict bool + + // When Strict == false, AutoClose indicates a set of elements to + // consider closed immediately after they are opened, regardless + // of whether an end element is present. + AutoClose []string + + // Entity can be used to map non-standard entity names to string replacements. + // The parser behaves as if these standard mappings are present in the map, + // regardless of the actual map content: + // + // "lt": "<", + // "gt": ">", + // "amp": "&", + // "apos": "'", + // "quot": `"`, + Entity map[string]string + + // CharsetReader, if non-nil, defines a function to generate + // charset-conversion readers, converting from the provided + // non-UTF-8 charset into UTF-8. If CharsetReader is nil or + // returns an error, parsing stops with an error. One of the + // the CharsetReader's result values must be non-nil. + CharsetReader func(charset string, input io.Reader) (io.Reader, error) + + // DefaultSpace sets the default name space used for unadorned tags, + // as if the entire XML stream were wrapped in an element containing + // the attribute xmlns="DefaultSpace". + DefaultSpace string + + r io.ByteReader + buf bytes.Buffer + saved *bytes.Buffer + stk *stack + free *stack + needClose bool + toClose Name + nextToken Token + nextByte int + ns map[string]string + err error + line int + offset int64 + unmarshalDepth int +} + +// NewDecoder creates a new XML parser reading from r. +// If r does not implement io.ByteReader, NewDecoder will +// do its own buffering. +func NewDecoder(r io.Reader) *Decoder { + d := &Decoder{ + ns: make(map[string]string), + nextByte: -1, + line: 1, + Strict: true, + } + d.switchToReader(r) + return d +} + +// Token returns the next XML token in the input stream. +// At the end of the input stream, Token returns nil, io.EOF. +// +// Slices of bytes in the returned token data refer to the +// parser's internal buffer and remain valid only until the next +// call to Token. To acquire a copy of the bytes, call CopyToken +// or the token's Copy method. +// +// Token expands self-closing elements such as
+// into separate start and end elements returned by successive calls. +// +// Token guarantees that the StartElement and EndElement +// tokens it returns are properly nested and matched: +// if Token encounters an unexpected end element, +// it will return an error. +// +// Token implements XML name spaces as described by +// http://www.w3.org/TR/REC-xml-names/. Each of the +// Name structures contained in the Token has the Space +// set to the URL identifying its name space when known. +// If Token encounters an unrecognized name space prefix, +// it uses the prefix as the Space rather than report an error. +func (d *Decoder) Token() (t Token, err error) { + if d.stk != nil && d.stk.kind == stkEOF { + err = io.EOF + return + } + if d.nextToken != nil { + t = d.nextToken + d.nextToken = nil + } else if t, err = d.rawToken(); err != nil { + return + } + + if !d.Strict { + if t1, ok := d.autoClose(t); ok { + d.nextToken = t + t = t1 + } + } + switch t1 := t.(type) { + case StartElement: + // In XML name spaces, the translations listed in the + // attributes apply to the element name and + // to the other attribute names, so process + // the translations first. + for _, a := range t1.Attr { + if a.Name.Space == "xmlns" { + v, ok := d.ns[a.Name.Local] + d.pushNs(a.Name.Local, v, ok) + d.ns[a.Name.Local] = a.Value + } + if a.Name.Space == "" && a.Name.Local == "xmlns" { + // Default space for untagged names + v, ok := d.ns[""] + d.pushNs("", v, ok) + d.ns[""] = a.Value + } + } + + d.translate(&t1.Name, true) + for i := range t1.Attr { + d.translate(&t1.Attr[i].Name, false) + } + d.pushElement(t1.Name) + t = t1 + + case EndElement: + d.translate(&t1.Name, true) + if !d.popElement(&t1) { + return nil, d.err + } + t = t1 + } + return +} + +const xmlURL = "http://www.w3.org/XML/1998/namespace" + +// Apply name space translation to name n. +// The default name space (for Space=="") +// applies only to element names, not to attribute names. +func (d *Decoder) translate(n *Name, isElementName bool) { + switch { + case n.Space == "xmlns": + return + case n.Space == "" && !isElementName: + return + case n.Space == "xml": + n.Space = xmlURL + case n.Space == "" && n.Local == "xmlns": + return + } + if v, ok := d.ns[n.Space]; ok { + n.Space = v + } else if n.Space == "" { + n.Space = d.DefaultSpace + } +} + +func (d *Decoder) switchToReader(r io.Reader) { + // Get efficient byte at a time reader. + // Assume that if reader has its own + // ReadByte, it's efficient enough. + // Otherwise, use bufio. + if rb, ok := r.(io.ByteReader); ok { + d.r = rb + } else { + d.r = bufio.NewReader(r) + } +} + +// Parsing state - stack holds old name space translations +// and the current set of open elements. The translations to pop when +// ending a given tag are *below* it on the stack, which is +// more work but forced on us by XML. +type stack struct { + next *stack + kind int + name Name + ok bool +} + +const ( + stkStart = iota + stkNs + stkEOF +) + +func (d *Decoder) push(kind int) *stack { + s := d.free + if s != nil { + d.free = s.next + } else { + s = new(stack) + } + s.next = d.stk + s.kind = kind + d.stk = s + return s +} + +func (d *Decoder) pop() *stack { + s := d.stk + if s != nil { + d.stk = s.next + s.next = d.free + d.free = s + } + return s +} + +// Record that after the current element is finished +// (that element is already pushed on the stack) +// Token should return EOF until popEOF is called. +func (d *Decoder) pushEOF() { + // Walk down stack to find Start. + // It might not be the top, because there might be stkNs + // entries above it. + start := d.stk + for start.kind != stkStart { + start = start.next + } + // The stkNs entries below a start are associated with that + // element too; skip over them. + for start.next != nil && start.next.kind == stkNs { + start = start.next + } + s := d.free + if s != nil { + d.free = s.next + } else { + s = new(stack) + } + s.kind = stkEOF + s.next = start.next + start.next = s +} + +// Undo a pushEOF. +// The element must have been finished, so the EOF should be at the top of the stack. +func (d *Decoder) popEOF() bool { + if d.stk == nil || d.stk.kind != stkEOF { + return false + } + d.pop() + return true +} + +// Record that we are starting an element with the given name. +func (d *Decoder) pushElement(name Name) { + s := d.push(stkStart) + s.name = name +} + +// Record that we are changing the value of ns[local]. +// The old value is url, ok. +func (d *Decoder) pushNs(local string, url string, ok bool) { + s := d.push(stkNs) + s.name.Local = local + s.name.Space = url + s.ok = ok +} + +// Creates a SyntaxError with the current line number. +func (d *Decoder) syntaxError(msg string) error { + return &SyntaxError{Msg: msg, Line: d.line} +} + +// Record that we are ending an element with the given name. +// The name must match the record at the top of the stack, +// which must be a pushElement record. +// After popping the element, apply any undo records from +// the stack to restore the name translations that existed +// before we saw this element. +func (d *Decoder) popElement(t *EndElement) bool { + s := d.pop() + name := t.Name + switch { + case s == nil || s.kind != stkStart: + d.err = d.syntaxError("unexpected end element ") + return false + case s.name.Local != name.Local: + if !d.Strict { + d.needClose = true + d.toClose = t.Name + t.Name = s.name + return true + } + d.err = d.syntaxError("element <" + s.name.Local + "> closed by ") + return false + case s.name.Space != name.Space: + d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space + + "closed by in space " + name.Space) + return false + } + + // Pop stack until a Start or EOF is on the top, undoing the + // translations that were associated with the element we just closed. + for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF { + s := d.pop() + if s.ok { + d.ns[s.name.Local] = s.name.Space + } else { + delete(d.ns, s.name.Local) + } + } + + return true +} + +// If the top element on the stack is autoclosing and +// t is not the end tag, invent the end tag. +func (d *Decoder) autoClose(t Token) (Token, bool) { + if d.stk == nil || d.stk.kind != stkStart { + return nil, false + } + name := strings.ToLower(d.stk.name.Local) + for _, s := range d.AutoClose { + if strings.ToLower(s) == name { + // This one should be auto closed if t doesn't close it. + et, ok := t.(EndElement) + if !ok || et.Name.Local != name { + return EndElement{d.stk.name}, true + } + break + } + } + return nil, false +} + +var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method") + +// RawToken is like Token but does not verify that +// start and end elements match and does not translate +// name space prefixes to their corresponding URLs. +func (d *Decoder) RawToken() (Token, error) { + if d.unmarshalDepth > 0 { + return nil, errRawToken + } + return d.rawToken() +} + +func (d *Decoder) rawToken() (Token, error) { + if d.err != nil { + return nil, d.err + } + if d.needClose { + // The last element we read was self-closing and + // we returned just the StartElement half. + // Return the EndElement half now. + d.needClose = false + return EndElement{d.toClose}, nil + } + + b, ok := d.getc() + if !ok { + return nil, d.err + } + + if b != '<' { + // Text section. + d.ungetc(b) + data := d.text(-1, false) + if data == nil { + return nil, d.err + } + return CharData(data), nil + } + + if b, ok = d.mustgetc(); !ok { + return nil, d.err + } + switch b { + case '/': + // ' { + d.err = d.syntaxError("invalid characters between ") + return nil, d.err + } + return EndElement{name}, nil + + case '?': + // ' { + break + } + b0 = b + } + data := d.buf.Bytes() + data = data[0 : len(data)-2] // chop ?> + + if target == "xml" { + content := string(data) + ver := procInst("version", content) + if ver != "" && ver != "1.0" { + d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver) + return nil, d.err + } + enc := procInst("encoding", content) + if enc != "" && enc != "utf-8" && enc != "UTF-8" { + if d.CharsetReader == nil { + d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc) + return nil, d.err + } + newr, err := d.CharsetReader(enc, d.r.(io.Reader)) + if err != nil { + d.err = fmt.Errorf("xml: opening charset %q: %v", enc, err) + return nil, d.err + } + if newr == nil { + panic("CharsetReader returned a nil Reader for charset " + enc) + } + d.switchToReader(newr) + } + } + return ProcInst{target, data}, nil + + case '!': + // ' { + break + } + b0, b1 = b1, b + } + data := d.buf.Bytes() + data = data[0 : len(data)-3] // chop --> + return Comment(data), nil + + case '[': // . + data := d.text(-1, true) + if data == nil { + return nil, d.err + } + return CharData(data), nil + } + + // Probably a directive: , , etc. + // We don't care, but accumulate for caller. Quoted angle + // brackets do not count for nesting. + d.buf.Reset() + d.buf.WriteByte(b) + inquote := uint8(0) + depth := 0 + for { + if b, ok = d.mustgetc(); !ok { + return nil, d.err + } + if inquote == 0 && b == '>' && depth == 0 { + break + } + HandleB: + d.buf.WriteByte(b) + switch { + case b == inquote: + inquote = 0 + + case inquote != 0: + // in quotes, no special action + + case b == '\'' || b == '"': + inquote = b + + case b == '>' && inquote == 0: + depth-- + + case b == '<' && inquote == 0: + // Look for + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-brands-400.ttf b/static/lib/fontawesome@5.15.4/webfonts/fa-brands-400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8d75deddae520da95d3cf111f4ccbf3361074292 GIT binary patch literal 133988 zcmeFacbpu>nLpgsIrq%;O!wrtGqZVTCvK2dtJNxja+Z)#Kp?;f69kqqLF6cd0NW(n z!T}se#+btxV}Uu&hcV}K;A|gYIb+WDPui6bPP^~7dUl1t_ul7s|GuAhwB21@U0q#W z_0$u-&r>aiFbrcbdl-&cHgDdl#UJnA_6Eah3y>S1KRS0F(@y>!=dCzTE?wDE?)})B z0fr&#aK7cVom$t=khbpZ_|py@suRCNlUs_jlA6#Cgk^J9q6qZ&ds(&Yxl!sq>rKaZhw|xjx9&Xso_){!m?4L7E?j%w2QS=Jc>aS|Fy!a~h6!zA z@NVSf>sk(-r81kX8Aln7#cd4pdg=1%qcZuY$w%31$w6euO!G2s!ry_(0}R9N!S%!J zwKV6%ANj6V=DXZX25*NSy_0yQhUqDOJoy8;jS-N&h@64*`BTTEOoX|H-XL&ZxqsL# zJ7ey4X3s(Coj1KUbd#5vRVd`OfDDk&Bb{c*bW@oxc@NjwVJ1xuFa#Tev_+3z8smne zfIQmB2)oBSde^+`ILDFqUf=+(qvKg-a-3enMtjUh@0mJ3ex&8G$>b2O(XCk?J;vx> z`ry=aa4#)OKw<1KW0F0Slk__4^YYl~`)C~~Cz4@C^72sLD>v-bt$5GEedIjv+E!?=GBj@anE?67xK zr{84hh!{3t_`Y0$Jc{?pI%t{wDfm!En@vt7;mROCtQ z@bUK1XUfy>j5O_|=DRbr9aD85V8T=FqIrLwDg!#6obc|)J>K==Q5D ztlyhg&HGT#uvf3irl+1o>!7qgz2Tf4#jy=fVL-|qj97nHTy*3>P-gAyJC`)OD(x~Y5 zIogf1jlAhGqh*@o*(~p(UekLAdhed;XQF@hFai3G@8&hrUfE&BWrrCSbz$@7lk1gb zCjUBBmpAul9_pcOc$XgN9Q%YfM`&9VTnl;gj=tj_@U>yadoSd3UR#GfS)d~w!gYEN z#>3+)G)>=&wj(k945aBeNZy9)Uj76lGT>QLTb%LaD1QVwG!J$&ckyAI!b_)~|!boieRKYRG)!~b#k_lN&<_~;lnri__m&RBV@F*Y=|XzbLn ztz#b;J9q57vCGG<8oO!i&au149vFLM?1{0b#$Fuz+1MLn2gf&#Uo?K%_@41=$8Q+F zb^H_K_l$pf{Bz@vkAHLg!1xQ}-x+^-{QKjtjsJZ7*W-T}|3Bm7<9{BXI3gS|j<`oM zM{-Ack1Rg2;>g+~>yP~S$ZwAP`DpOy?MFX#^s`65aP;w`UpxBj(HD=teDvRr9zJ^P z=wIHp-VVGy>+O-ZKl%2fZ@={R%WuDSj6c?UY}2ui9J}_|jmP#L+js2lV_!M;)nm^b zd-2#0kG*>A7sr0}&dhg4-ucu!54`izJ3n~m7w^0YZI5|RpRGRlp@Y{Sy3*^jyAS#&)95E*;x5cFouwV;>*;{MZ-A9z&nKF!tlI*S$VFbA0#s72{W< z&u$*yH-7i{C&%v}e_;Fx^x3z^UmSl4ef9(N*)PU_JN_s1*-`Wvdqg_oKN3NoGhg1KRdNcKG z>dDj-sgI@Zu&MT|Bv|t^F{NY%@@pXo8K~@HJ>q`G9Nb|H6Jk_ zGQVto#{86dhk2WMrFpq|nR&js(>&We%Uo)nY%Vlsnw@5c*>1L(t!BcEn=#Wi1EypO zCT|ksZR1Vjx5jUbvyIKhCS#+q!B}UkF;*L^j1|UmW0|qkSZthZoMbFC<{5L1ImU=F z+ZZ-x8Z(SOqh?f%UZZ667~O_#ScYb(`mOqv`X2o}ZCra(`?YpZ`w#8M+V`{f*2R^L?rO?^fEmU@@EQyozYYC?^wt{PH(%3qbgDC5do${WgS z%8!&EDpxC4DMckM|6P7tepCKsbIxM6{{O%KMGp}0J&)Pp9?x6=dwkDt`r>;s|37>3 zH0dT+k*CR?cAug#O^Ha~^SyxGnB=;dFRe_=WJ1$h^oi(Z1*z(VL=A#=2uq#@YBt{I>WjiO%Fu z^6AvF)c!P^J|q1~rkq)oU6#E)`$q1bmO#s!`P&Mm!kWUT3U3wH6<=*-S}$&Wtu5Vl zUq^SxTU~E;|Db12&!0-?mVVHCL+_L2S1W8~LFF^mc&)E?aqYMDq52c`HyX*tQ2%!Z z0t2@U`UW=+J~jC38SxprXB?cFoq5yH14D1kdVbc#@VenI%szAWkr8=h!N|6eSLTe& z`Oc_1+By2z-1OW9bDy6VowsJ*?s;FDH#UFC{JRz;7kqpnv+&ZB)RXQyxqR}jMZQJb z7VlpC^pe1mmzD;WKC<+eOaHd)FU!wa{^p8{S28Q>D=%HOf3>;#;?;-Ne1FZ~)}FKW zm342gKYRVpHau~PdCHno9@zNA#=mX4Y?FEuMYuIjhe3_|Bo77wmlF z+@W(fo_oW&W9L6~!8;drUijLs=&oJ6etXf#hYs#Od-qcxc0T;lC4oyuFM0bTH+|&I zOMRC%l2RPv&;F*@42FI#l}6OSN2``$W`;M+J4pJS0}HzC+>Xp&bK~x+sCUPzvV9TuG{YZ(>>0;?0q-g_l5gj z{^U!aUiRtFeEPutd-gwZ|El}1x&NupuKL{A=jG4$eg5pvKlS+^JaE;6eGi`Z;Mf;_ z^u@j}?*8IWzBK%$+rRX}mxEtE^UDVw3Ow}4!zVrbsfWiNx%|;(kG}F)`LSodvf(R7 z9#231!dIVtV%w94zA^HRH=pVICjacvv+o?Z;lOvEW1p)(cinS;d;aX_fA;M?-+tl+ z^M!#I&U@j>f4=0OfAFu{UP^!O+3$CL|C)bi|NYJ%_x*UoPdb0H_CQFLt?XP7m31QVP-9P#3M>zxH#_Z8mMkvCYk2 z*Rt-;Y%-Z{Tpf<5<6$9r+R&-Bw0hNtCyo&Pyo*1)^B6gqNInuv&??^CyZ1-o?$HMx z2s@$h%Dd*C;ux;#o^r}5{vW2ghwJg3yU2lw)jLi<{q%{mi4p~Ek;$KvZ{a;-%nXLf zS3JrIiJ$~ZAlaM3Gs}tW zD9?|wBFA>lB}61`ZP<~ybUYxDCl8Y6&`y=fFib#0 zF7U@2#iR`6h_NPLA>-t6jK0O#jElaJT&aiTijB%FVv$ONbBj5lQIyD7GFkiQ#NchW z4JQ8i^_>r|{lq8MK1{mX+t-ej%ipS$Z@Hyh*?G>si60hjzvTAYZ}%*$sdq6!S)G7$ zlZ28)wot=Mm3s3Tep?pXcr+eka!dy( z9Mp}$_Ncqz1nHwGhbT}^P%pcVSguzKSut3jIyOKUe%k$LyC01w^=h%36boLXB{4`D zhEoO;d8sp%>P$T@ii+dA&*v!9iI0z#N~5Ju`*hu>og0kDgA@Ddo-D;wEp-Gp20OxG z%-N}Q=_o2mbuM^M6|}AwQAufZyM}tK+mBbWB^aN0gVs@^RfNM{eO|iMq^TqjuV0eu zF$#I`Ro4kx1jEoxX5kfvNTp01%4R|H)mfxoDJL=R7w%!%D^1rQW3`PNRW=%M$@v-^ z^SkDiEW5{a15sApNOnEM%iP0(aEp1_N6eP+#Ix819^qu}A)5CQ+V=u@`Zvhe!CzXK zE~by!!khu^)0X^nJ{9Y|<%&Na098+McJw5&%Dor_sb0jmNJFFu`fpw?NL57}T%OFa{Anh~PW*eG6;#s0JIR8rdAu?16KX_} zm4GB?!_h9u7nNOA5gV*&Dz?D;STTqR#1R`aT?vLIS>^PilgzWkjXI~Asv45Wx{2FT z59R6l|GxIGqcz| zWH!?VNwkVNojISm1Z}8*IZKp%6l>rh80|_40!b?5vb|Xl3Y~=D9Q8)7#Yqr|B@`_d zpf_N?mfc#FvU#akuekLZQXZ=T0n$245`ukeRmD!1>hIemd)XB-o0}y!65u5ar5qO!_ zlWpW|atHY&c@V?tP5+RKHwPPd&k?;_%3;#E5P6V^G({6VBQp@MQ(j2sSe@=r{5ehquFDaKHzY; zC&_|rr*7;ZS+`jM9zy=k@gZWfLKxgwjBqL#7f&KkDkMS=L?*0DcmbLp8zO=N<&O13 zA!TLOL<(94Q3Mh~c_MJE>y>9C1eyek0}n}|auE@AhXvLq4#zp~K8%GTbK=to=RJ+( z{>P{B?0^5XsD%0b?xU_uEAmp=$FY*+mPi-J-7U*$!fLFXZ*OanS)IgWNmLa5CyGdL zG?o&n78O~gQ!x}plx`o42ZUK)cQ~7noJ<12(bgC*hw2(uqUBQ|;Y7v0I?i{f~oi!ovs`A$Zt{ zUGx4?(BAVjI^fgKV)^L-zg1GzfWqfUG{@FiRgtt@z@O9F&{u|{8ZyD*c~y-?c3T{$ z@NpeItF-!6Wj7aAI7w6$AE$6!YfDLv@O(t?F@niNSeAo6UYbB38p;=O0}d2AnmhnK z>Hw1k7r~^4GDnqWP;zK$V$^H?O0d_n$sl+RkU5Rb*KgiDs^ORF?3~%Tj#WF8`9BpO zAKi=#WCMr1&J@{1G_?wCXj=bm>S`LE;z_Z}Ov;_961ew)2Y&XKzg%|NiDD-_qXNO5K!;q2E)wA-Ihq%%`rIcq^makDd8*4zLYi`plD4moi@G>a5dWk%75>w?c;CyvoA~n?J9ee-=zsZ8{15(%CVu)oSfpc$41**ECg=C6-fw9+*6!2cmEq*PcyP2G@mHOCoyYy7?pXqPlFJMuI*$oPb@c z4D-aYlYDZvsEMqZw*0>CQx7w*R-|)~CTPxk>?=RSXa-7}Kj>64OS&hU^3jQ3M)Ub7Nk;RRdDlN13%Rjv_r)A1wr%V2g2_y2VjnFu zbpvVj3NX;OHDCl!U>vi|TxKz|n%M;1b0>2Va~Z{>8lX4IF><|B^MPOorBTHLii9W0 zF)S`Pp*W=~(GpZY@zfV+5U^SjFkRRt%m7WHX?;3V=i=14$5E%!)Iy!MQm4y5M940V z1CHYe!gf~Ra5(uQmgpRNr@|8cbQb2t>4M6!;7UZ4WSQkp;vzxA2pTDhxfq*m!?4XQ zUOMIFFY=^(2GQkm+8zj66oYo){HWr5Gha*Aic z&nF&b_pFaZ(i*GFA}?XS)9p;yCt*a%g_tC)+B&mn zIrKzv3i>EhKrL4Ux&*qYRo$kof|spOqzMNXmmkk35{0fpESXD?cuQa~mmAE^N~HqY zb9ywIh({xOHl0jZX7W>MVniartP{;Dg~B-(UG(K$yDq-CGdI}MGB~%`8nTO$U5v$G zWPkaLR-apJJtGi`Mi$LW=4P*jX?LQ`wP^p7_svBCFe}V&ks4Z}TktgA0%X7Aia@gAN3_?F3|_$2M&{BnKTko@$j=)|8~rOuD8|%!XRJ6sfz>zpjn!KM}+Dv>B9H z!`1mvDI*M9fm{$;XSfC0YcLWg$$?c}f~SKV^st=V@s?5?vXP^5$}{X>`-RYd(@2fi zrW*&exvi;qtfMk(){P$UGWF!U7W5Qm3gzy`g1ex907yZ9P`TKAh6S380}=g)KCz+l zho-?HygBU}3Bw2@oa#eKHbKaK!?ulyJ#@c=%<-pPH|>z&Ot+hn$nYGWtNXyJ_fHog zC^)g_)mO*el7v*%7#OMkdrh8RtcGHL>&f9 z4k(`$!7v5r8?cW!;N{4HRpmWcLN4?&ItEk+MkE;GpL%fO^;eVr8?YWJm+vMsVK-9y z6_DVR3OY4`$ahKW!d>&$E!50~1G$XXuv!grJlF|WzJEWCYYGC`$j$RDe-Sk!|wM z?)4{3gY~=jy|VAX#+%KDk57Sz&6_vw*td_qCls5>AA&DG1#V|z7HnhAW-b5c9JfZCFR zyJi*%QY`>^XeQUJlsax`GMA%jyxX;rjAv_Z+_c(Ehk2l}_@)V-b5D}znJ24s%U!tDb3<6#it zCscS)2H|B0RvxcFZRkCFcdWcR!oswi6-=Wp(`k*{VJnq~Q$|q~UbDD-Dw2t}Iv_CJ z;d$K;hY_)OK#f6*WAzddWj1p4$}?}7cyQ|JDoCBm?F^m_+0Oep*zzowg?TE0$l(Vj!$oxFVF{@)JFRf%nvSt;{{Ss1Vpz<2ISDb9fe$2^oeP^v2fk& zMQh^@00nd?7noV;9_Y&04$tbM&$6RvLS)so9&q0-&r1x1=N<9YT4PS8sLQ;!AN)P@+CVcG0{2G|ft+Yv1>9cV0EJNsnsMc_xldz8EI9s#_ECPiYFjII?7 z0dI+m>pkudMo-S85PXY^S6VkbbNSk#c%Q~e1S7_|nU3MU&fZzkfR>9XNuG~eLHbf~ zf~9rGZ;+;_pt1r{WXEMi8&kvky-#}DbfAh544xy?GnN~4+=5OX9oSa#ld%TBIUlij`Z=Jl5A!cKB-UteFN z(f69)T6xxa`_C(v6Z5yvugB*|$nWd(`T*~J0Js1Ll)8msDmj0pFs0W5h^=| zsI8QtvKh}hi1(71611*m@Z&U5h_ZmWE#%rsH}AoRlm!EphBS8ZOuWD3NOZ<{o*qvw zCRtdvLu_G6PkY+V*>;Zf2b5S_x)F}Yt$MgC9G8RbvYG3RwD+_ZBE4BlE)KV5^-ds* z9Y(e_*3*+LB}+Zg?eym0O@)@0LJL3GV#j<6Abwu+MSQJ|*`;vAP56SU60{O-#O?l2 zt|W4tSjwe3f|3;MScAJ-3eCBK$b6N21im<6ERA}hgK#-Jhpm{QJ`wW0tyRwF>z%Q6 zaOI4xGrGvGp_aTMjQi|~w}?ZxEnQtRr~HU}$bR%#h++I0PAZZ{&aGJBytx#q%z}rH z?8$xdlf*9^)*lpWb-qVDjchd^+IaRqP7B*!2vtE1~k&a3^maj z2m%R|m!;&F%>k`-z{P6a1i*34X+T4+Q;!C9tQA9Lr(UKqrJEO}vNHtvgH(>x7fa&& zk=}^WtE^Kw$#3X{a}xr$%Ak3b8JzeEvDJ`i>zb$p{4py^h^t3@j%i3*$jb? zwN8F?&YV$LG_w3tpG2yJEL}ntFBS5w1FN=Bu^_9a0zM7_K>kXZ2(PFQj61DG2N z3CXZ!&}4>EKaD`3b|QU0uxl#p09{iSjXzLhlE9nF79hJcwP>H++4<%6A{;M?~RI zm+Fde$s$3~*ZloK?7zs?uUMc{fpj9jOM6(%Kkz%Kmehfg6#>JDz}YAXW7eS|csz8P z6M5Z6Stzk-LGFfD_l`Uq$+%H}89;>&`oq*)L>Cc-#5(bl=3+e*W`n6}&*ieEbW>(u<|AGhl1L@i;GZ zpvVDWu2VMbkRKA(7-h|gr{NMFRY*Sa$vD~18HAnKY+zE}#}Y}Ic=e7u&@cjg@c`C& z9e_WS5vU%~&CbLg0F$TqVOk|1RXvv#G^GYqX24RUuGcc{LrJ4Y)!JJ*V$DMcqq-`W zQFwuM__SfiyF1<6)KQ%`NAf=PLUo0DZ7ie%@{op`uICeU8?5Mizh*-)mtj#t=Lcc| z)S?PI92=eL5ca`A*pNvUu>~g>hQwq+mQbuiPE{1EVke@LfF~zqyAW%C-{{=QO058r zS=sQfM9~GJ+UMt_4snASj|b4t9Qye(%*_M?xtR~TAona)ta2iq1n6f-f2cU1d$9;Z zg7%a{X3f+G(q^~c-=jIb3E7<6ZS{%VaHv0C=}YJNgkA`6U!9dGEF*ycn3dCBoHY;T z35<>8xdpB@Z3amz)j_6ozG=R|_#4ooF#jnZ;E;amsi%TR@FUxzk3aPB$JobzL_U>$ z6=Mnh$qci@Adaj=;7kTm-X;daJRcAxL<)OgABqP;kzgc+<8l+x$z3 zg>RyFVD{{RUQSfm(yS#SJ1j1_-3*%3e^;+$IaOF4i>;=J;L7aog$u!PR7RQnCixn9 z4mx5KcHL#nN0|qh=i!XXlUd+A*<2w9_bWI}E=zs5NS5Ji=q-u16QV4IjxhL)SO6!= z(KN-Y(Z!zn4)*Uw)8Q2Vsz9tk1W6Y5pT~p%GEnT!bvS?qZlPWQcAZ5Y?#)WTm+B=* zE^1TaZqOFWfQTGg6##DxEP5r&)e-PPNzY?(XaKbpQOa&ML4A3u(MP-Q8Gmx-dzHlnD8P26pwg8 z*rB2tWnr#Zyv3Uc6oQYjl?|%8DzgeF8XAyYIA3`#(xQjUss0%55`0`PE(l_t7vvZ( z8MYz{LLg#D7K>Jf5d=fw7gY%$xFsCZd7#dMXh#f<;|-OFrXUHD53r6Oo?{3MRTMNg z98}VwNuItUPzyc4>J%rIUsm}=B&91@{}j@Qm}>0priUuT9J$B z{d4q!-5OfbOJcLHTQQ?&nH316S?)`D(_OqWcyf1jLr{ZxM)hOLFP{Uij!}DU$`&nR z+E5#fvTA6>*r<)>S<6&~p>C6Dh=78aNr?veQfR}oCL!m@7u}KW0>Hi1yZPg(f9aZY zil8|Gqdge0HPb)3b~dNT0VSfQ1ix;C?LgeHRnwY(XR^>e;_|y!huq_-3%c6+Ll{c< z#2ueMV1`qzZCU`)JfZ|-K;Se*w@kn3H)7OO^WN)8vWt9^apE-Je{O}+8Hb8>^5$+#1b(fwYZwo>zXyXSn`a+<`B z?4Q2=<;z;#%*4YJ^a9;|JzzXuNg-44V2ov4;}lQQbcB0YOkK zH>2wXUC+8ExXbxd6uDdqr&LWb4T8WuO-;Mf-Be!+Fln}mxPbXMq2em&mZ)^V+fhkH zjsGb;#3M8e0`;pyS(u3xAs|Ojp$gJ)PDo>%uoF)@tiK@x^+! zv}C)?;Gm}Qp_x9IRS5aqq1Qax?P9x6Cvij`#7(6@n(2o+Sw4w=yvc1Pr{K;h>?J%3u>XF zbGGr#)mJTAFr$+rB4^E5Xak2I;kn__snh;C$LLdcewT|wy zR#qf&lTeoW~G|nHIcsUW*lv*qnm1V>j$ck#Kaxm!UWCegNG*)hkUp@i! zIsjh7*ucX*P0-F3!4RQ;h#o#q!;oKHF*0!Ry0%$;U9&W8R#)SSkrnGMChm%B({nd$ zyvdpfCgaPyyO+n4>(bY*_@s5y#trb-PfossfQl!XrQl*F3nhdq<6u!f<;; zu_R7S#xhZxZK>u$SZBbS2}`hZzzjrzH>_|pXOm=mn`uf0XA}yJ>kCCzm8GEt;lYZ; zD_un&>qM=VPDH62p?t&;<0(VW+ML$XQjZ$#9j&@SA`&b5EuSpqA=_BCEzj$&=IQ-B zGL(A<$bE&Fz4ozKf!sH-o!mD& zR+!jci0yI`#SI&ZiLTYF&t1LxUs~gi6K|cG{|7xEo&|aK9!}I`nb7PgDT8V$C&)ri zqvCqAz46BrC*AD#Df|-i~+89)7QF@$p%NTcUu+ zr`wZf!~y2}ji_i_dM=)cn3Yv4&_?S2Xtq&C4^J`l5@ z>6xCzVTF}*jwmNiZLFNh5-Su6+%g-{eJ#o4vFJc)wr_?f39h^Og`01Ffw&WIMRyE! zW&PFpzhMd1yRbx2*i&x#op;h%?Q<<(HaYNB!s-es_cR8!#h+ zzYl>9Z}YS(;5r`jr!mgdXX*!RRD|wSbKC~;jjp|D=gP+1#RH>XxjLV0om1!zrNMu!JV$a@0Fd%ivDI2`V1pOR=yrq~9uqeC2d9lPEMPTG@#1Nju93Bgc6;g4FXYFWXXyz%=tHNq~@HPZ@Orb)y#Y(x#GWJzvqG+Lq4r^35X1@HG` z#~WmQ^Hysr4vFeNhUXEfF{e^Zbh^!0yHUp^^)ym+uhV>k=4s=^z@!W;)BoE}Au-rc zD*|{I!CYVpYkit#S(@fMrFrl@c4F|uc2g_X?Li-4GtDQD2yC!k(5yg6^0BK123N8^ zDRc%e1Oli`FioL%st%NHroKM4pah<+`2A{(tVSOL*t0NTo7k8Z&B(ISK4V6^ia;1B zUDL9X+7@}t`QuucLs^Lxqdljq2)DtC3KIy+Jykk0QeA%0Z?M%9z*K)e{W6(-3s zVCgV3Jwp?qZr+Z`#K*%|# z%&9&(uX|*6_dK6(KJBgr11YMH?(d#G(mii3&G~HCtl_Q}%X|LMJzFL3#eGbNr2z}@ z{&`A095J58*aQs#Wx#!gIROw3s|M=iS(Xm0C~69epkthnEil?)w(Ucqa%;0breyX3VESGMXrT=foK?@#j=WM=Id&s+bRVBt>2{oMct^ zrAQ{_@}vA&j(7OX33UJMp4mOhD{4g;80jXq>9Y4BP5Vun{5sa$9Dt+?K#GqrUtzw+ ze4Tj_vRo>bz2?)%1o%h@2b~!36$hQI5vm|1&jQEuP$Q}}0xpt5H4dr>%!+Of;1?_h zIYAt$AQoqkMipyIpqJCNRiKw9KbZwNN-;3{9BeQWo70K zBrJRtxXI}anq2M(=mRS~_i_@#-$|t*Y4tF-(3JyfKn_x8lq}89VKJzr@>r(?5J~Uc z!TWT9=u+SZWKfOzgJ!N%4TO|z67nv z_J37;x}Vre7w~N$PGI<)DZ3odDFQT1QZ>oo{er_|Rm{c+U=vQTSY8Nz6?X5$)xMM! zP<(#DT6XdbWN@s^!2%Z${jV6XrUWsjaEPLktysPjAw6kPP}wAOW4J0zHOT6`T(FUMM5kDyZKr5Yk5!i~;pd*MfU=dm56~GKA2>_NtERZwAVtSBaC0vM{ zw`9q#Xd$k&8a9`m45v`A`v15{}&eYUwM<|@b zS3B%VYrCSB$YR0ioLgLR=Fa8$(RNpGG&5IFrQpO90^+1h31q!2~{vCtR#Wc()F*P9q+dKX7 zkh;CIlJNx%IT*cijcL~-T-FWel8&#d({hrUy5S8cnTv$7e560v>5Dts_O4Up)@`Mt z-rC?Zp-3(oG&?&@RZFSsHL^XDON8|HP7}9o?<{A1c0I~xHm^4E09p?o+t<}at5G+c z!)4q^E*6qaXR7=uN-Loio1rKknc*9qD2l}k>kv%=?t!mOvBTsdcozfEA`-9(5dP4h zz0pDZSZx#pr=`)JG~^RY$nxOCZcxg3ic*6{O45En_em8>B5%%KPP|}0j@HCAac&mzf8s=L{n(Nv9l7YxhE0j$Ct7B;7Sm;4 zmJ2A^?e|8i4Y#W+Y5MLtfmL5-U)iP_;nIP4N4lduoo?%q)f`@c(qj`FNRBms4iwOyW=Js54TO$S&65hGDYqaEd0Ksqvsoxa6YXSG zYhPn=V=x@NR{rR=9pAPRhGC|Ic2JT1t)YPO+e$uP$*(}bY%xZIo=#s{45vGiGe}>t zSg#k!8e%lITr+Wls3#LxjwdU@V5?u20~fbcTUx3iYFbfnaC%9QFwN{hNhzz&-^G}fj`L3J>L|2A_9;M*iB z>Xy9*AbIuDm10`fw8h)YC7&*{>Z~hDatk=(ijRy`{f5e^Grmw0r))pxtbhlB& zWSzxU$nZAll>3cNWz!~U&3$HvvW=YfRdtWDO4;;;LJtg$_F!s=|2`Rfz{M=EIv0x#7pUw^lBGwBs@ zrm6sMr9Qbz8G*X4L?cb8|A|(C+;X!(eF+yTFQH+QZ0B9T~{6z666jm8ZFF9K0 z(_ewojpdNSX9wW}RF_aTM}mWh}%*&>3?;K77s^soc!vY-Gqco22sQtBsrVv)$w zc1MeKcUW;JaC|d zt^y$KSx!`40zT@g*QDKZ=t85yT|oJqS{cq;DtNrxk(nf(TN%J0_$PWB^?+$Y+iGAP zI`Sm32|kd?Y)VmP6mvg4$=@=lYHk9nK#PSQInvs@bro;{d_g4Cp^`*taCW>k1f>&R zw?Z~2b4J28W22wD$Ja5)7sC--UT7tgrf7vT78FoX7mQAWZEjc?>Q!3hPq(ZK3R=rh0RW}b3XB5lxx+mZcwM_Y$ z3VC@H_|Re)X*BE?=u5B3QB~D*UqBV3!PX5LYfate4H_sBqL+|>zX}R!v*eIhu3m#B z;^5nvJ8tFJ84au@jA;J28F$ceeuOu>iki^C8Hgr|U7d=C1>~}vFdR{kRnbr)kh%i8 z(a|&#Nw(rcH#hWs{LC3=<@iXYJ`yuk9?>VUzL28@c_A&>vSg$bxl+bn)ocMC(x5E+ zIx2nxE-ZnM&hGCuO_l^=y`vpFZ^8S5{Z8ozI%vNQD{tm7Cj*t;#sJbo%mi#q=&eQi z=O6(_=|VrnL}6w?NR52)_Y2xW0i!U7lCDYY_evBvu`OB?Z4$fgsTqJb!% z^^Q<<5q*U#AZTj9xp*F`mQWm3VijiE7Z})@^kH#s+sxlek}nqX$)c;OHwv~jur1+} z^+4O8s``>!2Le7}W*ceIWnW_3fMw(4gPvf#_NEtZy6J_}rtfq``9Z^snnuK`29#lr z8&(2UU)X?C(lEll6Y|JSoXz%^6rW~w>qq>SQtt2X1=J?RQ^~}K!p)0@>B9m8tj8$z zvo;sjyC-3HOr?9?m9pvLqUgX(1KSR(d+@xH{ITV?DQH>SP@&oQ0VJ(R4CQ zx1j1^`H9GrnGv6%hHTbh$%q34nc5%t8Zbj{g-5U#I>#br4RbNmDl1~br zC5Db|nq1U&O#yZ(!Zw36ssrwzribH#+J~@I1y>prM60-=BDGGa5ra@249QHkTA-o0 zm?jnYgAw0^CBXC>AV0}liMAHQkga$$Z~29R+8K`Da&n2bE(@$JsB6_)C1Ts*aLE3Y z0JbT(!YWn>&I;K1eDL2gnU)l3Nk(?nJbh- zAt|WZL4RkWpmM^Pg2fobz^5;akG14-E!*+c09O1E4BX5Yv4AIi#17co0xVU7o=H~nR zW0j1XN!b^Y(QR{=obKo2oNvXP{$(xwfP74)b}HVXiqO>uLwqu$&f^V zQ?^K->ggw@h#>}tYc|uHGa`9haAhSLk*$EtS?A_*JFze%7>N>AlHon06t7AdZuyGk zD}cDD5+5g&0W}cOsOW+WeNPQQy}$=0G`QPDVwcj9<)?ml_vYo1bO}TYOB8F&D`dat zM{EVZo=sOu0y}B0hlDml36(0Rh_=G22+VNM9o>OUgARiFT@OcV+Rfhd_bxO!ftMs# z&fS8kXZMcUOD+!?G&JSQZNas67~l9fkjo0JBQM90+4ffi=@u{$j>2(NDtpg<1wH zJ{lErePOhC8TsHNi?{9~U!3^v+R?>i{kizZeJN|XzPs76=#{4aE1?r?R zDkWwX^|LoHZJ^YGAwgO6%pSU`4%)2)-hk{Jf)}9aVzyC-G1Ns0$KZzM7aUwCk6=Pj z7ZnarjDc=!$A@^%L1-8P@}PeUy{dSUmf%g8Egd_tLhCFaYiB{*(gxQ50n1i~B#?Dx z;)k_ClsB@*OZ#S;R9hz*~X^d0yj&O(Bgsb#~LR4TQ9sYy$+7 zYv)WJ!I#ZKn8Y-YTf|(he~>8jV=X5OGQx{AIlds$Vg=OpU?8@#m`JP$ zn+&0EgfoX}xS)%uz_gb3B?A$kpT-p4B{yb4mler{vI1d*RcK2)*Td4_wd-Re=fT|L zMSd-B$wKlLh2 z(=iZ;Ezvkqs1H~WgOdhej2fmMzAi?&PYBistURop0Ix(Oagm1Q!Y5F1$*Vxk@gYXC z6WT-CTTylp-(Xue+)?B~UcIbp`G(ICGoCv-ig~^Ez-z1{<8XvWJ zmwvMkJa(9T8go(ckiRN?94p}A+|KM}?qwcj4lv(ie!~2QImG-GjKUyY_%75u#2yE; z)eOG)kp*0aKJrp7zL_NU27B>ME$?5UcLwRLR;nd@Y^wx+L`lN2+FPP1Va=`B@9R^Z za&XK@+JP=Uk|ze~5@PBy21f{CMGp0ZfC7+Yhq$R^BNw9m?cE9m4r`UGWw%kF3QH(R z)tY*xD8kuS^B7Es>MM=PlzrU*=8W(qS~)nW>tJi%i3_w|S_wQkClv8=o0+%=m4@7E z4Ic%?CkRV9u@^6o&zS_Vd>>x`E7eQ&-V#UyEBNrXv?3~)B+N}JsmQO~iGzTLcf-?h zk*;eOL3ug;qd~1WIq5wl!YuD^&oxLr*WQ0?tyWuaA$AEtD)>wT1^f|Z=($2Txl0!C z(K+aoyxi)V0wQ1#!pbY*9IHd~l4aW;^UG>P;YDjeMKG(%Vo4LOM-U@hlf`gYl(Sww z*N(FYN?<0_pyCsL2vVm15VTAiMb{;?_b>0IDlh`pTo-GlrhaG}QX5WCY0tQDx!bk3 zGkmP=`nI;~FSaB};PV_DGXPjr9s75a2r1UEbV|?=h|2>j;#Gt(3lw33=g*IjMSzi< z-_>MG#uv@F1TXXX5YQkSY*dmI!&GDucA-pDijYTSV?KmfG1r!r7&5MaElMt(ZmD;? zoJIiPw|am!vdcwe16>U{#T!IKYf@Z%0CQv+b0)qmN5AiJJ@`Zu9*0FT4a+toI4P01 z6>0!>b68k|Q_sN)%E1S|DBGZJ66*9QHi@l9?V7qPd4%g(EA-SOO7L{7U!w}4H+^#W zZXb-3Ou3G4vQgF!ke-zh7;ecPs@vo&Pav2p7_~Wk{Y~%V1?=6`|zt)H3m?7G#}I=;c!HwYYzgJ*`unq;;0Dd6D4?-4At+G zcwIIkzJLpt@)P^gXSvETDJqL~bUU|0&WY2fH_=~ z8qGpe8J_D~K}ny` z`+T49c|MOlPkNRnLTds(m=TSgM+MI#R)|EM<*0;`XL^7JXGy5%w1`Xu5@DIy9w{Mg zkfyzmPRN~!-G+fC&!{bJPmDFT$)F-hliqk9S$U9nDyC*;X`14@m`!sPko0cmIPwGp zEwJ%Ou$!|y4pyjL5rDm#Z6@QLV%c@m7$9_9%hT$q^o|t-xt|;!9K1EZ4N^?E)5f0c zsnuU`!*R<=sQx}FcnV`VNzF-CAm+)Wito!t)OV~LYNpW_k44QO@;R@JvPh)2BdK<{ zzO2-ZIos5RhfHf!w`zLPj|`EnKrq;~<7VV6*$J*9dyou=xJkr=VVJ~FuzjHjUmd`^ zXIox46$-~TX`TVjQ9E+j3fq_FMB`o#v!9Pb zEi8Anu&{^{g||;BAUZ_Qv3*qB&gDvlaw1oi+!epRKa#x*j^`Zi>zGG+fu-elRYG>` zRK^n970J3Qlj){Xk(lQ!6al6u-X4iYqq}acMNK0bjfBknt}@#n?D7+f?b@+pa&oBj z6A>1oV0qa6w8W(|6Fm&)(9IOft(|L={)>grZ5mFDkspyc!)rZ}5%x268 zyP4P!cc7xXt_FRl@IS>c*=;k`+p%MMde_`sEY@g7N<+lFh>%>6yMh}jk-@Ni-~>z( zj}Lr|D9JCN`HB)RePaeZsmMTDIQSYGt~B-6Xcs2INn!OuaU|N&-6W_AcpC#m8Vw%J zgWvNHC z+;if$3cx27;?dNSDibpF-+9$gzubVKB8~@@pb3Nyrpn}wCJiX8lZ9jy{%$>CXyMkf z?(15Cq!8?WSEX6{@nAnaO|p!r;Z}b)E8*vX>xP59#@H;*oLY;^rF_ltVvbig!%^6J zlSS>}SLAx>BPH`D!zyTc&I^T$6#j@{(_72NbtHTOzHS>vxvG_Q{dKaPUcO{IE}QM@ zhJG`8=rkvYg(KvSU3i~XV5MzEk{=(qa^MV1G;d=JW$%x%;urli>UKvN%ip5AW5%)8NVlkRXCsWztu3|GCPlWW`jj6C!9SmSa6N2?8bpDE_@K-shGRM7s|MZeShXw0|g?XO=tbp8Vdv}HTojGsu-BO{Ga zdVi%Fx;vIOVF>qTahxRG2e0t1d+@=h%69o3^;)IjI-d#+IkO?NJlHB#>rOe8me}OL zH2%ExjEac~CGlZ25L2w+uDF{w?mJs?&vBdjz7d@*FYVa5 zoNX20T(VKQBICnb^)Q&Bg1K|c_|^7iebmnY$1jk&ddbR~36NL%)Y!;a*feVC zYM};eNW}I-1+&uN_5l1{) z=q6cQM52`hFo71E$j-8bc5^ry4bPkJIlKQY<&{h3%hvjLWl`k{S1%m7*HR<0wEpM8 z()vp;$&ySINv+Xr{_J~>?z}j2O)kg$h?t?2bW)+ZV{4nErR^Cf?cm=w!rKPx!;_y&nGqXb z#wGr0Ezq7NAN{p)5?3|#*cuxmNl5(5}-Ec?Q9Qk3-k@PIA=ONmKhT88#VC=H}TqA4IIxM)PZ!CjnYK9*^DfG zYytFjHshqQoMgM(v}TV>!@VO{NG?fFBay79B6A8nrE!}XHE%^tbktl#^&*k3au$R# z(75&D7Yk4}t$%84Y+Q}aqL8WuV|GlN7*ls&x7_@tNH%it$ib6|w^%zH_a35txWx_$auBl4EyJ*UW7Xl61hVH{Hv z&9u_Lt$7js3_MZ#DNVD8mXiC1>^Z5EJ$pundXsTGY+Q@80Bf0w0BCX7IF@d#|MvdS zES&$_PS0tl5Kh`P+K=u<`!MQT_T|(~E1!NLl0AIl=;=gh&&zK)aU;s>4NBj#^-bL_ z99pTaI&@_8if#AoZ_jK_9{cv0Q+NQ+oH6YqoUObSr8k+rogQTz_=${?VG4QfBL_Z% z9PlJFA%K&KKoThSte>70oHolrGNIaY(|r3++Vk`6v6p9k?_Gd>)rp(euV_t8wf?lz zTYpi_zd7osyr(=LU*Z6M(dX4i@nreP$_^vpMjMK%7G{(<6?+*!lO>=9Qr9BeYGa*c zJ#spiKmEh%?CU>W&!y|1ysJ2vjQ8e-##i2CSyw#VtQHy{J{x&Qp>X;UbMRf))_>}5 zzjD{7>;C#*Of5xIdHcZ~*J!ZH!f3!jN82yi4$m^tLA<|AVJaJzJt}I_h;4WEZ z48p+*gmHfz>)jxAU%m;PU0G@N>XDecFgdnn&|gBTIXh zM@E+SEWy*#m9^c;M!7znTbP_&XfCQl|DZ7XmFABQuYVz)A0E!f)m6=Mxw-z5%B9=w z^!lGiB2Kw1xs|5)Vzmdbw~JsxHWM4Cvu{XeMihpZ3y)L$%ydNak{5-Riw^e6i~Ikw ztd)l6S7+8Ao>}eG^yy|b7rk=RuItx-(y^*GzJ{vhoMcuE7bd4(S$o{E%CeTpcfu>9 zvwQc>4sMCLk;Y7VVej?3Qoneo?0%{0Huajn50q;=6zh0=-qfzrgg`>09PV&cKJr z^A@9>hJ%xmu^tP2UdlPN_|yrdbXtTdvpxxTV!_M598$KB;tsO4814e~mwCAil;w@3 z8;mMkrWNB!Xnda_7V&=Of1zShT*R#2T{Ws-Zg~8Du70j@sIj&FxyJen?xDt@+jw?= zx4VD-ow;(ZUJ5yW$*<+h`AX4Ip)!=fZ*tYO?)s0pBkK9@|3~$S^#@+~=K2FU+@R+g zO6TL3>fd4dWc^U%-fUyC(FSX5guO86k7%0t9gr#IJ($T^UW$f2bvFE(pY@j-jo;xA z*@pWk^ZV!L_isWWH$$-)$@B>VQMw)T$im;*XnecTxU61RQ|q^0cb%`I>wj~FI=6ZA z!}a=Tz5cN4ej=E;A2?y7@i1F+Ov((ojfRU|N^3#dD5=?-C*Cw1=wz3={%HRAjsiwc zO#+e|Za(=`eq|1d)r~zDbN{8+VXXS+U`l4EyZ-Z%R-*RHbZE$pt^Yn>U-;ux zoS&-A>MgX!eqPrEL#UvfFn%_CMsGKk9A_tn#6q+c{J2 z4h`3bJM-m{MK8K#bY(Nd4Itl>wIf5zr%r6IZy6hFbXpVnQrmG_1*cBFyR|Zt8_Kd# zsJ*=90OThVJKi|GBhwt892-oJEiH|W5G=z@9WONwZ(F`1-58r3Yh=p9!(}N$k+WvD zCwYywLl#=>xn#~w>D&;u_aEDVfC z5mvvpdRujMCN(5{)sF4OMDI4dB6f2n=@g27uI)S9=eHar$v8dwX7$|Z)#>9~{6u8T zt9ZFgOw*^F;;x$=zcv;3GLfXe&-e4Snd!{jrpvcv$5g1eGUd1K4R&1aqECm~y z`NjCOj@k)?O>|bEL_{TfnEC>n8zfLW7KXgag@ORsz9}2^yrsti)u#<>IVZSiZJfUoc-Xj5oGNNfw`k#SqhL(C} z<<#kii`9E(x14@>{gylSuPto#n$bBqxgT0SUPghuc$5ZK^f_>1*kQ=OyOQ1tNGlPAv}j#7AN`Owve z&K0}rnY*THQ!l;5)&;xV7+n7YLO1X+QGCuTZNDJ?lKq#(6>K@0`eabv07 z3o1Lk;mGEl$4j`J%-X4%sSY?RTJF9aF$Z0+7wVY#zW138!+H#epJ}!&`<|cqnI{Y_ z2e3ppe#*Gyp8Dq}zN)wYAJ@D^fbRmX<1a6-PuNyuyt%&;9QOJ115aNW^@>-%n^eFY zJZirV+1RrKKRockfgfia`1yga4ZJw;n*)D1@Sg|%UJal6HoQS>fQLN zKTX{%$s)|qsyp%<;1b(iRLnO2xc%{5V4DZ9JfiuyFJ>k5IX5ri&t5l^6+{h=+F%dV z8TRYYX0n-05WNGvky&m6oEmY13>tJdXjwtaYo^ldmPu!r*fQxb5i5!&%I2Ak!(lmP zL1ni=xzVE}JBfo5GV8Dj*GO=Eo;YVWFvi5R%C?&%zEp&*4yy~KkR)u(*@QQ6;IcEk z0kTqnhH?_@J9;wk*QPuJIjUrQFp&jWBn2L=U92_kUM?{>wI#R3ui4*2rfK{+IO52l zl0CUtSt+-~CEGZKNY0v&VnZ-n2?o@bQL{@Dbx#mB9UcUT7gq2k$8Gm@9-c<0-IZ`% zD!87mMtZTD%~rfGecmf4OtE1 z&Vs&n-T5+Fp&kOdx~400gbIYFGkC2TiJ`D-T4KTU_8pqsHv**|SCfLiP}kGtnC3>O zEqv7YcH?DbCf($W<_t!oS@LipVCdn>2?>u7{qe}I$yA0TB^MW-`hvzoFbtOmhU2g| z-TQ<#lMMT2J{}$Xx#Es`WXs(8@4y|QXB{uq`qNy^47U>bsp{YIJ}k|0?U?$4*GhR# z7SD(aV@V9BlV%ldBRecLP^=twQr05oM|>fHC z19FUzg1HB>T3B;RF`qbNV^6k)(7=nM5s{2G27L-H!ULo^5&YJslW^UH&!eO!j!TS? z=WOZr|8$DsI&VSOLmpD4Ljckkg4ahS2R*XJaD|(pdOHLp7>br5GtnqZ)g2hgKQUgd zjgQx=4=YHOY}2!JtC_TGz~9aCgw+nK@F2NZ-FOYpm@yP0xL_VAdUGQN;Q6}68~1F8 zX+sONhs=dUC$owL~-|XHSq@C`D8JlPLaO` z%?1xeo6X~&Yg>Aah`dUxca-6Gi`CYjrrwmD)C?GiDqm>kC&%9#x+X@J&;K7YLHNXBy&u!uh0TD!?7+ZcEZL ztqJ(xHTCI2yI5@hPni_dq0Z)^O2|q^I=SL(DKgtmWltR1bnTACY9-?9BR77m&@Keq zGgZT&PZDk+&X_Tl&n&b$Sui@GNH$qX)XcGANxR@mF5rJ{#_1_)IqvWCqFg{;Wyw!Q zal4QbyfM$X4bbYMMJk3(Cn#vbb}W#jwXq~J1ubgh1}_i`KJ)npAN>4-Z%|Is=}dH- zgtK^X@vmI_2NJzz@&kg>hGV`f!S~5@Wg}DlN51y><6nDRy`McF{CtR5b+KHpm*sP4 zaq(}Tl(gq3Il#LgGmOW~`E(f6dKIqHbXs`<`gi?{?Ed)IUX5#sbJv3W1Zzg3&on~M zCgTu!-y~Z2+Gq)hXOcdOcOA7d3xVpK2x{@F37DSHGyX%MFJM3eviOb!r2#d3zU_I6 zBy(+O=;l{NH11nO0-&}RD_+A5CyPm#v((S!d$aXMcRrh&ZUBRSHl2vZQ;B=^Hz#wy zR@1$xmLjU4n$KS1hI-Vk5%71-SSiT&h)0TvmSt;By-=hhS|!h5s5GcCo6#7IrU2?!VN(wtmg)FFX3WJFd9= zF2O$yP%BTk(oV?4g;6{Yt|9-x~S{=7aW^hh*j@|plzeuD`q+=Z` z+Q<&I1}`ksb3?74dH2n?z3V+^Z+!3i)_YD|ao+=njs(1;8qYLByx|Q&9+TuNb>!d1 zoz|c4F>iOic=qfUzc^m-&z+mQ?28xY@@Kzy_9m9{vVOm;@6Q#^A~zf``v1W5u<_wk zFL_7(1NJz9oaDlZ><e+78g^8r&5ei|ARh`^{g3z152AWio~FG6L3LrlUWC|((>B|V*| zj|L&|4O&P8{AztMy&nSkSZZ;<*K{KL)0=BhIa|fF5ucu$A_iI{RJ#7x`)}XR-wq1F z@ppIHVyC9#%1-Qi85T`4oAltC567b+8=9VE_POr<{oVQf`{$+bOtIDKx0{!Pn23!( zwkkPw-G1UCglyvM$6q6aIJo|SRRtDkR^%*3AFwr)9PWawGCsFSnsIj$aQ2dVmdfI} z+F!q_v3`4U=j7zhw;J(irWLQ)76BV8oJh66xR$)B!3fhyubEDS*Xy}lJ^REZef0=? zu1x(bI3$?#0Q`pBm`jjIO?u`2p3$j@;kf~(k$xb2D&j92MF;PrF1gyiQ&29Bhm4DZ z5kuZb5ZI7=$jqn@C9;oPb=4!e#INTX!`S)Zc%$h1r5ZHL$=FCE=j7D6T;lPo9(m-d z#}m2rzs=S<5LG23bvToYRc748P%TT1GVmt<9lQFeAjSeu98&0PU2nB=wW*;8OvUq4NoOMo~&8+t)8>R zGB=0Z@h9OhaVk#PxBWt5%dpu_ZPu5y2dKZK-W5?p>tCtA5Ph;m1+nifWTwdHqM8F7 zoqu0S+#Lx&4wa`z3_Z2O?@h#_@}*XJv-6ap3NbHAjP(Lfi*VAG$h_>5(R+B{)WGdT zUVeDsefX@zU-ja^OSF5y)Egt0i4h=VNmNCY8A9enJvhStBari~_(Vx*KTP5O(( z7qQXAtsslEH)&-ufD$m5*o}OLNp;C#*nlGkyNm6Me_bGwEQ{oup9_vJ7jSVqtU+;P z$O^nDoTY=4zZGmDu$T)M(vwpnKb3#So}++H9$yI#!56PS$PI7!{2SDs zSMB9+)KKU%d+zwtV4SW5hm*ayoFlIsoJBvlg5awd_*^Y!4ih;g*l%- z*>&TV?B54!B9{mcgWN<29?pw5|EiLJETERJopIZzDXL)if|y&M8p|ZCjy)vS1)X4s8rhIZP9LCQvaQ?G)v55Kp_lxUUX;PTT_}x@bF1u6rC|p9ML}2 zrmfeEcfPg0)jgGwUU#&*r+PsB*xGFmP3@~}GoQNQ?0dFV z*6;E4bo{!9u8RYCS^M2Uhx!^O-MKMmH zzBb(LzPGT}uH-7gvy%FWlG`$a&Ie|n#w|nkX2}B9Dr%#w9raF7L~M)3%pVOHzaSdP zxEn5|4n|X{=%#es6GKWpD@$`r<`a0|vT$F8ZTNu)yQL>mwWlUWwu=|_Ezy*pPfazK zihr4ku0I-0Z9Q9AazlP(cGu+QtXs4rz4B~b`kpaRJ^zCGg!&S^9#=A6JT9>`&ds=n zYbl8S;1t0vC6A2@)=OG?quYrrwwrw0w~ta{83?-}7ob6{v&6ljL5XV1ZMFTbIAmlj z<*ne*>PR5Ci>$#JBgOI9u)}st+hfRCRvy&H{|UD$|-;X+D@VX((mC4P0Qw>UJtIi{ENVjDm{4$@epn3?o*ky`tX z4$KII;f>H&!j;E{{KldAkzE}xI;}>?VY4cEGm%IqpaxE^KWC+^=|cO=HV`A`mcym| z`*hA4O(jjp1`?LXdBMl>{3S2qE3}UhB2fDVuAxnD(I$-Mh>((Y#3qnJVN%-$eW>5Q zm-Os>Fv8MA1OXI0ROtN;q-7WJC661CDfkH~-Og4d>*AR*?Fhq6%!?Uot4r01oQxWa zZ9Beg%UA(Ei{#N#IT3!lJ$Q6->gw4z-XblR>9v;^*E+g22s<$&4{*g1VX5{*ZHfk} zGU+B@0`Yk{si-})oGj(t_j(1}UKn)A7n|&q$8s_A_^{q9JK;j?oldbjJd6`YMZE&- zK0fXR8_qABAuf#zCU@LA%D|lA@tMaX$IE9vl1 zx{`6`BDtivOd!_6{Z+qemuhdn`;Du9b9{J;0yCjjG6z-A{tw1u^Gc0p)4p!qE}TFj z3;X)HF1R=GX}3D`OMF+P392p2%g-(^pB7*8o1Z;)?Aeq3KKIH#Bk+EZ>n8gV0Reu{ zM&kvHjFHV-zu*Lid>72Z9C25q8cy;CTGUojTC^>XXE-o8%~Dwp^Smi5-%DV$F5cFz}-FTL@hE7Tj`d5Cl07W z9(19my}qSsIXn@6lNXi-^`Q!`y4x+K|EFBIR0`+np+q9ozc1l4{2TT0z`|V#7*I*w zmCRH6HC_``Y3cD|TvcUG&`PYAoYbx<<7)w9KllhfaP z;`p11iByW2_~L=8=3E=eCbD4gvL{Lh7vt-Hn2X2Bg^1^V+vX>I8!EnS7vEHj=YlW( zwml6&%C?gyw|TBN)rk-3?{KtCCR=Bp)Ps75{4VA=;Ok^R@=I;oDjk+Jvb)%lI<~yn zuEl|6@v;PQpuX&qa8+LmmJx_s)Te;v$!+4UMy>|RRVF(@ayh@Gp7C&yiz4=d4d~ZA zhyIr8`n&+&VHi2rs;Dr&6`V za6CUwt!_iruCF!eIrBr&ynWN|L2~&-2iY_}TgCr1A9!S8-6_uZpv`wv~yeri+YyX*hB z>HlHRBv_UIrhbK*i8qq(!F}{o0)pNsczLOx@vlE;=fyvUYf$c!1{`!-?i=}&{@?7; z3NXiXT#iYP#)#?9tG_V6)EH@e$t;?K8~-iWiDTWm7HkR$%_uUaxUopfC>gC_i}iov zgTMFoKb|pu|C&O%T)5`<4WmXq;#w{Eze@-c;8Gw~VQj&1-M;XJ@pCo9TsDklvp=O1 z2l7;VSUoB+=Rsr(?@dPdrWC^3xP3-?NvLOFmxP3iFPWN4Caieb8MJ^4eH+XohIJj4 zu&T6&&67wI&HQhnLI$t-Nr%5;zLP3MZ?xL^^2kUz-?qqyga@BApJ+OtOySioCNi~J zCQ-C1UZ&uvu4A73W|%AhESW)XO9Nji2P%$r$Fh}?O(T`8XvraJ$yOUN$~&g2O2mJlbL2V#-LesL`XePK}C zvv`@ro0=33igl}tF4c1gzN zDQce3x<~9vB^1dxjiTj3`wik9brhV@dZxwYYX zDC58&ksjVWeE;JMPR1R-ecVlJ?&`HeER^<^!xDn6bfaM#qy9wgBISt=i%*po+~%8S(-F+yFD{ig{w~&SAY5(Z7t7vJDk_W+m+x+@q~CrcuwcD%}!bCedD_K>Bp+K z-(EfT^xVwMSI@rxSC7?hzrA+sTOXad;no|l7pVL6&*y&=P3yDZ%;YG(v{^qhP1Uy< zz31~NXZ02ewBI2)vpaLk;-d?C^rrInf8c)dt5*-4H{2h5e_`R#MJ=j6{khNC>wj}% z{d>=GC`TMxocN^kQbpjP)wbUcpFZ&HC0;H=WvAH`m`kGV;6QHx9RNzvEM%dI-E) zwUEmds*?-3_R%$|SiE+0eABzL@g#LRlDFcS6^)O&J-jh8=4%_wMS{=j2Kc(ycs=z5 z5>y^5=}a`G`iuao1OWxC(|l#tXI4F*Pp*G}x(P{jYck)moIAH}y%T7Py470$r`6Tf zquu*d@*Cgy#$C(zz2kay?<zaX_0nNeV*E$>$@buBMvh@%QIrwiLM0mYrun{=NhwQEr|<4Q}w)AQ={Sd*pNw)`l+xndx^XGJ0UP+D5iMjuphQ1wjCHB8dqwI zYf+fRrnHS=MjG*aWnqv7Dd6bEb zOLKOtwhni@J;+-01odLTw%OLFC@Vw3j%t-$+7M&3^8TyVv#GGd10trMi7cF)?&P~Z zaqO^{a#NZbsf-(Yc8s6cJ~dyu37yU{LL^#f2MYz>SQ7*ZIyh>rsk~_m*G|U9$7YA(?US49Wmn4b%sue!2UURW5p>*^hDI^!JOGLh9-Xb-7c=PT; z^A{(UvVII48)V03HD!c~g*f*ucIJh8C^x(kEi);2Wpv=TkiIOp+vWy%WxU$v6v_E= zXJUQe&SggO+wj6rwFu{_$e}=CrKM-22eZTr?sWrw=RNAXPY_l_SPhj3hb-w$ zx*eG)TA@TSZNDCyx`BC!R8gbg4B##<8{Ofu?0C>W){4!8_G>MN+5 zsVxjH0{FGWbABBs52h5Nu3XE!G_WuBj@_5SxeChIwXq zE*T(<4J0=5P#hY4(-!DWAWV>+>P6eK?u>;?gYDVO@Z{>v<92xS13&w~1IN0PJJ$c~ z^bM_{)tl8%X;EYCSa(}F(JW_gUR{}qd0USjdw}hVz4a&m-POsPR}afrWepgNRbNGR z4+MDhBiN;k-cW#MZJgMb{L@A|i117P;kU8dm;Te_vt0Hi|5-5OD8L=EC3|`{ZFlAe zFM|8L??l2zCheEU6W+|$u(gapURk!>tuvA2csY^H7;eUu4JzY_=rDI4ruHX~bS zz2tbsPiOS-pZ(tN{ocP1e!lwEuPXJ9>#lppb-(xMC0ivqjN^HfpbAdJaa?Qrt_#PB z_~VsSIs+h%nn~GIDmc@UD`%>nA2@eT4V-(&z4!i?`|eW*@A$pfz3zLPuiL%r`s;V? z?vD?@#TfsyWJ8UMb>dS)qn}~|g0&xJZq0&`vTXd@^Z47)!bt2-G|ARa%yoL1E1$E! zSRNf6ju3KG?utK@E09tfCeffWRj(?5QU21*pM5v1eQDa>s@~uam%mjW_UBu_-kMvO zxn+4*dnlbIrc>2s&54|Hi+i?DfAop|TXuupJd4(}w3^6nqt4+D<{?oz9#>4o3pWjfFB#F9zaI&`KkJE4kq8Hi$4jpr< z`%*aWIB^9DapLlVN+7tLniHzA&WjhSjY2F|OAS`LQQJulQUMW7+*0ZMo=!NF$Y&EM zljb;l^495AB2${0-%7ww!razFywZZ88jIv~c0u_~$qu&Aax0 zocooD#as5~^D|2m$I6LV@Dndy{?y2}!6%?UN%;t$OZ^oMsdjM@%M_Hfkj&@cjfmz- zyojbw(Rg7W!DXJN)I`7Z#uw&yX!q{chYNy5tfcCV>Dkp)RcJOzW**!ak^gw-yb6a$ zDVn%E;n!=cH?7_(1bP_DulTq{=la)Uh%`t!vyhWrXh2&7)iOg%OZUGO57|_pWV~v8 zsKEy~8jH0}2d09kW42?l(YU+;)xMcJAqBNL83}6 z)v)Tp1)!-F>V0VHDEiQL@UmL6NJ<}Nv5HE6v!+fF*=-C0hEp0~*UcKtC%<-M^vcMa zQnx<0>K|NO_I8hM3NKxLz_{Xcu>xO!cE;GDPFTx8BbBxmnl=BU+N+^~MeAA@zx{-^ zqNt;Jxu)E_x_X)z-|#YqzSzi zn|@>K&Ml8D?cO?;-AP^S7!;H%lRMW|hAP-6jpDY!?L2P{Ucr~ubJ*)rAAqMTUX_lu zp>2y2MLX#B#BP#i5}1v>3AV9?6cwL7;MSqi=GLY+?7RQ+18-c*7UFSrcVd2FVRm-G zkA`C<;kGJ{)`zz`#YT21K6JzOEAG1U*qKd(eq>W?+ri5(KX~ABGnq{pxhzR}rnFdK z0Oz=#0(h9ic--ZWGR6!ppep zk+1qB)gG)A+YwKoQH$(F??&gA&)J!4x2qM8P*$uwr&VfM4}a@J>MHneNUwIIRWgMO z(U2RBNSRdd-=RcYk3(E!*ohJxp6LqcT2%t49r{A8qRmmvjVzWGwLQ)uJ$22tD{ow8 zSJN2We(m&Hs~|i{>p!d1$26*@R+ol45yPH?X+v3&bew8Op+q5P7RM-Dpc!7XwOFn$ zGz*rMnH&Ve^_kY%^mWUFn43;y`Nk`^Q2>GziA!ya@+*>t@|3~>Oxs5zj%k2{uoyOs zgu692^jDs8w>}9ckaiClvXv$HEBZQqKH}Hg)IneE5@bN3=OQK0C$0)y zRxFYj#V{Hr13@q(})T_%K264q^pJSkxqUqC;$l4W97QQ3l@TeOZ@_0xJcS>O=KVw3G6OP2Q9tKv2bOX1HcLCHpXm-pjM@?q^tD+Oh{1rh_|x*%?rIn$2}rYcp!eVPrMj;$vnJ(Hk0Rep^=_wOG-o1cnt_DIAc zp@DRX7W{!xzd^(~8LQN=-iYXWAt$2j&1u6jD-4RWK1{5po3`<0a488VT=GhF2>Gc= z5=kVI$xt*j9|^y1q|~Ao2Ln!E^PfY$oZx-qtw41PVZXr!(U~`h?o5RGX~eymr4S`F zQrRXj^L8KPjdx0&3tK<)O*0{MKa^f3$_0)ea-dM0`ZhO*80hI%q)CUZCv5$M+`mx3 z3q3uoD@4JCu-;CujGv779@Ui1n0~{Sy_Qu7oKSQ_+kEM6sty~Nu)>0t4@Dj_Qoy`D z8*|P22`p$yAn`&;YhPs5q>>2GE~UM*V`!e4a|Uf`-vm&Rp?#mH)KhHW?_8nY8kxDT z^>ElibixpijxV32VG%4wz>+aUS!%>8NW2XXm2B8U_=00kmvH9H+GOXOs}PRx8ShWbUO|80rf0L|}+~l@<2QE6<%f zw`JHrcf}RQk4Hxm;UxLD>iR*d(S}FPg~F$&fgqUXQJB}XVm)e(c-*%J$G}VKf2hwB zZ@P}R%f$)39-Zq|zYUal;op-H`r@yo>PsKH^mhtk2yk4l0)3_Ic~MT}VWB1wpvJYP zTXDP(gqk9WELm{Mt|=coqk!+ljlo(=C($h1i>4f!DK>sOo`lp|kv0*j6btFFlg6(9 zSg~ZUuEzZD;u2Qzw3{zv$Z#YJkwd_|%6o@C0_`%MglZ&}HVix-iEKItU$KQ_0Kz*q zlI9hUrCqmBOD46_N<3Bj`qfF{a_;-OUI_f)-G8ekBm)UHJtx6ssZDF%-&bF48O7=HL<0i$Qae{Ckdhz#BqW&FXTH2 zFUIgCtPZ*N0QcNg&mZ4r8E1Bld}`$QHq*Ff*VJd{jDuS?pE7irs%MTb9ov1QV`i-5 zTaPniW&dRJ2}3`ydCPG_zg#l=&p*Fmr%9iz2Gw$;){GecGrnlMVpz4ZcBiU@ZLSZB zXHgjNM7t@|E%?h*dhUpU@6{@zK-xkhI*)=sOmtFrTs9$<|T+2{l32TngK z8@}8+-a35s4L95trkv|rDm%-CY!4AQ5W$!GoR(BC5Uq)DEy8*rnJp`zM{b9`^UL7E zGr)eb8$+LF$xz6EC2c~6!9k1X!r&)C#{geeQ6}FDwv#VtB{E=k+ugu5Ji$Q87aii0 zQ&60;0V5?QX8^y%9fENu1Ej<-F!vC(ZJEk*7Xn&obYhJ%2xG!pjDzAe zpW;O++(6C~m2_QrtaGWjqYY~&0L~KXbBg@8Ea!2wmZnopF_n%QA)m1!?z_fV+DK~$ zG42@IBI=){R`iO3K$L>TO8es zGirEmtnW)Fp?=NL3%qi=V9spIG}o+|!CGSbe0cequ;nJM^T@*^u)#=6TA&o9FEvU< zjk16$Zrr8;?sU!Fy33~8)C5YWxi3VCTa*gth{bhq%`wrvF7=;R1)=lW(M2Ut(qWj! zsh%O4)}<8fD@NRO!=C3w%9@KtU*HQ9^u9p(mtIY_beChVKO-iZy2f_CE2i9dVDEut zk3?TF^e!>~UOl9&-z7V497I*)aV$Tv^2FNn)Q2xxfR>W6L?=V{m()*V_YGr*V41Yg z)-d7(fF#i@G&M0f#458UFv@74(-qV?`bj(J(V3JECSBU4c+A98qJGlTs$~@(j*q~_ zlbNn|%AMxK{?XZ3&GvT2{U45)?xtI#{`g3xGE(`oN})4&YHhYY6xVW-&wteSlKum* zge{GCvRh`Fg-$JWEI;9S)#%o!dnieK+mU)H z=l@E3OudJg@08SDZDE>BOQ<4)QEhRJ^ef>ku41}L2c4Ofm%~7?k^4%g4m4ksg7#oj z@YGXX`X)7fFi%Ot+c7bAm96epNlo4NCc}yt`s_3MUm*EW2{&!>BX;8Jq=~*BDus84 zL)rs$jTjk$*7|SJtRnB#O~>B6=qK(oeeWA1!wr1dIlYA)V5m3TPu`?bJKm(LQ7Bwl z<)r`EH?WbhIEdTr4=}}s+KIkokiDqFYnjj-QL8}az8v6XV*|^u#))U_BmcUU${mVv z#sJ10G3Bo(QIBp1^dx?L$*<=*h#)fO+C;G%_$Ub2ArFIOnVGH+6aiLEaac&c8%};H zT+lxnk8!?3+d+l~gQPjtZcLawKfb0hrO|G`pNvG3>zhe1NxUE0^Uh`p5^MVO3c2{) zkJ*G3ibuid9*Q{2Tj83F+Hs4l{hpeodY}5$Usb?P8Dinley1WekWewpDXTP7Pnmhg zstu2)fVj}DlX_^*X*Hc}E;1jFs`c-XkE#n<8JWYo2pG22GhE4Ad`Rro4<#aBrQo9- zvfWOmTBo`n!#I)${WglfE!6Q!Zo)ANRkKjE&{uUk7yGXQ`x0#*g~e2-=n%HQC(elO z&dk&&d`YM!Vnn!Rb2c9HXJ-mp*55nM8zhop;fdqnA;eU^A#GMW{{y&XxF;+&#;qg| zaY@UVJT!3w(FuFsCtGfEJ*KfVOJ%23k4fZ~wLbuJ;ue)`wcC{C|`^V?T zqr0bPvvq=e8~KfaeryMvg0sYM!A)NDh6O_rI4WE=uZ{;&y$d*sI6;w7Kzq;xgQOC9 zl|9rTEIWqqU?_inZEkLD?n4OSVcq!AT(g;5|3#U;Rq5!4KH(S&RUWlK&QbWl2K8zK ze%*1)+S)B^%3;sBHD3Lormq;XDWGYtv-8?5 zqSwUHYrcT47gXc(gS)V4v;w{o58s474;!{YdjvBkT0Zwd`;<}MC#{iz7amxc0%m9a z`r0$5zC2HU+lfYXDvyx^XGhr1{K!tt&83Hq6%9{F>B9RzR^647VkHtUN`fs|-M0SQ zT$Kvt6ZvGJnz2ecQi18)8Ie7J4XgN3@LwaOt+ zSYlzwY?=CYeUNwG;^-LKuB9Biv{LsPY44jMbC zZ%slKda-Dfw4_$lQ+oPd?apH`K9;o8dQ6KiX{h_Dh)2jZsoIVKLfT&5l5`^Nq017Q z&!}+I&Dypd+Hl0flZb|9TSg6PvWPZ1p6#;#r$8AdfTWzivI+#)XkSj>a2VhETp}}nYM21}@G|BtbrnZEPWJZ)o>uX?fn$?N&k{SA2ZqoLgk>h{XQf%9a|z^~hR0_Yp^T2H zS?SX1O%wTY{q5PodgjK)E;X|GCTQy_qmh}febA4uZo2!nyN@0}^#|7+I;qs(6^jRM zst?xRnMuBGPdGH+GE`%>)EgezS_`N1^@$@HRr%vs{PMRa64mI~%tSP@I!sm zJE3uDj9_$S%N8a}A|<`7`ewOdE}GNj^%pP9SZ53Yv{_m-X;K01tmE%Wrz4x(Hsr|I7LF z*cWf(9dD)%$j8VMW|St=T@YZDlR=nRP3m3X38y1w=ewYL>3M>c;kk)UB^wgjfsdz& z2TB~|XjC}r=7{xmgNVU}k4+>=&|Y8xCG2K(%s{c36CIs{btcRJox_`91!`PVOcue{ zWh*$bcs`;6i2})m&~v9bWrnK>vw_uU(dmB7j9-8 z^lk`PE#IBcNnC18E_Vp>il;15i^qx+AV& z2ytfvgwI!-H@AnkZ2~!XR81MtIH)};G&ryeU6v-4@M=Fn6P@&5`w0-3Xw%e75WlKa ze+%eR7Z>+%R|eFWlJqDD{nEuLNqs#O{cRHxu|;P;zn$`e!e*} z)YRHMAfgti4ld779|W_GI4p`lI5 zI)u_J!CHDc6WUIvOC}>KHT7&NW-plSFl&+1D{&3o-s%?JP?Sl;YLSuVkVOgr4T@8= zH;`6MTAEt~#l@sC>&Ax4i;DPx2cVOPwMvGQVOIwsfEnhvc9>xrZ<8%_NmPsG6#ro) zJ#LL^`j|bA2$pgNMg*Rzy;v4XtAgwux5qSn+!}Y{~ z|8&Hs*>~ck0q08>lo3|e&~3%4Skf-v^Wv&S;pAul@)&uM=_h#N)f*`p0dqMO%$J+CMyZd)U|By2-X;>o=A^b4{35cl3h= zJwdpXf&_)94^jOveAQ1*3ybGonS7JDRCv$S=;#zf0(BOr>xp`nuSq^xH``_EL{HaEJPkLuL|4=z!Z|zP# zUMj5aPXC}(*s~k`x18U-J2@0g-&887-K^V}Dxb{f^D#ai$;YNo%70fT?+E5{@#&L& z{q7Id3+l(g?^p2ILM0an(0({tV7OccFCnJMJYUh;M8Og3PJYGFgU(k&SW5VYRie`h z*ppvgEx*Xgz6*p=c}acT2xm)R!u3TeP^=8Ygr(We)EvFt))U||OX<)jKWWo^E%2P0 zSwzmPTJ@Nz9YX~#8lk+OF&i_9(ZKSjlFofjISqbU{WJD$P?|?+i4z2X$g@RO5`xqo zNmo%HbZYU0Blf311;+*61iRwap7{6|s1k>=A0@pSd&Q1VSey1lGc}2J8ku<3J`(u3 z`p;*O92#)S0poz&mpl*ts1U#dV9enu@f+N1rbRnuC=etQb{pJHGK?@vu$yePO{uSQ z-f+G-8U4E3*i5P~anJEuvNN|}x5`8G$T2;<{=5^4SmWbn#Iq&_6VDO5v2rUr3M9U1 zo_+MPKQezP(#j*}HG8%d8{dC*xH<3P&(hq=Fb0U2)-z6tEJ+CQd6wU@@*%c`$&_+T z3Wb+;c_ChLAvev(FH+oyCA^wR zu=3T*>X~z)yY9OG;$-OJT(IuaMd@$Cq4Ue?pVU_Z-wwc_K{2=xDf)!?A^8(bv4wS_ zixHCPs{PjRe4YP=J@+g)p?wRJH=W#z*!$7Fq00Qe&85*qVfLwS&DYHlwp#xU(lxNqG{0h|-I}mw>6^IWo06%5LW>|DVZvl>KcKKAI0-WNt3w|jZx^=$WtK{)4M*y`#>c_yMKzo;$?c#McgU0^@!2+V~G3$BJ1DvAvO zh5ggJW@dKb%$eFVJ=16o&o`U!^#$Y@&y2I0s?hVp&BhF585~>UPv^DQtA}CBJO=an zJp*rriFg1u=s+-2!begF1$h8?Q6vP9AMG1e37L;VRFPLAJ}&elEJhS`5>L@F#Xz*D z5&sDGUb}PgaD6TwDV8hgj)5A6uZdYk0~zWAQF`IrGw+`!v~NuMsZb=AEV>gTsowmg z+ntGo_sk5wzP0(#A6Vo~joDO_PMR@Dp{=IAf-Na6c}A3#dMrlVS+}89{FCe`kS8a4#(mh$PEgNKFAU{V>8uN3#ayyh^YC&}BE*h1 zO#S+p|5&Iwl&?dQIpoBa`M7Q^?PjAxUYyFuNzc_$Su1n~>1!{;7yJy;ASXHVy4``f zbr!hYbT)>!qgf>wLgl=3&5wRmW&Xx`vwfHGDWf~DPg~bt=iP~gwEl*@!P!&)-oCHNGwJv z207`N;>DGzj9sZTi5g`wy|Qg{D%%dmcfLboQYj&*nwb;xr#I7sd6h3Iwurr$nI=vv z$XiKnn3 zeM$BvbwZ?igH;kwMhVg6k~?5dxC6GoNVPMC*4a-l$p|O~x(|ij2quF*!4BOP|5@1s zoh6eMo*%Rso&dj`HTabS^DAqn`w4TXIGHqyT&WyGo)uzVg3Tmdivy?^RXhjFW)e6f zx`;OZErgzBlfu={xWlC`GLcjF+K180b*EvFqnA!EL~UZh7+EE931C$YyHz)isZ?`4 zsJwp*lqR4CE3UQjMdC6fA~%K$1^k?n$VS;(GBPrL54NFa&Vk@k&*_sWF0`=evNzM9=nrl0;TwSSL(Nu{-Wy+>1 z4cZvzNpcd9ODQYL8OY(+aKZVmTrunpuI@UHpF<1tV!90*Hw8geHjV?|@*?Z+wBp%B z*t8Q?!{T^$9BWoEOnM?z@CjBy!AYJE;W_lCn43<*feI@)DkG#qTG|b#YDCxpgQ4}n zm};n61XW!OM?7CK*U3gAe$kqV8b0_%j-e$SG=8UJhTfuizp?Y<&Sag#WbXd2P zAU%y-C4yg+Rjkx(yGjVGn2cA#mIp@+)Us62ur)7{ zIYoC6fe8jSjwfssdvKRz^eZ$;qD6FBbP{|hPy?bKVaiie;D7&B>k>Qw)J5$MW89@_ zxay&~x#)N-mCL506S3uF8LYnl@Z6j?LCK74ny;2w!Jpc>;S2~|0)=+FuzpUaYT>Wb zFj6?}e6~X!rT8W(^+C6J|G&NZmwfO1K;TqhT5A{14+IBcO4f|zJid$_oI;wfNZsTt zQUs!GF_&hAYs04ID=0xKAuvu8R>N^c^gow}NzYyxskiegc3A0NDw>KPZFlqG$CmBf;Bp(^ zVj@meAtN5PXY=V%Q~hMM`tncpBC(W%&j-&Ez^UqgAa~bJk!ey)Dw!%+jlSQ5 z*8c+9w@nnJ!~Nj4mX{UatmmhRf&~&7Z&{N>b|f1mHs)uKuf2U~Nqr}s-*M}f*@Gac z$1A<7wp`P_^1kJTBi}o7rm?p6_}2fleBYJbYqng~tBkve(xI6xx9-TNlSkJ7=!`TU zorvDc+P&DVdp3}W0D2f@$SXu-H*oUNgytAa<_M}yHK!OQ8c1oN@))Glxsy2$h0=;Iabs8w8XpYO-p$FCgZSh;g%KehtM|U2PC=*6fnlspH-Vc zn1t+lqfxi%hD)2)f0G-oj#sL`o2gQ=qN*PFkzY`1Ii|Iy47=ACYCd~E0$&!cCAC5G+yqe%nvw+vw z#(|#ue^2#D0<&x1`@0<~oK$tr`Mx(k@AIDg(_7$hgkBrh;2U_jDrZ3@o8+*Ip*~i;$bi(^%i=Y)$V6od_X(n351J40t&k>9hWgC zxe-}u8zQq^{$*=*Vtsx6q4neZt4m^`{Lb+Y-F3@Sk*1d)D|vDHp1UnGJ-HEO{X^@~ z_5ZT%P20D>Y1_8F%luq}ke^Xk->_ak-ihS4W?}vv)s4)y;D;^v?nYp@J;OMf2FJ1_ z`K^}St1}n?u<+evP7XOUgaAX90<`D0irE3a)fu z78M%0(XHBPVgoQmeQ$AmEJuY80J3D`;H8b(jlY!Qo>b?K@#nUx>#? zwP<`QmjFBwq26@-URI%H=E~XK0`$nSh#cHS@5*WMc4((yvI{kun3Q_WrH+MVgK@H}K;xr&vsmB5@V^V54z3hYA;S9e;oEnw)RwQ<`r!{>e8n|~Z(LK4?peKb z;{3Jt+LfzoCkI?B#_@kve+K7dY%^l_k&!1y{%GVG4o~t(L~h&F$R=>7#RQ$vvNHX! z$IrU+rqw~bkbcOL)B%5w5h+x2*o6yy3~Dia*^hu`n?_*`cq&$fpl}ZVOE^AgtzZ%J z42BtD3M&9nEl~Q~=V+2y-aJ@foC;c+@F&N@h^*L|7G5-mm%x(@QfX5uu~k>Yb>kXf zaJB& ziK^#~P7}3;hZ3X-=7VnbCmLfqU<*xU!Ko8qq*8#G^2YaRSLJo^(PQ>Gw543Iun199 zm=x46lWDNVye2r`@LsA))I$yhBf%%(k?B$32-2q8&~6&mZUv9;D3-3rJ|;;*cESP; zKt3kH1F6%90~FGt;>C_Y9PZda1eC;v^Ou)P@j{kP2VuN>D1VAz&iQcH*2cmiKqj=C z1TwB*-Z#m36Nn|5f$7}}C({OB+M+S7{fH;aWAXD~k#p>sNi74efP-YHr@mNNC(>Sg z#&+-|&kN+y-y=(Z4l5}Z#AKy9h^m34NgNjcpf$H3^`MM1?4c6^)Mjwf2$;|rqd-@CZo0l3 zidoxqk{HQ5L$0+Pyb?Jf^8QKubm6`6h;YNS|Ii z{p9;kA1@T-sjybq_@<(w0NlXo(}mNg*WSV7T4C+DdOr*0bFh!-19w`zf%w=qPz598 z?kW24EV;VGP>5rRa2j55&khp&lGyMpRB*6*mMnqnkga0D*&Ul4(qMr`*9-pbm&Xs% zL-=FmaHv98x{2A{PAmzNs!F_}6mja|Teu|IO4ON{bfOir?Zv#d`OLz*xK7GyG--tV zPJN*~KU19urDI92#*W&?k8w4_Zvg{1_7!Fg#*NxC?PRmgbjxYC-A!9h{fIb3WW<3Ni&$y!fnPCIC{>%u{N~W((hGJqN zSIFlVCJh>H#6gi}jq=%lJY~2^v*6JUBW2QErVw(TUCBmnraI3&rST*y<#-gq- z8pFp|?l>>_0zpN`@T{;ZP(|{sWZ~IgIf3DOP9Kj|)(`*jise#VO9$v5Qw?f&&ivra zU#Q=Mhailt-VUrA38)b?!`vJ6>9oWY7Q06LA{I&WBdTz^@tZ5XIB;M0iEe2QR*6?y zX7TQi-F^4*#aT*m!fx_lJfu#>dzG8xVYk_8Rpu`8GH-Xnb6bwxbI(Wb$rG|FER*mV3{l;xD>DrSevL?t)F`Aj%f6b$5Lj5o=Nv#6^S0cVfPlf z+>0xRRw8anhnx4BGEK&>p-a4;aw9BWB+VY#vipX^(a2Tz6Kak;0ULhC{k7mx?VIb} z`2pi$r5-juaA$9hibQ96?wYs8UZEM+r|-XL*X=bc;+W;@R(8KIf0>brW}G4n0HJv0 z)tdI|N}QLqqLYcHjLY)3?%sY~*(4QOyM5=y_ouHnv{%I5da65(mirK%yqjqRU5!QG z4CBuaVgCvq5r#-2lOinw1>@VB4(*^v$e;Kvsz>cgmt0Hjy6*DR_g;4Cj@9-phYk%E z+p4vYTfFOZqTt7l+<)2SuUcR29J=+;XydkCw=zM#SoGR60oGaa#ppFj-~>S%tV+ph zKR@gL0$u_PW3E zxL>dP>U_U`R~hGetkhm4e!09jL#WA)){BKENnvFt&#UiLsxnAK;MnTbCZ;ELKDTH6 zM~&YYQ>oGfMJ!vFf!=7OZSv_FAMey)ekiA%B-gKmAAB{jj2W?INYKM7h6EL{-ID@b zlntH{k>(-5NLKY0K-*YiXQ$=lSR|G==Q^nsV!G4oOw6YwFsda7jYF4VX`i=kVmtQU zlv3BW&fT4iJT$q>&>Lf!9XWW??d55`OQ(t{g+OVZ8=xB$PyT-1;V3B31_R>y3G(QU~^QxcgZBSC%b zep=-=eod*3Gg_c zRHFGTeGIBgsr-arTbb+j^0*EDlvms`-iPsZ=N@f3WO<7z8g))lZVDQ{SeuADwr!u! zbxwhtds5xaIB9_B*hlQ?ijnV*Y^Vq_XhQwGdbj$Z`Z#<8|5^Q!`WEpSalAwltqN!b z7zI3q4EbQtAZ)Qf1~P62ZJ*O-upw>15U?5B;Jfi4_8;LtmNT~S>VeN1~9x+jTadl-0QH6dBCbQvc@j|g* z2q*9?lU^3fzQMLZs)ryaYlnv$e(mAy?{a-)w*g%PhY2YT#Dy9Ju5IvfRZcWGK9__8 z6T(0;#j$?aEYKx<%mOaA>>*d3!!>+B8j>jmqrv4LSWQc&aBw~}!kotjBt?yvA}UZW z_2#ADE&-sKmYp&!ykuM!(cdIb;5?0rw%5z3gRp_`t& zjIR^1$6s$@FH%Yg3qI#dN5dGM&Lj}Q#l-oa3{z$VY#tCQUz|E8GRkJmqZCqiplPL$ z5%56BNlzkjG$B3HsI`wl^9GjELa}Rhaxq0#!^}Nn85B(dS+}fHy3_K;;?qVZV@$`# zyiwaOq>4?*2*4nP$gZFgxcn49@SPvtvk_s@B*e&!C_2q+)sR7% zBB>g3JwmfV5F{GPkP9q}{TNL+=@6hh*J&10_({ZZ$P#j?iG+Bz9p}uInKxBTg(E@q zqF}+vI2pIe4senf!yj^T`2~yd-E}AN3}z;i)1>FDg?!GDs|7rPR2?b9csZXUv83YC ziqQ&H46E+af*=kdGW`JQlgD{QNEczh=VJtO=o5sRj)Z|jJY3EYlri-QZE{O06pnY- z67Yg1)^eeg7GHKJH42FYdAL00nwUooX|8IBR zxeIG1ww*DrZ*g|*A-boG(w6-BQW$%FKBj1#9er(tk!U5T8HPELgfuB%0H!Kw87UZ> znH}O}!vBq&LZ3%KG!xuIZZdD7c0__v;{`uq++{b~p6VgJK6IiuMMfUI{)oU)lB}Eb zMBv1tS7;$3a@zUiqz#X+PwX!vAt&*l=%MQ96keAtL_*kx$FP=sjl?sN2XkxaI87~& z8w_tQ5f8@mY~eUoQw>}Ar*eFHX;vEHj(zHr{?6cGTHg|MSHwGG}ImXcxmIt2u!_mdron`=`#kt zK%{3VYHy|0DnBZ+)u!x3R2;Gqap}fS?U@UQO}WlUH?vxrgog%^GFhq;{sm{irR9R2 z`5`vlE+kvy|9s= zSQ)Kb5MYKY7w$czDq~kn&m2j$Pwop1rkj>gjg)uf69<>Co5*jSo1ik^%GJe279Q@u z;V^A|h!+CAKF}3u{G1*D3m+`C*Xa~9bgF);!2pEX=SM)V}~sx*a(csLKjeRf&M{#Xd@y1<)1R zF$_cR?Bw$DeL&4&UlZbVD&JxSBbC;ImAf-npn3{ILfR~ z=Yg4+b|`C8-mDfkkHBFzuHhKBJ;Ipy(V1_md+8TKpqmOKi)n!%7ik{MBq`{VlOde> ztp6)(`@sWMT5_sPK6Q6^X2MTuz*v%bVJD)ngM5Q-u?Zi8 zf0Stqo%9YL2XC5uceY*V%BCHJo*dL)oEwl@YYYg(wgq9ub702f>+YiV1rCWA0jzep2hX! zWZ4MeK{{FM_3@>+cq}BIz!Et+e9w^X5#8WnUznXeayL|E6Ia6ApN(<-`AE#V~K+A(c) z3cZYp(fFm0!@xWdR|v)N?V*1RNiM^|R;4%~fftJ6Rd_5B+B8tgf`&nL5PpVb%pY|< zMejr^TQGI?gqEdW9b$uCN%r5Gr6{wznGS!B05R+)Nkhw~Pi9Poof2s9kRGds;0>ew z2NdvL9wmf{u3{0_(jucUC6gs|Q+28fo`S|+(ju5V*b+)_v1-DrE9IoJuk)9*((J`J z1TA_b^4at!w`%b2)C+JYlKxC5tZ)QKTM^IAiE30}ddX>6op7SG)p#V82qoCr4f&Cl zJNAmM7t!Elj=EYrqV5YdJaA)j{&9+>Fp)Iw4(=cwBAZ*+D^F27sN!$Ca6Kf&%il*t%jjP=>v3VAs01? zTuIS9ow39~h!Rhswn+NE0U7+ya`VN)gw#1ohBih$Xhm#F zBb|kPkMqQcBOhqNN>$4e?+165wIGX$v}@!@x#pfaP6n5}Y-n7YIs-i<9QOsOv_08fU(D<`awz$#FH%#=>v5Nl_%RO=3ArRLBgZ zh)eAEeg~n%oJ3T?PCw`)Y@km=Y#|#k;!za_VHTlojH|AX)Ko7!I(yR>e|@&!ylr*Q zt-uw}S=gC^k4tQLQMTd1l^TS%Z;j; zq0x?zV&J1ka1lbuRrTgR$Gz!`mn^Mp{6ZA)9#nb`W^5FSj=bu>Mj0zFYRru9-+g|j zJzK*RBlQj&w;Re7`xNKtz83KShvJ3mmc_Mh0FJDSK6x(Qt7GFX3bHv_mpTwYR2U*$ zgkk$V;q1at;e0oVUZt7DS#w32e*JI)&!quLbK~l2r&xC40K$__Jw0A(6yUK3HX6$( z80~Z;yZVi9EKo{Rt5r*RdTHCj|CjO_wJvQUg)Jf+Eo3Ht;=9FR(p=+i{gnNk{(t*D zpJ$;z^&kDdXH9x_GE>@k&wuc%6QiXzgLv&H(b&^q0gneY6n6@XwrHdZw-s?ekNOgW zkSiPLXBvH?hOo3yHNbNE9hRaUWB{Tt`hyNTQS(9t+0amAaDq8T$BB{H2bBEma7NA9 z3jymXx^1wwJa=feL;cmDk83o&iVwH(-y`}ATrC8e zu-&wo0&AgaRkx>0rF6txmE(AFlyR-}89TgfuY2M}du{u$p{kL6ky;~{Yi#XoTW7}V zX)@1~P2KO5GKJC)=LWlac`Xvo(Vx_R2_nF5*mWn`&q0mUi`utjxhgRqm9u zgq@1{J#eMd!vZ-`3yr;?cz7VzQY>HrJ_Z4t%F!z9LR!f5fbFF*kcs z3rti$n|POzygevW6KaA%Fs*U*9(o?y=xINh_UL4qT?SJdQK7jp>89F_PSr{ox%tC^ zpk}guA^nSBOS2OPA}SiGIICNovJ=x%jL-n5^euHCb|o}QX-`ZK39w@hkXx7?8u-I+ zIG=s<1=&4Wg!}$W<9a%`lDc)QHrnYlYvbzBId|0zKix~+ct@(A@ip&t2PP(FTdLTc znGj9`8yoPS@F|2__%b?%y?EpmBlnHGX5{Di0%CI0yN`dm(n^w?1a|{^VJ-_y1KkC@ z4FCv$GiW{Qbr%SJWXi(p((Cr;UKJD1HYWahdp+aFNl;H@gJ*O_b2alkIm z%i0|AndGY0i7T_mdTMY8DhI^F1KxusFfKQqL|LO+)Ni70l)4gKb5dS_wp8jQ1?pGw zyz!F5htCf+X6mz-$>Q0@6EE6!{$&@c(DbVwpJ~jFv-ap=uq6kSy2a3YH<;QBm3kpN z?~~2>p_Yoj;O7r!z`)2S!gm}jyJ}{3*3A^Zlqvl2Ws92|eWRG!_>!@+G1HryyR@+X zvOl@Bn7*`l@yyK3+h#6JL*q;R%^CUt{U*4?GeLc)}saiLN3S zd1^j~mY|wuh?WqqhgDqO;R3iagB53=rP^uX-)7WE=1FE0EmMLa2II1?5(Gz79pJkt z!y5Yg2sRvIUN;~^V(}Msy;>dq&*=KQyN!*%01ecDZDn@livM)-&^Dpn38jwujUS$) ztEmaY2%dEP9Qj-3SW4sNmSqk-{N?E9=$AZqnC?6KhYt1U_JL|leCyvCMdDQMuv;o*xV|0{)itPbW|!*x+D@g#v?V(UHW682el(wUSYE=_#Pq?Odf^{UrX0GPbQ(_l z;PT`_2)q;iLAyi4(~nIq&omDnR39Dd+jevh0fQ_wVpeqV{@WrEzPCoM=kw}w%%ia6 z#3+nNcI-603DU`7kAkGHKDYL+N7UM%)>f~$Vzs8$&JaR4bJ=BQMp__)HZB`EGkRuZ zFi;~rr2@bCN%CP&29>}&q?4bR2si^lk1rhuA4rtTyu{4FdFgQONbt@Cx^(~wT*gYq z-h3Y5aBx{9e-?}faVd}@vOR7U5yv2CfIq<%ybB`=V@G22JjmUl%7Lz#kbh7kfuD)> zfh8ubdK661j`@byCK9hrj2%rRj#AW-io+=ts>Eaauiqbw<9ORzJOyAcOld_N3@7wK ziIDkK5Lh53qQEm|YO!n@JRsIDRSwEX(r2d_+7YJxa}ehHa;>&jt34PY=|1Hq=89vP zg}r+hGGoQLM0_e7F`bT+%oR(sxwT6#UCYguiiJ27PRLG|hyO+00CAf1;w<W2bdBUb*PjD9+4(r#FY>HzYYL* z@!yC)2fi)V(dLwvK8i>NCiL);TX}Z!XKugcf>PzWhabMKQo7*NTifNNJ5zksyJlmd znb$rxxVPPKC){YUcGaBHZXh_oUpIIRUZ~!8J{$!rqt=*FZ$V1uIOh9 zcY40>{dzH%&VRp%(i~oE^#iW8jjdUfyZkJN+HjO7`zRuYJCG(WJ=GraG8^zByy=5} z!>@mU2MS?d&(rKCN%tQo+F-|y!RZ@rIKMM4wRhv4 zuRQVy+V{+vFVTbiG0w=NBDfFQS~_=19H~tk!Um5*hqj`TMid`HiVuYAZTN~l@3!aa z%ztW!2{0@`7m*1Nm7RHFEL6EMwyZ^_J9eO?d>Z!ySjx_Oen80-V<7Uf)Z{EvMm{2aHbKP|M3H~yfC+_P`U1j;Wp?TsHT&eGZ!75n}2@guHT&k`S`%cFTq%f`Ah{@Po)7DfC4JxeiVr2xC6fF-(YL7CF zfZ7BK?cjO%=z(DM7F4ZPQ?-p}PCxqSX~ZlKYtKB%3tq0RJz1+gSv!65CuVk#AOn*y{9Od9z_j*kycUk%lI?=c zm>nHy+A)vGFA=?tN9W~UyW#WCVdpz+-RuD2y}nQ^+5`v+em$!e3%ll2cXy%R0?6`9 zh2DXFp;Ih$3MyOki=BR3y*mZdAQV|dfvr+14aJJD!ami8WDFd~3t6S)IE8wl--k~_ z7;VualsB4Ip+;DOa71L6*|4noxYe?()^`f|)k67W1%AvBakd0)n)wQaxm~*ehW6Tp z!tk+3Nf~X^vUE3Xx37v0djRToQWawHBq1;@9d#tHN5(6maxvOpL{#dwT{J)`M_o6n z%Fz0SRUR~2R6)fVns6P*b&gP*m5Ahy|ECksO2q@2_K^A%(RpE_6t2T-U}C-#FW~-> z*N?nqZ@3!E!3L|x*3BpErgjB#LfRonH&4IsQ*#ocR<6tmP z=_S}qR)P+xB247pXK@oNg%0jE)4S6f1PuPf- zo-G9b5-<1f-F4w>cheUq=I)}o+it4bT-O+NfnCK(hebnLI+af@p)x}oudRLU?^i2- zl?cs5oKS3WFsBZdUoqOPS1R?thNC_ozpfIkB&~vVF`yN{L~pA~ehT>{c+qFHC3LDo z6zUdaVG!ZK0G4Dqk|#jupg72vNq@+;JtLwbz>7)}KFIPnIus#p(^gDy^s)oEn?z5OyAx_WlJ_Jwwa7h%FiNU;^g zWa{?iBevHWb8~xY7rgx93odZCugu=O|NL8KSJ&=YpB~*(Fuh`{P+Yo5onF1&--+AZxW7i(uqN-CnMteJosbVpO_&Y~pwESRO-OET9zQ#SA zn{PL5lt$B@)hv`sPwFIkjQBxSqcajXE%b=cQ({-)3^h6)rx9c$=l!0+3K3swrx&V( zGg%6Ih4d=y1#dk!c~^55|WAtoJ3hS?4S@}Yu#b8 zh;wDTIZN;{D9v=>8}?Aakg-S}OCW9NVxT%EoJMB4+FIho27zi-3fv_ITF9eM;I&Ju(hN&x{h`y9g>RmE;9KHjS z0}Ogz_G^v9F_0L}%&;#-aet$^G~QXPz+yF~8 z+UX=F>${x1LJRzMbyv0H{_jo&8*UjI384T1|S~hsM80;boYb`nV@J6H*)QXse_y zGqOqg*ceVq`8lzpsd_i9|DwvNbXkFUqgWiEm3cjh)6Al~OZHTml&&{sXIt10a3(<6 z;ImVCiso;Q%EGMI?$Yii6^+x|1FVbk9pHq9+IUPgi$Lo=(nOpFNhn$~LDmdjLfQWc z=ndO}gQqj$aGCC13_#nyA>olmL@!}>6Z0U86H!>Lr0PJzfa;176R@SD0YyO%&;rJZ z2R(d9v!vtSfEfb9K41;XCAmZ5NeB#H$H6iXFH1(or12?hkQHbC>C9hXr#_0O(-wZS z7LZG=hgcT=;vNE-QI;X9Lz=`(c9Igd!g8coj!jlI4+$-NSe~VAGx^qEejC8)eDzeT zvwORj{dOu8Inh6`ZFc*{`)Wy2=;82du4IEkb>{p7d_Vo%exDvr;b?OyW`uk@mAvTZ zsx%#nZM?6n9&z&C@|MBGP2pz50=PuhCD=AOhkXPm-H*@wDSgl00}GaqXFrNGk!%mr zx82b}d$js6-gJm;_S>cpi?2ocr;~6My^Vf;f71*#%^P$=!3p|}xXx!klGKci z|M9LX|H&}#EZO&5K;|xOgvPq_m|+Zl_-)!aY&^Oa z|Lu+cNwj1;w&&N7asPbgzp5{)_o2@v4<#~ApsWytZkRb;RTr zT`f#JfiWIjdt4){+1{*oP@e>>=Vu?ikqV-IEqh~OY;5dRL2JU-6~|hWMb{e5z4^v$ zZD9$UD*LiTG@6M1XmzGkaL3!kdJ^qxv$gSJcVi=HYxu#j!rV=Rd^t9r&%=giR6SNd z7_35voUId(-rmB9^;5YSzb&zmelPG8c$PHM=IiZ>bfA%dU z(Trk-!LtiCC8z8q7>VKYFbJXEV}xIU*Q>imcsW5jEfj+cN+*v3U53grlR5<1%21T( zp>Qe2M1tQ4Ps_3ssRO_8wqr$dq2#SQk)L%3Cdy zZ%pl(1g@(W0bT7TP}dH)xz6T1>LY7JAA(*@CWB*h;E2P_FbYl=#|ghtJTKvR6>G0U zw`S4fBBX~p9@~#g(1z8T?Zml8XL7Rw>Y?D3T6+?zfu1~kJZuvPBtu^s)!-lxzXZ%y zG?h>nkVgh_<2X*OS#2cTcxa5|rE=ZN;DL%!ZX7-PTpJ!pj`oMdDkJHiI}YAu4^W^K z=p~pDA`!X7tyZJMRk$_*DYqGgvnKKqSYC+S%GmoNHo_;-s-wb6(V}>=kAau9=oo^5 zC&2@AAZea}WnU!KiqeTy<$tI2nXv+0#1iY*J**zScK23aRlCm9myhO~QOE5zrvEha znwPhKdCOJ(2*F@tqvpfcUi)zK{8p?{EINLDyw#V;-1wnZv4&BR~|jO z(w~@GBAFeFB!pbz`SXq_;n{fy6%r-`;Tsx1El6CO;O*w@dF!ct*^K)xr{TQi_(d1) z&!%FxZq9*?|M_C2#*$COV!wLz)#LH|<=PU!JM&#)M=#-yOU;Y$PW){C!V#hLHwQlB zfJ7A!XP<3(Kk$Tse^tp^dFFxWVbCwhXNfFOC;Iyiof(;F435{5^t&j#OSy2dZ1~oa zr)SF z!qu^TWCtF+-4nNNh(;qW6C~kBEKD(+cp@wo-+ovS*Au-9`+%5^5OOUxGJmqG-%qG` zwLLq!_27Bx-io_S$v=*5ay;Cg(h{T7y~)*!%W=02jb;o=%1lD7eDziN&)@M1qZb`C zI@^e#U%I?}eB)@voU(zzC-t@)FX;AMcx!87#aJ{hTkB3ZW6*jUv?EwfClWFy&;>sr zZXCj57@>s4uTv6(Vc49}JN={6cfZ)(c**=hD>i=X9VgtA;ok1u4edMDmYbK2gQtGi zS~>a9f$0lZr(=hQ<7+7AgxO-mv^yfbBnTzb=&Z_nvhwiE@~*3{df=+sr(dxDzzqjf z^)2nIUw`%0dj?b01L6b8SJJQt{zQENdtisKe2z+~j>PdLDJz@}!3&FWkd82wbe?-9 z`F5ej-h9TimOTN33_7;@RM>T=2@AN1f{{3pfLb74FcXW2G`Q~F=}M1Ry1ZhWa?wa! z9yi@m(M(Lc#c<4>sZPhgb)tItldOu*vZoo3&DLh(MRtyLQ;P1RtT;|H;)q)`6$xU}BLlv2KxD$85X4#=B7f{0(QX<- zveOWJN0tN=y=(CHL_@4CJFouei^Dq|!fVFV%O3dUPI-2mENUe-TU7a2H96Lpw-U8n zT9sq7`IKuFmexP^;_&?+T@Djq(pB1|!__zi3X|>8H1K~3XyqpAfW+brzfEsNxEEl} z4erOkocSC*#-GA^5Dpn>RqLu*P0Du=XVk?5lg=dHfwp zJG4KtXp&<6f^A-U!zZCU)76}rr}uCNl;7APC$L-vO!ty=2`z3DiKXYOTJ`$Tg=TZ%=+4=j z^|^Wlvf3;C@;PdKcJ`yAMawRv6Y+MM9%rdm@$aT;)#>SKO^wMOqwy0v&#OKAwvM-r|RsR;`lQeuXHEG17N(*-&uPK}a@9s{m}hZXpP#Afg-WjEOy zM^j9X0O$w?RYsgBK90lqYd7#oWfA(C*~a$rJj9v;T9?a~m12!9ixx=4d0i26x;9U9 zG2p|(M;(h${a{97gxCS{sc<8l2mVDJ63{o?87=}Y4K{@`%J@FgcZMI#H+-q!&zNkL zGvzqZE?p%vnk{t;IAT~QL9aLQxbU^G@+^U+vk$K+?BQ9qOQ-WIJ*%`O6V7Q`Wh$B| z(;-a5y_HX)CnE_}lBpmtvG4RB9g3zPwj-cKRTf1`YS{UdjY-pLk=aNsp)+m5os5;! zLKAqMfZp)Qz}b^=)hP-A{iSKvC=fTgAPLGDrV$)Cn1=|Pf;AqU3}vU`8v(JW#{hq! zvE_pygcGd3HI*z=ZNw4ydZQCGCM6-6O;B1J1CJb|KZDBG;V0#ZXczI%u%*+hnHnHK zj${-O??L?NdyFHfu$Aw{tv-p`I6Yu|I@zFCJO1!@R`Fth#wDze9#+p7`Oeb$_`)eI zv-9#LN@48Gu`TW^FcC~X+V@-96 zqa|&h8Jk(y<)`}2%TqVq)82P=J9Xj9maYsZTakQFHYNQE&y4IQ)^cT#(_I}oNOtZd z@$oxG9vJxm{R%(B*bkzM82DlbR}`&3&%)c8@PXfB%Z&PmEa~w(@G+o zG-VUYEba6gPc=uQ(NhmD%=CWzI1dk=YBgfcsRx(C;Rpe)1k_P(gi^v-A{L74cg0hc zbYip->O>Qi_er_j7G9HJh)c#{3tgkb;3+Bm53Pn4L#__gO9#vw>V&pQ5fMWk--RFb zskvR|zTRXrF=tIR5_6^QZo&rpE+?5n06*fm)V3Qo{bwxbyv_xZD zO*Dkq^~fJ_<<;kRh052>JCV@m@gVH)UYpc1>J6Y6F5mdAM&dx%x#3qB^5$D>1R>sG zLQ*KU>scRajHCXP_nJbI(aaPu`144Jx2tAWy^D~cyK%ofzU9_)Ec4Lyhs+c9E}Op- zG^IVePQAj-Y`i&o$%MMY+~V@3kUxN zum)c~ay1>uUnrT^&O%4}$}sW}pHvhLhK~%Z!R9}lIDDDmdwGT^g0zBU-y~lr&%*tu zw>x#q);E`$!Mo10TW)@Y_b+#Kzy8#9*Ja%F>n!6c-MU57uD$O0KPqPFHz@t8v&()D zKFgMy%JY8X14dL`5OVHJ$L_SXi&;{uJx0?xGqxuYj>ekNNF=&Dnfz7LY--x>Q0V%2 ze7EB?qtVBtp5;@H(~3s-g+d3ljq3<%xatnmd`mq3DbtU~TH!>-JQ9lmCvGGe2Y41| zKC8WydhaRt8gJx|xRiil;tiv&j4}*tf}aaShiFN45YIJz^(JpL4)&Vb-nYcO%3>@WeQP99#^d#R4Wz&1AE})}i0kU3 zw!!2?yMg0Q&}P)5t`-5#Hm{0?V~Z7!T}7Y3t`7-;27uk7z?DWlMDEmsleWboR#h;YZ@yPm+fa4Am<~UOn;#vdZrp`3SlOj|S&YE$RXZ#srYaAAP1Im z5gU`mMlImJ6J6;IkBVLy%)n3dOB5ONW2hN z3KOngN>BtgPSpj43P9QE*h%Gt>wrn5VHAUwN^GfvaGW~zbS0fm zILTxs4_iYg<}58bp&hHXan2rH?cHnaImfV9cZ8h9rAV{`)GS{~Qh=RK(;m@Ax7For zulv3vaE`xJpm7|JN#Z1)_gXBY&E=8fdhFJ;XRp~N1dC7;8|j#!EMcY7lHl~kYBUpY zf zhiHlbWx+VY%m%v5D1u&uR}#nzs^{3WqNT`eVvV#BIMUdNQ6+}?GgQ-N<5$Bm5Un?^ zL43NjyoB=kRHM$K+SLg!tfxmqb93QT$_ww@8TL}Cu)0z$II)bAMT*42ty+cTwkGj8 zj9b!|wU#W7W+Sx4`E){EbP-l&=B~Rk6_@6=%y$c3*3YSbMqbVm>ADil@`{lUAvFQ3 zx;DkI%nw@Hi11|kHfPMhq~9jZ83Zw>fprwO0Mt86WcCo)!qlH%F)8)xQN+b5GD(Lo zIA+FbgYDs};58wB<+R0ZLaOkDfJFw2^c{MSWr{a_p|_U>>NE9HgdWFUI!jMKyRomu z)u8BvEQs7ORhsgXB0js7Yet)k7u9mKEwL--P8rGR@ot>z8O@<9E@9nW)isbK$yhd- zioTYPywq45lUX%}aMX>7Sxl8#%ig_cSz8Z8oRXVd&F0bxadRnIO1e(evV}ybYt7j*#37XJ=1I? z(>X7nr0m!&Q5q7r9XIJvw#4`k=Ovc}9Yi82SfS_JMq=Urlx<{Ucu~d1U9{vzNKK4{ zErZ)2ab)%8bfJ*mc!xZy1N!{VT)Ym{gnWN83oiNSi#D~XIJv>;>ExoBqw!dUy>{mc;w}sclsY4bBY@wjF3}``g1!$#$CcfcinT z%!G|bZ;=NywYqcmpeN%Y`&P&t0PqRF#(rAC==;g`NvXVXt4;~gzq9_)e{Tc1w#Kt| zabjd0l*yG6*Cla0465VYF&BLXKyc?}1juZZ)N$a^cN&s%Aa32Q5LCm7Pyf`|Ne2#B zTW|$JWBj3;J7b3iqg8W0rf0rN2E}F^GH`V(oFfB81)m(7?Zn3Vs>o&>4mTClC8Q4y95YcMUrF{!#x zPnKcEFWX=lFcs`5-B9d`lhN_sGLcd!1pf$&BVO9J%d+^5vyH}V{odJu(aH4PWT)fB zCSuvqR@@zA+Gf9Rbv)21tx-QZ5%n$lZkWlOrABAzZnBj&uLLKOCftk~onHB@aHtgZ z^m1AEqQ#I66%HsnJ}VS1($oX)IxqMNnMioOK3lKP&eKu@ODYjx^v5jutn7R;-fU;x z@pz^)>LwO59cyuh+UGPi(bOBFL$|gkS7w_wlskG9mJrFcJlBU!BEqY9InQPt#6Hul zG)&Xnh-{h&t%R2X2i}*-Y|k$Y0-@y(W|`8cnc;ij-E1gU+}nfpX!+e+ZcKlxJ*w2M zoz>OzsR;tgr?j<8wpl^lkj~=f=Faipo9zwu0vf)r9)<~*DXr@>+hK7g~PfljD z^m%S>JQ_}~zH}b`>N4#T^40PCE~!OEiEhCa6OYbbk?$&XQ$&Tcd>}nP zxslscve`>=D^@p@7ARwCl+72_I@?-ZED@#`(C`ie;rvSRZWu38 znBH|m#C~iTN-cu9e1WEjJys5xmr;E|=%+dGn4nlHT9~J7pkMGS?z^$ssUF4Egw>K z4Zs@q0qja7mZ3jGuK)*06yRMbWw&5>IFV*^%jo)t4rW@J5BuphoX)vSI-mEh^z%Ng zacCGBj_k{+O!&b&?s#h<9dMEVnYIRo&m{6z0WY!+I`!(27jZxEr>N%Ossx(kr)!?f zECW`CG!`)KU^}?ZyvL^ClFDUfkOwT^AfV?VDv${c2?N2j;Cix5kkW+5n&81m`+KtA zK+TkMxr3A=MN)r`WUqt_4&+# zSI*p-O(nA`O%shmI}P_-=2}_;?I@AAXB!VN{_{X4W_~~W4YJPdhuj3<|d&;DaK$)`AZ?r!dN+^^L^QF^`oGhlL_a|bPer+u@j%sa zuAu8K;fJ?`w2LM>0770_Y(N9_2eE|}+7oCyuFh28&vuhuJWa=Mb!~5X_9gTzQ0AMC zUOAnNXEwf|_UQ9lihBn$Ct|66opWA#jm%f@hiCqkIrM5U{wGJSC(?R1IOGqG{N~6X zkNgu_wW{iB6!E=@{l|ro{0<(@Fr$OB&64M^|33rzZw)9%4kB@KV~2vBGY)*G9)m%q z6j_5!M?XvQb3hIQ%Ix)3|92Qe<;jE|>LEh>VyPIzkusy4^Uq^LS%BnFO@Byb+O0&(SO2AmZj@4}in zWk58bX;&E7<7!m9<|DkoHrI@E4818?8{-6H-_u^LVlkDYc@kLsoa~Vj=p26Ph)kkjs#MKW( zV|SfA_6v0@wr6+LOm2h{Z8jKW7}3!E6kjG^wO8aoL5Rb`^-0q1->6Sa4we1v5{LxUV?x28Y&XrLx1N_ zjeKe38zZo05-ngFautSGi0gvz4?KHLd1&TvK|~So#5TU<1GzM^2U`x8Am+H7!`NKA zBijf@T-G5XcpdCNEI5E*#+J8Mu#gQnh)~rCHqj5Zq_>$KY{A#qtYaDOKfGbV;m|Ac zF~OIWFHsQ_Uc4J*qF*@CtMxm+r(-#lC5%TW*OMl&S~4wj+j=y1n$l1^h0*$`_XvLGd1V6 z*=!VrtMALEGuR_uI+Mw!)5w}k+S@~@%_O_HBbzmK0#sK95c@;+!YF;jfD79NZ{r7z zYPC*Oy5^=MshD<+VHQeI!-hxapn;2aQz;<1GmRQHj$SH+bU$rJ?};_yu{u4=>XlkG z$!Qha=rHknzk&{XoCud7>Qju;H0A`h=R&6m^u!mCnOb@8!Td||hhBOi0iqr6%6xER zIrA<@J-$&peE41-)0|(BB2`jSVh@Y^Lbnh&jHOu1!%ARl z>`#ID$xCV1Dd4mJ(-8@QaFnJ@o?-cGyYDSfGNPR-7WFhHF1@^c(5w+)foc5(lZ{G) zVvw{~*3?A3SSkuToNy8v;f-I!QFq))`fSJ^j7!-gILiJXOg5_Z;@SNgg>u15k*0$p z-VDFJ*3_=Bn#p9MP-#x7=`F?lUuG3G@J>CN&*Yg*;X0LxnptzeriXKxe6&8{HnQbx zHR*vpv16jM{}*3A0wzJeqAU1Cp9aDV?hoLm1&R9xyW@C6VZNPBV6xLe%6%?Mc_b3{M{ zf{RCf1J~lLh>|534P*$2G!afDUL~cB>=&$=Ly4S~jc64CPRO1^?GmhzqXp3x_L8Hc zQRXwgR6s~c9Yi$?fcqs&)#V#fM=&Si(d)_vfdG?nC99AY{tz>t4S$c4*C}>1E;@W8RA%& z*vuKYVqMzj=~~G$=&~Y4Ndl%@2sI!aVG2`0YB?}c!huCET&mX-$>mDSjU*0YSJ=C! zOx>?7h|dJ~a|ILiVeo#f{sm0Vh&OE7o8gYP{K_HV8sZf#)MRP5V}qATsOH zf)=yFyDyn40vy3S(4FciGz~E)o5HaIaN;xXVzC-c0~67FoJTL}Vhz9DP# zriQdTq`I-%h9CF^3*3fKBJY-=1E3x1JU5SeB|0TKkZMO_2uWhaNXjR{`&oGFBWeN6 zuRpMhirk($b?GzDJlVKdK6Z@CRaN_)-(fcxhseP{t{xTZNvsF5 zdL3W4I}(b+E%ravZnwWud;Ia5I&$BA-Qq2Uk6(7#clT|4_o}N@X5)uybmQsub&f+0 za^xtoc8u>J9S_pv#JkklJTdZlgm56k{f>=wEhq}9Y?XYsAS=M4Y6L{66yrBYMZU$(5Crbm#JwCJB>)Mklgm7QGp zeAtg|=h)vVwPOcU4~orPDz&;ora<}n+L}^-ckD}qs8X5tPE6c?|J9Sr_fuJX`t+T5 z-WiRyg71*_OF0l9g4PH}TiLWre$8;x+0^jGE(H&q4U3gUaGY8zQ_s1!?Gj0+&cue~ ziWY`Z!1!QJ|%ubw_XvflVth@@+nX~mi9W3 zqH73n`IYK(G4n|N<8u3g8AWk$)4<#^Ft$miiDe-BG=Cmo8ZTKTB~;KxN|_Y`!P!YHeKAvTWg&M@mZ@x*08y<-RAo z4`dsBNlwAnPRo>c^3s_A42%&WM;k6B+>D`nTcZ%OrLvO5h3?tLjnZID6L3$|B@bo6 z9%%{KK4Byy#GPo{A_*zWrBpYRPb9+$%uAU1fYeEy6uXJH5huP>BU7PgsOQ#4Q4U(1{*RQ2T|0C+wTQNdXl4C1hs9&Q@JS94A1I2C#_* zIu5RJ$B9F67%k)+$eTjNXe>t*fJ_7PgX5Bx0?|ju8gOq&0RMC=aoMw&etOC$7yKj-@{dSepPxUq@CyrX zo4;GFAJ{mcJ}&?N_>a;kH^O+cPANCLS&I%_~aLk8rYufGcepCw75ZIJ6vV76 zZZfXNI=L;uQPJ$eRrXTuw+UWt1iPSPH|q;1IR9O5JGQcNOwH_k;cdI7p%8rf&O4ue z`sk)UAI9X90lIBFtUQ;%pLd%?lGCDGadQaodNRNvb?f_H+ZJ6+p-0a=i_(NvDgbeU z)8PiPNwWd?FYs@I9fQRnbQW1bXnxZ>!Vc#)O0k+OCy6P@xA!#~;VAj}Or~&uH1EZx z+E+|%obd`o*z%w;@3u3exm(QCXc*T-7bO5^AZQD*nH{Aja4zt^db27V3T zB~_Q9+o#lQyS*9)c+s$OnFlAb;c+{0-P^Z~I-@6u;Q1*(9~p~BY$xO;{bFc>b_RAK zT#t@*nlm$L`Zh02w#LSy^Ujwe?#t2JerP>hfBV~+`d~CZukPZS*STI9ByQmNZC($$ z5ud#tzgX{X>DF$#?C|~z_YP|E`i7$i)_3ij1BjP(bCqpl`_HT0JJU?$;<@rtYyZWC z*AT}I?&&k?3GBA?NGcpFZQ;zRCHLj8 zE45<&TqUJ$Z`^%@wtU{*k1qPIKWax(i=CrOdoOQf@u|qjxFbrtUEM=W?I@f89~t?* zksm8SkfKe8ztrXh#v7V-=vndDAZ6bKh!^Pa#ZH=Toxu>eM;sNx$d!pleD7BQgA3T(`^m z#({dh-?yB6<%-KByo9Wq-qY!piXzPsbj8AC@ACb|`zvIMXAMNEXp$)+UEyV?LsaP7j zSFR*u0sumxfKVCyv?OF3>LH!Vsa%|Hz&MNckvO5H7I}b zpqPqW|0}fIZM*|IqF;Ay#D#nfvS-X?6aoV~&^mfVZX}u6%o`$}aB1vgex~t0txnuC z@v9Sm&Pjtm9?6&=PalLK;ox2uAOB`ncFy5EcT?YC-&5(xPRCUlSM0_<_l`vsf$* z7MSc*1mAgtk;d^+1Te}$=oq0;mE$ggw%FZs`Lzn92fi9{0*pY*wxtoSUx$l>1>Zrl4Ofi0Mn8Vk9tii$Lp969f)rvjUP=sZeuA? z*&yy|QPYZ>={VRPMY*16%C;Vt(gs?tl8?H|@d}J1M~6{J#<5se>aDuD{|E&V`=#QZ zB`q&C7ls$rTfUEzB~3t}UYl>rap$n%Bj7~w<1(}|X{;>>>tWDl1d>^jz&rCVZKf!$ zm#hZ?Ly=%kOiz-c%h)Au0=Xax^;@44>zsj&@!CB8iYTXqivew!hRL$JUDO$_?h5D+ zRAN10ImTTizgTGE;zhaEv_Mia*2&AE!(SXiOXNMdEowQp1xVVzg5`&xO}1x7g|@p z;SKlQxBcx$9=V71IiU+V3cH!F-**h*K!yMa^40O5`j7xPx6jG*+xwq;P=3@?yIUw0 z9NYfH=RVi(pA3I@uHos>2a}e3o>5?b-|QE86v9%O8F4Ab$c(CD{)!)w0LX9Nbdxfl zi=3KrtYY+VwQ^6n2q^t|Z~kRC{LANzoKNqq?CcVoNha3E``d-+jF9&|i$j!Lhme_? zlE^6_0I&{j?^9>D|LNN6giu<=u9cU31rHGGpY{fFhCOm1Z$)E#9q}i$MgRzS%Y|Of z9>cpubzA^)1UtXZCGj!#5Fdx!gQlnpEj}A_F|g8ctytJ1>yf4Glnp~mX!<#H$56l8 zJ%l&|fPqN*{BGUwf72&*es3=0?PMlMQPh|d%fii}$p>0cYODX3QrF~kK`oSkDWFlq zQeT0Fuk3frCCz9|BUP=n!oSXK?VD{B_*&4a$BXUua=ZN|OpAOo#FBuoUWHc?lrv9&g z`{iH$w_o0V)h|AA)m2Z((;Kju9W!br^tdLa3B+UYVB>H-4)-}i*vVK$-F;7oY6#Q_ zmqZ6yFNsr_dIwTJmXHu-Ls(s&m5nXr}HLGTUo~r)0$;_xBpx+IZVU3%BGqBG0XA9IZdE1>ShupFA+2oEMQ9A zymjG=8Xno`ZQ=K%0=lMVWPORkbMPJqo?m7dWL*lgzcuT}9NwVXmKp+&NJm&&@2fAP_#NcHE+kfC| z^Z&y>T2df7*B#vyR-EYO(d*>x+uEy+v)X>Q{u8?Xl=0kWy7ei;cfNfG{pW1C z)z`FstDOCpOl7Xsn%n-D09U`h@7ZVLelWVSW&F&i27TZ>^AFE_LOsU%p9a6QPF>48 zSVJDh#{j!$sOgK}kD6n`Y9nq$?0y^vs334qX|NcJo)r4^HuZ3|$cU~YDnHspXoQ5% zqMNXIE`@azSx#jgr4+R^JK`qGhxF?fumkqw)17U!57H&4a+jUm12Q_>_ac*(&g7}% zv74tGNpArf8OD)WC+1*9a}U%zDbj-k?h4|ITv@~3xV@M?NKjd_VGXm9%@%wPTk0Kt z^U~6EvC!}g+XF~A`K383hy9tU`OCw2;^ISXO?{yTq+EO7>E&$yF%kr>y|m3Lh4^(N z2OjlZa2ZB~)GV6ytU_;;Pxi}870oGEW`j(#8dQHKUC9P9poGLC$m#?O?i^lWoDu))^vQWFzBtfNOoB<-N{=ITv=``CbjPV zm9rx~Qp)Acaw^?S2TMiuvy{_IrIdLf79pKw#LAMe@^;-wnR!y2{_V35K6sW8o4KdeYCieS z7r*53cinOO6SJ?n{PctOUUMZ}=b>&e<{$K6S=omaea?Y)aCe*fs7LqWeIZtjs~lBf zgxdt$6Tb<5aI|qD^5=AV-S6z2!ByUar(2tyhO6IT_41X;X0re;vaIgfcaz=DR+{B{ ztDJNfW`D@qyI1}CJMMhRM zFVah*?@Z-j;O}0`U5)ilGh#k;eRQ>yjg&jHhn-Ro82h~k52_Pyw(h_3+~(!B-Cb*z zy?m~bF^uw|XD?}c!!NYp{aRh}=8_a(21HS<)LN$>{A6amP`>j18`_>b6+zE+F$)$`hqG$WNm%*9$1dl$j2N%x&+(oDMZS31;t(AYs zeelC0ec$cQ{a0>WUAVk-pdU;h*y^fZm$4ytV0+_5?e^+wFCFczmg}b#ch4g zxU}g9EZ$w_nG8)$AHx<<%mWzI(-I&XE zdwJusOlEM+KP&rz)63VEE@@meSMSFcV!JFg|7~qv-CUkYQ8~D@45quaaPzT+A1M}3 zKd>~_ST0W{4YVY5(4Bef;iIlFcLwN5&+7-ylnILLW|(D`P(I`cH=rtqhwkp@+Qt~ z!O<7q$>XNESJ&4ra`$cRJ@`If-F>&y@AR&nefB&rEI0p6KZH2RmyJ?+UtS%mY;K;N z(dK67*OJN9%5+Ac@z1&M(yuS*(dVA2jW3?8xo}bBbbrP;1!6s zR!Y%>o4M(pxv4Mb+T_tY=8~0OT>Jqi`*W44v|XB>&Mluz%(dtG(e@Z7 zd(836w&rASC7t-etM6_%(Ge)5^htL7Dt!CA&XGbV z^fFIF>7-4-$UATCCG^xVOoKB^08(hKFYLM8-a%SN6S1VYDOILS6MA5SH$3@7LhZpc z@JL*7yfduvJ~$SMikd#Xs2y?~NVnwa2Xx(+f*D8_gVUb3Z_V?LT<&>C4|(2+X)kir zA{S9}qt`_udrpF%yTbEsoQ){&;(-^r!F5O%-)%Sa5$ww702#L`^$h=`F-MSkM~_E) z$BYnP;6Szs%>k6TkOceBN`|Y(dP3529P3fj8Cp*CG1GZ;GCDfEifb`Pyv!HoV+(cgEt^7RKi}v4!rq zKa4CMqx$=8=#T?28a?T|fUp7cPrx7&-sllf0=Pc#nS$tG==e+YB+E>T4T3i@c02*2 z74!zydKRLN(A!XkAZ$gxR}tI+`t6O)7q!b9rhsE7D|Kb{OTDbBYxQimI;TYrrt^~x zt!W%wNP3;o_Qz(+<=N8r^2zyhs!-a#O-)W)4P&}AH90leo^GnyS$qqh8r~O)A4qtv zM=GXi^4tlu5Ra=klF{>;7KsXi5|jLV{3uv3gjmt4ha+|& zaxr$H1fUxNzzlej_%?fzuOy5fbQ1WOWzvU5`NHQSDwj`+fIN$BC3!Q91=%!y&9k*@ z{o>1@^w{g$uw${lB(N=FbH(*H%;d3mZMa|~CZ*7%IE9PXSx>}r8Z@0w(h6dFJOf>A z#2tN8H!Ao(E%+K@+E0O8#j{R$K0^vPHVG(&RJ^H^{m!cv!32tq$RR6U-1FieSXo=> zk@_1kyEAc^RHAk&Xk5BZ3cq2+;EiomnxlmPIjX9DJ57B86@^-~z(VXy7877*@;At0 z8SPMS0JWW^GniFT79?I+*(>&mLD= zvJzy|UBDCN!QwDm%OxU~Mx@`e=RPy9JGoT+Qj(Ib^hLrtdJ*v)Q=8Aj-ZNJWJVGf) zmhv-Zl#Ij_`OX5C=-}*%o0)2Pwl=C%qE>0Hl%YhhubJ86-21Z2K|PlCSXoQNUa9^F z$hRIWXYZlBZ^4UgZM9hwoG8LV^v-W;7c)LnFr@DbIaT3+X!R_yO~k~*L1JP&lMg}x zPbt~QP}))NEfz+M0aOH>RaVRP$s%lN7hiMm<^4wIMQ0!T(BFS(d-meh-!-CjF1`Rw zEhUGHL-*Z${pCG>zJ6-YJ(s%1=4SNV;mhy2=ceBN(XWhjMymd>vtqsm@9+xoDx^vx9lnr6%fFY3%u& zFH5AXNLDs(w0r_2gO%o-NsvS$l^9}N&$?P_nkql#@APWrVZvu-V3W91h|SQ-VK`Ses2C~3K7KOJ-8jYh}GQ|&Ygy#SFQy*g8k8?T(R(mBBGZnF}- zca-ZKo{QC{dlU%{eBevExj1bawzHU?xf9f^GNzUdE%pj&hzB%n4h#p zKHdd;X}2EpuKl$89;jK5#bW0V!`|*b_iuR=uvS0k55stbt^e#_*6xk%tM`2N@y9>= z_4YDFqhoCByJr)rD>;6Ji9~5 zUug%6={&IFl3g7dzG-uWZOxFh^qT4<+B6RX!xF>2Uj6 zLz|_*?sf+9eSF70caiN76x|f2I=}DfM<0Fq(J!pdraN=1bDi|;MfG@WZ*H%vpE{+x zyokkLupyfG^`=v>%iEtym+gWhFVju+NWp2Q%iG_emDz8nXIJN>6vVr}tWMDSqfg%> zAKHa**XiAMYl+n%Nec8$sLnpHPdN1wCExd-~Kb!gAd>rU!(`` zo_Hl5+Q%k-f%_yiX@tZFcT*UkVPd0QFr{r)45ojVPy^T@Jm+|;!hgcm6M9(rx5N-` zvNCp&g%aaIv!FTppJh|l7x8_g-!L6kq@)|FUvB4C?M8ZrJMYOjw+5trdtU5(qb)8t5lo*Pi+vND9oHWtW*kuXW0;6fjFd#?v zJr|0=a?I(f$>>I--`z^YGm*7^W6_Ng9bRno*CGIfwz~bsMj$0Q^P_SmQ_jpl^OsA$ zU5atRbm&kiaSuWa-( zlNdT#1hJitMd2NwREmzT+4iD<9}v~qoMlXAx&?@S_Cfxv(F$NT-?xd1Gh!&TC+KQW2si&(MJkNAOm_B$eKPpU=-`M$Dd|+Y7`)FMm}NXsr$p zAa>r{apFd_XsR`HXv&znc(y6zT3+6}1aH3ebAFDLuGEbNehg-PUv!(23vZ z^%{{#sb^WOqoX-+sVkE$*KJ+2Jl`l-W_GwR9g8;BXM07Qh^dR(6cT_*YED3~y0!g# zb0gPXs2f-6-qhmBSu?pfJIZQKskS({sHMjkuLXE%moGt&FM$pF88nPn5-Isb^(pl= z0(!_n5Ju~Y>hMe(fkpyQmzV_dk#rVd7BYE2#Dm5lSw$d6?8dHq9?mpA_8IWl0mw~W z@J~#FaCdfP4vd>yk!cC{GG5kkMPc5{bR+Rao_j!@L?q+bKo;-l`_e92zqGL|Cn(2# z?qgo4hQxbMF!}F`}!b zyXB9zI9Pb{bS_H-*E;@ec`)Pvv`Hf*5bJ33goA9-d`6ZmR71i?^al$X%+JvL{D z*b$=2F|hz$$RZ=#MLi;Kpe2sb`^ghgYbR|^97W5rlDd_rWc<*5x;k1YZQaN7uV&yXFJb2b5QjL2L zZJk@eFBpHFA|A9D2Tm9E8&A?za^eue@}G{CVG{${9^MId;KqerZ2_i{R1@LkC5>Bl zM~K+b9CiSN6#SCUDn(8Nn@^IU6?Xvs(GX@fKLC||dcaG;Dk{uzNxy69)PY7++SI#^ zV@bxyAfYG%=W0{L!pYWMqeHNs3)YiF0gXH-X<6jN#(>l_o*_3Ob8%0+G{e%b7yPwj zPnfGcN=+A1Gxbi?E_C8x%E8ZnhPnd3hCcCSr190-Y3*_C)0}+hQ)7VwW+wv`Zj*Za?O>64Q2(6$8T=; zMb>X}4Le_M$w|wbox{jU$QNbpk_G?5179_3`A{&h-c-JwVj~_c{u=6!^ zWOeu|XiH$3Ov3l?#A;q0XH zcGh2@Q=#APHNyfVt!8U^ks91`CkM-z{ivQqik26-zr);U0S72vM$vMq+?^XrY-0dk z(r)s{wfPKEkjT=ilsjo<#TjQe7jXF*kR!x==k$$rHdnD@@d-JfiAVj=Z zWD0;3QMY9oWD$#lf)qC(Cy^w@!sWpti9EueL$XrJ{Y}k6Gp|7~C<{385{lzxSofuA zN={i(S!9s`mXpXDXXSg+aL8VckmfU%)ZHtT*Q|$QtddlLLYjbWBrStN4X%}fZiZG( zhyKDuh_Sq}O!D5c1knW1V7+PEo{>zYN+6;UD`adDz@a)z6tpMHKbiglx=6(19{E}h zq#F>)k*y`-Nj?huj+2l+=b_oGrsQ?W0Go*6ht2#EJY^ zNO1mfQv9PO@%l+mh99br%Uu%2L(ioGHFyu)MKH^<)pJcJp0p8m0Mihiaz;Bp2$}mt zUL*C;EIizA;JPR;gVw@kBmfqS7fD1JLSVMWr>H(AUq;fq=~}JF&~h_4#E}q5!Jw0b zW|Rv{ty~N#Dy_;@@x*H~5g|^G&g_rHttdx^am7nBI#H|m7S$jvRrI?B+aL#x9~@pF zPRV%J3Ab6Z>m=YLqTt-4TB}A?@ucM7ilh#kS6(3<7&4NqGy^vsXl}I_WGjA+%9u(m z#mGBT=v-p**-*j8gvOrxNOyx`3;lH!Hr z7{gZKjkP;81$rI4FFU&^$)eLScVu_c_c#T<%yF!kZ!uG4gpo5X9m@Gg!ZqmZ@DA!^ zn3JpQsDcb!;eP@Ai*t;G8U`0A`DcrW97!mInj(fUHBJ{SVraevz=YS{UqZ- z8C`S6io_zZdNBe4s+=|_C>TIl8W@n=Y_bvcc$R!Xq0_Y-H_9^!e(=E=5u;KyqYU$W zItyHx{pC9h3F;bff_M<4%t^Q{xaXc7vtuD9_A~7Eaq3OK1b@dcfXD>F70Mm43gjU& zZ@dt%$Y+r4g-%g6g&&W10cpmUPz_dC*Kv+Y6Rg%qvauC3mIN!C3Knp_c=ORSQ#1X> zfjJ{uDF>alJ#3K2=|>ZUI)kiCjZ~&p@>4c+z0jgAHfA*}{#Y{&p-?(iTxir#R3#w%p37IYf5Ld3JY*{PvQne9TlfG*aWOT_!_`Snb8dG=_l>@+)@GmEw5 z8y6TLjs%^@`0b~O88l%MUBc5&`Z+-n+yxT50xTmBs~5f%TW!S0FYxy~5WOB3<@M1A z4(&Z;nmnvU-ZoW#e;q+Wk_DpX;NUBX=A^xq^k*-LXbwg$3YvVxYABDW54fvKlPTkeCjRg zP4B+qiiP_-KlZ7kr{DGS@65iYboxK%5{XcAE6{_K0oAxp4O8oZ3?@oM)V5!~X;ZvfCh*EDT0J*@Tt9gW)r-9eOgQMvsdu?qYPmM@3ug^dq;c!YXZ zAQ`NNy&`v-iOZZ9WtQLEC>QXODNc?K8*@SUQeq}MFWKE^59~#c{A9^0L2&C{qKfb- z)a+{7EJI(HDY}sFpve>sFV_oFJxvSJS(x+?`p&iHn*I_yHIpnGe!b!A<>XA-K4+{M z*HTXsmRc>F&MU2#3c9(dLCGVnh;z4;1*csy(^achgn6g}^ABq*;u`#kb#W51K57b) zJ<`u3p!A|qfHt5J>zV&s(!OWl3C&qyrNOo%w9b2`-!Ms)sjIDJZY7hMYUMJ zulrR8a)+kfu>G>xBHEcQx@NW$$#yhV&m<}U<1>cS*eEaE+Ph)hW_e$HFv-t@i^vFj z{f6GHOXZD*V`Q31vy#ZvmDb5dI$6^#rpX*`nPs1*IY8H``g*?~tL5uS+=>-HPZF9P zeW^z&;h8KsT@K56Jh7STxmx0wk&kMTw^}L7>ZQ=bqVY^39=oKPP?6qN9d9I0@jEc+|Jye7>U&>5d$oMu>+J<9J>IkX-zHqRz}J{)g-J--XC->3zTL6oC)qg zz9ROTiN@a&(qn3*Z9*v^wua=3OZn7-CaQ0)AE!-ipAYb z)D80S;>DC_OtM|Q z);Hw%R6Q}{`D`?KXhu^H9Om5c)oPFF^{u(KJ8sC)drMS-U&IZP%O&#L|G@El+s0>E z<@`C7d_JByGNVl45cMW3Fb^M9KPxjnln|@rASDsdl)MD#GCoY$U}YKElI)aF_(R$gAoFnxj+Pd{8psJC?0bA3 zK0;fR!*Xs^G-ydcL+IG0?T`@-$D)XQ9&^g>_9W+rhS}P~dp_9IFfo@GIqyYG++|`> zO&k|1ElXXBV-3O>!6%rj)U!k%6b3U3^F&MH^}*`XZShDs8=4eSBIyF3p{;)njgToW znlTO{ragOtgg~c830eY@k=%dTiG!*9B$aB&#yWJ+k9x70t)@^u)!j_e*#2EVWtcNv z9rS&DGf|JYX{&Hk3tV;~fECpNhl#Lu#95`qiMHiE4>vt{ELO)Q zLl%M!mM`&E0t*mJ4qXln(n{jZ!Vg7Q#W^gRp6y`Uh_@3ZIf_jdh1k^~tda@3i?JA4 zV+F&&f=C`ddLWlzMNTJRdv!}N`neGZve%mVYN}dEm+rn|QJ6h)%094ksA_nbTcFd0 zJ}Kd=8tgq%?k%0=HlV}no|h`2ofFAWgk_?Blr%f~(JG;35uHr;rx0(4KsplcVE z6dPH6ik-~}j#I+S+@J)uAap&VKaDY6Cb~*5K^2<#8blz875e`CR(z7@oF@Fzmf_z6?#jUmG!qlG8rWAN(PBUuyx6c z?|kCLv;N88rN@uI^u&9@je+ct_|zRw+;PVx>ass;w6?!^{QU9bvLv8?XUNI>MRZ2N z9#6E#D=_o|%p~#5tOPboB_62|;M*JJRFfo~?(kQ>dioVFJ9+;6`sp*TKhtZ>9r>JW z?QMKjd+_w-_gmeqt-f{L#{M&B_D>%2i+efFF4uKkkglxM3(r}&@g|aPi{2H+0&*d@ z+m8EY&R}hp;3R1xKYZYFb;rBjb;nJIrH+=m?NzzTsMFk^Q@27_jS*4V7vx(hYD6`I zBS)3JNT0*`V;GlTQeSQ~lCc8T+1Den`Dv8$yz8dW+zc}ti*Bf}PWwO6#M_8t_oz8^ zncRKpbJ8jR3`kGQD@4uCCSGw$#9fAjQA1`OPy<8@WeZ;e_bO~V62sy9;g>)DWaZRa z<$=Ux{6`a&$;6YkAOEL>{r>W)3LX>(;_xT!zxlpB?EgL9h1Bu!E_XgzSvy55i62e$ zEAc1!>Vt`_{r*bD$tI{r_@r~w^FEjFz5Mw*aHl7p`7I)5pCSvRMkc`u$efGAN*)Ae z!qg}(Rl-?GW^l%y7;*bz+P`Ci99~I-1GJyL2^}@~H4tIfz3iQvZ{DS(OWoQfWAqN=-pO9*LYI z$?XsQ$oWX*yu5PL#+kF#cKi00QLm`8&E^%!RD-nrZl=+1tgNJgEQmb`$AStu7Eba~ zgimNB;tRC+o3k+xL-bG}g9`F4{?2p$QUQhKS&3atD zZoVC>pV*i_G#p-BLVd|XYvz#SG~22aYdDC?*-Go)yphaQ-u76%{@B|psc0q19m9Ha~^<8c@@j)Wn3d3Ow?%6dP4ns06c)9h%60j7>GFLLw>3169TM-MGu`^ zz*cMpYq73_F$(n{6m?5vsx60tT>PD+<2}(ivg~O>&Jp+Y=~l{{ zwyhb@E+RJ9QGo#?v9<>=YHF=aTKf*6xl}&7u_)2I#Z51tLK1yPOK0AAz7Pb3^AEZ2 zrL;Z5^?mr`BtnL?lE{mtoqn~Eh-^e6n^N}Y)vvLV?p7qSC2vToVys-iuaND$iyAUT zi;?R`T|r?$g{V@xJY2uurQWRJIRv_lLFG|<0T6lYz{T6qZHn6i(#0&=FEHWm z%7Dm#g;(5CzvuhEHS>vF?h`XDt0Qz%R1$+e;-tLlSY5Uts3Fm_w38}a8BcfrSNHsR zdD_0UjiQn-U3I`TJM+{l)3i2Q^!skHtkNuEexav@a|l`VNwvf|(=(`Fq(A~j4^x82 zX~lj@0RBS9s1|Sw9kk4s)|`RE?;9|2@VmZkh@N)Un-*%ksFTcrhwMRo4`#tSp zxV1&XHODjbx$F$2E7@Usc`!n}hNN`bsZ6Pq`S(APXVu==+<-!E<1=SAH#XE8OPTGj zhTG>drR}eN_4x6xK6w22gZjBU0UDYY?AjRl>}9ZaJvO#_zTHX*ao%W- zj8@p5Q9{}T#3E&@58QO_s$2W#Uw!p0+Xs*Q&nuTtY=3(BtaNn%m z;d7bQ7S=OXc5f5KmmHg%EOtOa6l^gJC}izC@Yhg#?@2M4P>La9{e?Aixb)#yElxSX zEk~nf`8pjMZ7boFnXzg}g0SUR_t^)G=&}amqgRA;R8QLY0IxBPfu_Ea!Se+)Isah; zN{7s(W+wkiMP8-yITStHOvNlOelCIv`ld{G(uwKS`(~zz=W6BkB=s;;*=!c)|IGg? z7V{taP&$1h_9WE7Zo|sj_Wm5Fn{gM91;Id%lH<{+0MqqxESkNR7VqOl*Nu9^2w)^y zLrFiDKMJ|9&48q`++jjAx1om{Ny6v`XDlxL+f_K{zZv3Dm!(cG1Gs{qL$1M?C$1%N zE`^RD0%#%zxDm)SZU|;$V~1i)m%3GwxvXAQnatl-h-3}pn)BxeFMa8mUx}nHpIe(X z^tpxERYN(gssrhU5U6fp3YiYCE<=Pz@`RZXb z%f`6bv2PJ`cx0A`i}PxU5hLag$U6Kcgb-QZFvD^IxP5yVU`>ba5;C84%F?RYmG)n0ROhvQWq_JbGP%G(q@1epYwkAXd>wJfHTBz%eANUj6Wl*JJTRckn! z(|h7S;#cx0gWgiWl)(r^!=dK_W+{*u{8&AUk|3Xfhhj50TwK;ri*pryCWIv!; zEaes?j?2Z3=tq35HhqXH(W^Rsj{~4U1^kywqQ}O*D@$fSBdf)%?s9@)dBobq(iTx< z`ShX1!YC&l4nl+z!URK>v*lYW90IvL93bceiD8mN670`yP_LtxHO{WX-sI_91I`Wwz1*bfk>5A%znkcXEPoCXZ5 z%*0}dU~tTe7M)$8R&UfUTlt*cY8WXi7D>3o#&G^ih8F&HJ8)l?b;wL0CV)A~C=;(aYK-)V3?_-0PFKpk zZjcDPgqHHs*=lA6TRob4*o{S^v3N=4lc{uk68s7^0peysvybZG`?LY{neaFnR`=3Pk1(DT5Rb zhvlCH0XQ?`W8@E|Q;3y$F*7Pf;)ofE*MaYmJ7x5Bl-npZIF#+yQ`C7;E+OOup=++x z)xQjTV@f6B-kAs2H?HHrx!D%?#Nf2jZi+hB-AdeoNrFGy_Vc;f5@dW(1QQa^O57C& zW}Tc2VHIKoDdO0P6qOu_J?7pLECJP2JsR;j zW6}lfdSl8gr99%=h!`$_B^KP0rWc8jf@q}DgkX<2?{qCqkkU4C`FOli#_p0nqYEIT z6*n&ro(*4R0Efj$h;i&nTQ}6iP%4&*0F<(G(Em7j;HZ-@#~P8Z#~P3(1rlV8Wz*1#np!D+X$qFH zd;-%)nYo0KPpTP6LnvBA*pi5%Q1pQqAg(M|!w+cCaxOVNZ*dBu$%E(z>LgKk=6Jb8 z8c$NUqviU7dxWlukz`LMk(5!2S@)Z6$BQPC3j?TkW26Ncew3I!6A1Ea+_XXz#$Z?? zE5_0nN&11KnSRG1kIzPGQF3(1ScvL_(h4ZYMUf4cf$v3#y1Mp3mU4=e$5<;2I|a7N z;vVB-qcdf&iEf=nKAuNDzFb&aOxF7PVpCQ=&_hE(Be9yXYNJXcVt^h3on%eiBve7D zP%tHkgYKXqa?>WYg!MP{8H(tGcMkCR3aA($A>(z@&k2-BmhoIy$dn}sEQHZCvGOfh z;88M6wf#$s2*bX|0i0$}5|P%L_tGU1__FM3RiXe~IlW(qB}O&oJhS1ngk+6{_)L^5 zx2v&q5lY#N((jX)0yo}Dhturz!24B#9PPBR(>(PFS-ewM)dtB>HEUOlM{c1rE#_TN%f}~UOnxI_B{gS zCB3Q7=|mzk^o%f{i7g7kMlyJiFx&_cN>*Hmhl(9=bl}N~f?e>;r7j1C`x9$o;ANh;K2IIqR z7h?LB3<$D@LXiq?smT`?v)p$coCs2OM5Bxxb`^yKxjf{vB{>5r$-^7ARuIFClHrxE)GWVLoS4GE4C$vPr zp)(ig2usHV=F8KMb9-Q{CZ|vIEbh)Cw*ZJWna@>?R^13}AhbJVC2PnT@dY_RLYxY$&sdAHPAjuX zw19@>P`aH?m_{1-79Uu?m!Jp+uUPqnH&ZT{54!y4B|ZK|K*2kC(MBL$!Y$Yy7u;~z(WK5@pMnSi&}u>*AuU&JT8@T(2NZIN_<63 z{jUiw?&(+4QLlX+!g6h0y@u=k(-P69`}FMU2z-rc{^jb3<}agbDD*}Oi7K&h)9H*B zEq0Jqnc%WrV!N#s7${P%id(1Dp~H0K!HvH(Thjf#>go3?eg9$0y5ztmqp&kWg;%Lp zu{*j-USv|1+jeA;fo;OjD8oa`k;LeFWa`J|K2}lBxd)l>9z`SBQnrEW1rm;M5SSn% zsQArO+#kb}3>eNNj-xax zKrOVKnianr$xH~GnZZ1?XamA6jxJv`CWWqJ=lO> zPTlE;C*C*l&51vU^WSHD?}2^oa&-;*#6#+x$koqb<72z7bhANs)I)zEH4eChKpcjF zFbRxU=dB@0`#qLEAW|%U6d(+PvU3XJI<=BzH6DPqSg2~Of!M`%j&zq{PK-@kYGR`IpNz@TP<*uNzE94II#SYCH_uCiD(lz$S4#?n@yzKfaGhgZRfjO@CsaM;(h0e5U}Ba zeJ*Vvmj@_C8dhtVL?nnX@)?6NOj&**%D`xV!KBSL><7$O;+4z*i7iXCRi+)>CZc%p zhHP8Y>3J~^I&)gsad0~(F=^NQ`%+_Xp8B{YXMTSByC5vx6v1ggj!ZZ~4>BVJ9Z0AX zh>$39lBvRppeF(aW!xekP`ky17PmWA42-a3>x1P*ViY<46#LU2vQ1{A`0=;@jEVqE zFaV8FQpJd1tj2>qTqMR5rM+kk!6Q4$!~yc>sN2`$5Jw%2FL&Y}ny%nfn5p0;A*-*I zNL*r1*)y}qV{7WDqwEIoQvjzDE%y>FmJ||DLQxcgVgI6M=d>Bk?onO<+Q@qnDe5Rd zSDX=}B}@asGL@h`s5s63GS^5)MDU2ywVXW{NkRzb9*J8sP4!C_FxCR8llaWWN|wu zHH482a!GDIQE|O^QmX%nWM|iPHgg5CZYn+LyT=_r;jjCZiqGGkGCwXbYU(2aZ=zJ<$EmMA`d9F z>q>Ykd!#a-Bo2^WvZ1-BZ0d zUEKcn!>Q^|SMI7t-PfY7Rl3#gz3;l`o_A#k`kP|Mkbf)r(GAc@hb0zD2o0j8K#*!Y zp;Th6p!lOHhq)&xguE6bLgDZ0iRLZJFRFK(wGXutwR1??)PVIxO?=}U-x&GXHNz@c z2_FJtEn1H`lLh8-vs~C;z2s{bHSCgY&XBlcX=T(dNk%w>fX7vP?GJnzL$)tG!i^(jR&)?g606*y-7&_8?=&3_pQ4{N|=pui*_ON;_v70hHbyt(!{$dz3KREG+ zOtT)7?J9M%dYyVNTqVDw{zAJ#yH>kNyI*@)drX68Qw&Diq9Qrt9Jz<6U`uH8H5V6p zpai5_F;sI1!kpb&?(q)^8``+C4H?2)`LM21!@h9a{_ z#vd)NaBBj_Xba;P9Rb{)4{r~CFW zJCHtM>WHre3mEj>N|$cPjaI}hZOLRC;j?DXoLoV89a@O%qa1Z^Bt{;4gX*s+Jh%<^?1@H_ z&_eflZYwNIBI&I=thUICvT0U0ME9=Rb}4mk-Z zDO3>^724>s3qD2>uyS6!=D#AjhfTan;>f1Ztq31E9A)F0EE)^XyKaYtp>bSu>S3E=CXmo!#YJsnFL1*S z^@=ef9O~>!?gb*9i;=y>K__o8jqzP0za?7&ox;>B^b42>(Lrb%EegBC06BtpuB#G9 zj&%<1_nVT=L=r3Rd|k_U!Co_^>6L0K9=(Y!Lj?n-mnuq{KnZ6d!48^iw9CCpigznSCr z9#~&ePJE;i;1uOPM6Ad@?i*I0QRjLz{j8fzIBxBtxLxS$)=5GghdmRrNate|7cY^| z{1f+{!rT&QwH-;8DS4kQz^w02x^^NcXEWv6;^94~?~H41VX0f){$oGE+pmNZ*VCvW#uyXN35G3qg;PhT z57p0W6CH+&xMqxKHK6_?v!@tQXRtxh0%Za*Lf9K+P_92I+9RD`(K}rpViV zO>JpoZz-uq`X~4G$y8MF4<(a&f=XUYbR6_rES9IoIepO!LmZ4YiJoOkE=b2yy%OZD zCPkDON&o%JU#x%Y%cJ`Cp&$8H;|urq)GgajDfQm%_uq7v(zaisZuqa#MsY%W=9Aif ztYN8`wLmS}7m+vg(8MDX@16MQ#M2X>qaO2Lfo7f{kMg*Bv3j-oBlVB!-uZ#Qd9Nl8`9(Y%@QICYLHKe!Fr<6Fr(rS^3e~JNS+xb-ZQY`)6hByJ(Wr64 zFi7*Fa9!M^dPo_mNXB89zaLML{%NvQA{of(WOlJOkg#t=UGqx5On4L&wEZ1&Ov2v` zVk&tFeCCOS=lgTG!jLAo?~pl(B(nQvw#zmxAK~Zoa!%OBw)U5^v-ZYnp^&IIZ(W-0 z$323LL18Me%-XO^aiK)Kyja^m%IA~y<}HKiDV&DP{roi9LH(lxFP`5170wU4Uel(g zgAz=j*;3KZ&RtW(2k7L2>YYJWiU1 z)kY3r>5B+h7gx6~RdutOyrC26)c2Axg;$f97nR_nFuw2Arz%UjJ``cE87m@)_Q^37 zE4fzMl2-fi<#sgM_6j9ju#}O469@_6*;eyCPyf`~Lm;o?&sTh+Jog_>#VoLsg){z1_$Yy{^%nL~#w*rvpuju1?R+ zCbL1jM1LC3dTDcPa(;!i%7+^i66x9$zMF*YlRtl{=S1G2yVImBk9r&z3xi zoYP9T?c4*_Xq`3s8z^l*fn^<&DB-9PG@8ARU%2~WP!x>v1Xj3>PfiL-qv8Xr&It4vIIp>>-nUe( z8165@AM#owajTUyzD?NU7hTis`L(F)7QQz8vAs^*`JSWx7#w1im+4EUjtma33&2WU zz-EHf?8Jf4u^i&x!`!0K^hm-+QYeM>2X`wb{j)Ez+k9)hH8kOBD0~kw+#)wcGFH{f z+==^HS$7iJ_80IMC6-ZUv{IF{&S_9lUcbahAH~4Vtfh&>rtY}eG-4DF(BgOB5n&O` zCdgg50XCC^D9MrfI(O4~J##O5@(8e+;K2wYdb32_D7J3LO#3>nMdGnzzl+qO6rMN9 zA()1(do;0k$FFf2*6U57cVh+XMQ}(h-|nq|ede`~Tp+0d7VI7#m=5WdbBOA^~$GZ*Z2ZkPy)$ULMe{YSxb352SgtI_r69@1fPzhpszT zKd|~xB=XSqZ=9@OPgJa2zbyqlm+VOL>+PV8_gs=ZxWR_MV$Lq8HXg1=_=1%gZEzLlI!{ z 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 OvGs=*>()Ih1OWi|n4ByC literal 0 HcmV?d00001 diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.eot b/static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.eot new file mode 100644 index 0000000000000000000000000000000000000000..a4e598936b3eb6ceb0080dccccdcd49bfe95ca98 GIT binary patch literal 34034 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 + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.ttf b/static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7157aafbacdb095b479ae52f59e28e19ce61d79a GIT binary patch literal 33736 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 b5?7;>Z>>sQQ*PhZo%{_-QW_Bdb7%h#hbB&U literal 0 HcmV?d00001 diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.woff2 b/static/lib/fontawesome@5.15.4/webfonts/fa-regular-400.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..56328948b3b1bacb23a13af9d727fd75c0343448 GIT binary patch literal 13224 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 literal 0 HcmV?d00001 diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.svg b/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.svg new file mode 100644 index 00000000..00296e95 --- /dev/null +++ b/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.svg @@ -0,0 +1,5034 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.ttf b/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.ttf new file mode 100644 index 0000000000000000000000000000000000000000..25abf389e22db851b03dd14d87ca10acb8b6b44b GIT binary patch literal 202744 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 R_Uou~eShdq`k`O*{{v{mwVeO} literal 0 HcmV?d00001 diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.woff b/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.woff new file mode 100644 index 0000000000000000000000000000000000000000..23ee663443a7c6d2393dbcb713b07c566f40c925 GIT binary patch literal 101648 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

    j< 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%0D?I3ov(fVN| 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 M_kYo)8A$*D0I2Z0cmMzZ literal 0 HcmV?d00001 diff --git a/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.woff2 b/static/lib/fontawesome@5.15.4/webfonts/fa-solid-900.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2217164f0c05a385d7d0d83e030fdbae01e99304 GIT binary patch literal 78268 zcmV(@K-Rx^Pew8T0RR910WrJ)4FCWD0~hoF0Wo3$ONJx>00000000000000000000 z0000#Mn+Uk92y=5U;vp;5eN#3=4gn+LIE}cBm9D+l5(TeNkOfH1GK zKycdts!E>2_#aR(j!mIAt9~;``0r}QwhWrx4iGu=^^ENQ|NsAG$wJ2Ve}j7l8ygcr zF+-`W%&HWHn%HzhV7~2Ch<(a~l+wvi2m)w&wNu1nLT1jS(;iT!Ak91;93ni{X$cZS z3YDD1``#-Lp40-U2&f3C>>NVe&oHQGc#slfDXObzRRmNQb!{uy>NJO!lscbakm;hM znIRK1LuQ7|Op|5?Hq)jXF)4x!$lo04^p2SEx_VDYa{g4gs@9zj!11lYiH_vNe=(>j6xwn8S3{(@(oXAFX}X z>sk7|a0H`HF**vNjCOHs%o!OVPoSv%{_8$(bx#2I#9N{Qa0OtObLwlL-K?VifmmVg+!_fU+{AIWQb=sooOgrxc z$i$Hr)69z>-VIC9;fHxJ-!RRa3_939Vuu$$%u@jZP|K0VnvSm&t;h=jj%|7PdHe(G zsur)l`Vd&*p&%GpOPhK}RX@T8mnE_XYZTD~u&e9g_wBuK5t+uul+OO6QN0-`P+c1E^jTR!{ zUYot6cBVaG``BK)DU{K|Iiuvc;?e;-7G^>fLZuIl8UXE$?%=ix zd8WV+(^4(jStAjhu275wEXSXJ% z!)-1n{7}DG|JSc#RiOX@1&~4_4T1>(L5YMY6$&7`Py}TVqTCd%?xod!Z)LUTJ=yM{ zPVW%_sX$7yC^@8#lk#zHa+rCVkiy}<*E#m#yr(_x>A1(W?=R)O=I`EBY&8X}R?whV z4^UWRe>~}y382M517G{aLNvs_JO*SLCd=nSlEYBHZBIioH1A#Zvs7V=Fu{0mNO{@G z%(Yx-wam;d{3N^gdyyYih2wokl@ei@|7vPoB|A#wBi?pE zs?tYPp5ED}Jbq90fa@)2ox|vEAEN1%`lRIUpH7;iX5i z+v#=Rjx+ly*W=vhbei*RY)UFe_Ha5f=nGkv%P)iunML&1fRJLXz1u%=llKmb#5+;r z)b!FK&3=Y&zNro6TsM;{msU}^vP>%o48zYbmcw2jzdN1AX2)kO+>8~`Dj;QSf5=?* zczSKy7kwM3h*(xZK_Y3B%%r&gKhNC$zh=EPenpnNB1I%cML}5??pWsz9c0d)e{tUE zxK=SxSyRC=VFxlGpzR-b0~+S_i?@?L@9pw8SOZb&vVTOfr%15hPFR9oFoFJ@@KPi+ z!`cNu;o;vIPx$W#PHh~Y*7f)02Z}I17pQL*745c#yEWW#7N2;y$WyY`&SIv;n`0WD z((J^4_8g5%(9B==04Ss zsvmBg+x6wm!^=A#;S6v2*>_qqEGHP})#=w{d-w4C_FczF!>oo%N$bL+w|tK0X&s#X zCr}w&p-V@b4nlhyJ6I|Y-?u&3Fz+wFP3n7458-Ya(7V|aY(%%v;VZrzvd zHj(NI*IyhRpD2+b7{TzOVtPTGck_CByeUr9t#DW!ug}(Gx#xN7lfU}=?zI~`+hk278mUPl)~u5N;U-xLEtEKjzFccxOu_Rcsi3WmMV2dTSpgn z048V*mPlu@dyhWSFGPpebouCV|M>L%ul~-zID7HRlXpM;_V=kPxBj^D@c(2G(Qri; zfA&(tgyd;<)%%f&6gH|DG_hY?*4#ZKj}BFRI88$Ik|c<`{`&6e?f2*s&52IhFrXUfzO> zR7O;e*~9IHM}lm6`^z2UZ#Rd>-xKTqZ7(XXZPm78w|=B%P;1uygQWHxDDdp`ijH6C zHD%hz>b4zndZjNPZkW{Hx?YkTw)xGot0xR8Ylxb2jlsqNw*cXkRbNA7e}9ES1bMgE zVENZoPnT)qe>7dd|C$Tz1MF>Faw@%SWGyS{q?LutWhPN-nTVIMII&`6C`wKw=Lx>9 zsl+-CeN&`K967dS8oH)PK?z3ivJ3;?b9jy=QE1=RWi0Y6iF8fjIRb^hd9GtyrlD)9 zEQt;g>pm{$_4wiL=JNdXaBq9??cMy`%=GUj|Mbc|9ru@LrdlChQkd`j#`?ON%8K%m;-bRr*ocsz?%mp&8tQ7&qN5@s!a_rWg8~D3ramCJy6LiG%Vs$Q=z=!1f+sBookk^-N<=(1i$SLmIEKOy;L65AuTzT!JT99^z~itO zBn$!uxL7SFgW&TxWdfd6$(ky)DD)@2;}t_mH? z&{PQ?&!@w_&P|S`h|gUd`JO6#EULaUTtHla^D{fw1tP4bU_bWr63rJrZsdG^D|`ZR zpfVaoSm+pjuEAT}23CL2` zqTsioQFsxFwcvD=7(j}u>9XBahtmzV#fD)SdkQeOs|q-S!1HDrb3CcM>h)Gr#N9?^ zm#9$abVsJHGT$g1yYVDq=@GY+awqG1b+RUYGEq${;O{)eKAZeWwTj&s*d38oe7UNE z0G7JdT-M#@~OvE4`M?3}*%FO^{ zEdYxO+Zb*mfn;DCZ`QEzug>>?*w=9a=&5Ls3U_voSOMR#Oryvq!V*L7m;7;|FI+Pe zNmW+{{U>Hl$>er3}d_L(IP4Qy-!64Q=wLn zXy-H=biDnBTQ)G^CqcaaL{oW14;!zX*xy^<#Lh!40_r=#{(#n1C>a z=DQ>AzESq_JGdmp>^>?5OuB^Sv z#I$Uf%m~+(zdtgx?sJ1}ICYl$Htm+Ub`m259`}0zEbf}vUHjXI+N)pKs`5P^N!IGJ zSDFTnCoS}sdEK%=i=_t=Bb154i*<|GRg*wt7iD!##$pL!1Ek#!ilUX8mScM_k85)g z!<9C>wHQBMMvFT)77o+~nD>#DNZgVy}@Lu0}D&a&xr4Ja^bl2^*h$7m6 zs2vPsFo5Lt;g!->ww)iJlWavUW5jDW5%}aij54O^JuX{|wRuNo;C$ZR{<_iDN-w#V zbUKxc5`+bJ4v@o}B6+-pC9y5~TCB)CRL>7UN^;H;q`Qv;#la``rte()!~tsVVIOj4 zfgr(q>=qqt-Es|1N>cp8+YcVz?DZ#FVU*Y2F1XU0ztLmMe|H&P}bAj))*0*jpDqQu|D9b{5WtNUYYrKobcGJ=E&fg&2DK8q4o^ zSvNzV(ajG#f)MOF7(^_=7~AV7od}XjJ#l!wtLEBv8wByh2)+NW_x>~~*k~1RT+BJ1 z-eB=U=`2HxiGd7xjo6%-$kqBr%P1knT=y#YijA7)EOE0IY_MHYjAa9rAvXhSbQu}VX@h{=8C z3mDiWYHGWswZ@!B6_f;J@ms5H7=wf_Qdv#_sr`<3)}~`S*?x3xx0}s&eh=jr`h6Z8$UI+e45_gX)o zCVf%)aR1n~#Zi85ixG>6kr&mtj|6Roq|~zY{b@=lg)+~5|9ovEVvGatcVIyIG*8YM zIiK&0zd5RQ%U!jA%zQR%+B=NCB?7#vEt@| z;SeQ36S8~Vl81=1p00;?p3%rzn_mBRg_)aK+lsgrrqgybq7|kfPRKXPB4^5(;J55~ zF1>ZdBBms5VF9ubA6Q6kb`h6-DFkQCWvOgww1xUiZ471B@pvi4tYx*)Y90>6GDyQ@ zCI&A{Ss%#47%XM0kQHwbE8(W3XX!SkDGX9)i?X-Y4YQXchf>`G505hn54bhD4A;@` zk{VhCD<2p(6C&lBIpXpg#^ddFZ>p-d`S4nesvf0~52liK9;r%^WK=aC|FmxGttxM@ z@+gjL5t_YN*|Ej$fh%=;w)T^P6Xfmc%V`giRCQ^|PpjXZyrllef`%+y#GQHZea*}7 zjJb8(`M*y2OEpee_s`&?Nb;&OSzo@03uU1j_1)xA}s!_&FKl2VW_x@?EgDz+IGL`v5ll zGBj|0zhp2}W-UU<&~;5#(C&*Kk*3ylx6Pqku-?qDPH^6@DY?a9cGSbs^l{lP4BL7T z1SJshw5v06z)z;C5_>4aKBf!7NUOAOh6-yHw4=SS>dv+H80)B&()&V9bW_Rw<8as+ z^P-d}ekH8{d)%uJeYd}2J{+ilHX5ly@QfTI>(+->Bl%USCMBm9uT#UJk}G8_X2D{~ zS+LFNWW8GRj{N~Rv!vLYfem(RiH(7^GLcHQ?cAAQ^f>2fmZ&$t=_CT4gOHZjiaFih zm{??^k{BalUIEd>qy$xxx#VI@UgIV!l78JYNyK(3%dzD)5r$!>?(3+YU1A&poMQ^j zNgcqQx`jCdom7}3=02cYTLgN9bYKk#&3N92+Utki2kfL-N!Hz0gmI1MF48L>6=E$B{5!=?l?wL9# zsN9!yLGDeu_)sVU_=IsVzze2p$+ARja>&?b%=WPee?IL=fuz%j%=pGd0X62eh%De9 z`EVg0ObZ@LVYY{WCnx#S7ND+F&aahu90^NVp0Koh+clS>NlD(tr*6aAB{LAiS=ogibUTf2XN2;eR9(vf3F zt=hqD-gQIk!kgXFVV&2BW`1_sAf#z3L`O^tZlNYWr9|0q_3ws>PC+^3&?%3$WM;io zTD<9?u;D-hH(6sHIHG=BO>j*W8vTD;rk`O}JWK`*lqftTh${Je>JK>{nmhO2#7Tsj zXtu-4Aw+CF?XhpzBT&H_Y8#a#mPt;P`xWL(OXVIk{r<_K27shXeB*Yf2 znvu_13lSa6-fuB3I1IIl#4;cXf08Z~9{ zkI;$_?GR&!5EjS$rCWSSehF<>4>*#*z;t6IV@*9bv=<~mQjCftg~NYXa6 z&+!oP@KwOPaFJF3kB6%}nl>hc1K^Oy$Yyayb#BCA)&7VlxH2pb$=kdPq0SI;4#OFPiM%@_el&5lA%|1%AHuCn%* z)dK#9p~u(HkHl$7p}k>!LmzybU`4fB=~ zfzov9uj#1hmot}9PcfoDj|L>GXqwc!uE+GeI_T)M(`Y_N_77a;!P5gUA{nO~2K5Kd z`j+-m1Ykm+z}!nwQUqxA1BHQ@0QM8=v-wtsahva>_klr{TbO!I(tzo7~V?;mLn08TLnza zUXJ4IAj7Cw&$GV}YcamJjk3OE(-)j$iL{4GatYnc@w_0{gPiBVytw0gVYpGlQzJ{~ z7OT>!Mn=OK&V$sK(6OWkj=icxSXUx~dk?kV3bkpy2G*9u;`n0R-6bqimd;=HeTSV{0Q5*S}B_1MmLUlpQ1V`ch;`1-75z4kFx#G3;^ z|DN>rW6Paa0D5NjIlO00?2&2opG^ZYgB9-8dQyQin?~>qnEt%PI-jj3;}Q$M!vGj- zHZ?H?JwoBcCY5v`MlH%m%(8q(r6hca*K~daVN^{A_&8K)@|~C0&PE+lgCqzaj1s)L zh$$a!9Wji|3-f8*bCRNNc^3YACYVJFlg2Q*5M7Ky)At2J{gW};c9`s!lKNc=0muFY zWKoOi7_8YWWh28+N_I)gc5u@p>14il00;P(YLg@;sEn;tcp|!Xv5}G?Ez+mn`)09! zI%jBwg$$~G#g#VKZ$qawe2#oUl5`~w9mCu)H%{43R8 zxY#-A^QV6slIm&E2)g&as>C0M?fc2|0@3PhLt%7vj0^!7BLhVw*xU5i;K5JuSEsw~ z{%2*};}ypVRVG(18BRrFAyq#ja59gee|Ktx*;a`XP0^FUO_l|7k3}X=GGHS+Q%O?I zWNHM2Dfo#T=5jt)bT>AlHKhoL19+r^ImB~ug1;;|Ok*E1xv%@^hZy%Z) ze`kM4e&op*IV)eJU4V{ZINz#C_b3W=>Ds=B14hmElPt5jNk;Yh{YfH5+DKG7)Ff4M**Cl`%2Sr59W>~l=$4eVA9g%mSDUbMlg*sJ z&B|3^kOr13C*W~d6c zr`u#_iW<*Mr0Q-R=AyH zld)r&9z2faBhg2|qUe(_Z#n020cibg@7pdC4F~|n+!u@?6yOHHpaL#wBf4f&clc5y zFK`l}UU6rp3n{U>Sl_YdRBR?iOlt+asbZNwnKR|F><38)KU^dl7s1!fb&Q9sIyM*< zkJ7IFqxTpNCiZDyFstB(AW_FBQMMvA%c;{<9oX=x3#qrt{XJc}N+K`>rvq^G3)V-_ z(ly9kjXljUm>Nu26}v$Yy@L1+u@xJnmLJo6n|MfsGWjT`0p8Jh5zYwa=iP*01a<~{ zUKnwCMBEed2NcNbf>Y->>jhyA?JCQavxc&O*N=6#u*B-0d=~#p)~#OZnnW2O03f4; zzE7oA8{hUC+Csbq-|x~br|{a7OkRBPak*Uj`G-^J(AdF8rG)h`b#++(+xV0BCqH}f zuXATUe|miYvjc0|R};1SjBo4Jn=3H-R^H7uYJ9HkRkJ*S%7ine!D(tAUN%j7!weSm$L7*Y_3Ks3~ zwuS?1EF#+Fsm!3_HtYo)ZL`)}PFRWmvSSz(!ai~Y(g}(Tg-WUh3Ss5hh)@gQ$?-gv zCuFy0m-eVV0;w8)_ifr4DeGZvZOr^aBxU7GzxJ_O1)YYlww}OTB$$GV!0?Yu)}>QT z-u><;@x^{Cz$cEWO|cAo#^&1fIk~+I8nJGx_cZ4Qu1KQ^LXN0OKN`h_2m*St)YIbj zGAZ|-tulEOc~>CZhV0Yvi=R;oON@Go$OBh5k2Vs0<@TI#prVZ~!U(L55ARKs2{7rl@SUW$GVFR<|e$>ZKKrm!s= zBtNp&>Tn>3yz+xs^4h$)d>;_$>~INpq7Na(6CIt#nP@{WwcxAAc2amF?sHBM%Zsy% z$%|A!fak(_tCX@(b#f6m!!2!AW?~1S<^J;@(J$HU^r_?-OKcVOsN@JS?p=rnyv86pAZXZr@s}3VY7D{`H#__Q72&3E!J3f=hJ%Eo!`$BU{eJ z-#K9HLkCBhrElE5Rp1;d*=J2`6`f7)H<$*S4VoFX``PyQj1hPgw%a`*0O3~lDC5wd zq+hqcapj{!vJ=bM*#on~bd?V5E9AGNgoCMZa&k5HfdUYY7DAF@o#*e(0AE?XbSd;p ze){R_%fN3=)`VPNyL>sZ_FsJQ+M1Ax416D6wle&k^;nvkm`esZvd$CNSzXDTEsx?W^}@Y;b72%TN7JuWhonx5TNO^B!nh3 zb+F3#w%51dxLa<$l{*4(>F?Aipfw>PG#?&M3;sV2D5)k053M2%kXhKkY)yZKMQA#4 zjrE<+u(+4b5L*<68{5m6h_cuD;Fy~-DoNsHQ*6bEGeMOu`!aOWx-^2`=B z$&40rZx&?36O>I3inUCBO?X&Z4VR2j;vYbAddqHGDr~d0F=8U&7%$N-or#z7SoX5O zlJ0Xs2vyKjwJ2q`nni3LGoup}kB;&iIpc;~{4_eKsw6I9O64ii&Ztu~CqAL*UxZ!9 zG8yqdijXwSh#wUe_`R^CpZYw+$_Z2EWEBn-&_z_5=rCb|X++^rbSB}uAUdETMfP0P3xl2xuR~kC*M2Y)=89n% z7ww5vX0u7rPEKP7026|c_w`MujZzHBA>sXT28X4i26L1!>SR8xT-s0-i2edSh*-!q zG((R8@kP6|Afw7S0(VVvIMEXhe5eu*lp+CJJ#ig+J@wCHuVACOnvXc|!P~Y0+&EJh`z85KtBh=ef{uLKt5j5rnaJ{=S|VWemr9Ehut4X`DCG zCWrCycuXVh8GT`fkoF4tj1bgrDh!eIlL_CO-Y+!`M$HQEDholfW+BX4$ci};oI--K zeI$s;tLf#-qneuQ>lzzy*NvOqo!768gVbTm%%O#P>X8ZQFwBPV)OnEMBTVdM5(`}% zLSfmSrzM&i2xczgj*)gO6M{Cyw8byW3+>Z*T-8x^)}*mki;gzwHQ$@6`$PvwK@=3u zHB4mGE3i58DG-3iAC-A_4z$#e0Z}_+8!Gg@cH8N8gQ0L`s^bqxTR)Ng$USjRnd-SM z&HOHZE1@lyrl?ex#Xb>P7T0j4om3rTD6xb;hP`PXd(U`T%u_%-hPsDvZ^(g-5nfSb z?ol}ebx@euEjt0expM09* zzQAYbaGwC^HO$&cNh6}WY0>Pq`{9ZJm(FZ!(<#;+Bv%r7-;BUX2pmCA6IuoV(;r&S z$dAWf7p_+T=eGChXh87dndippki&qYkW3xz%!v$quxo3tltH?pEcN=#Xz~Jf89Wrt*q?E(j^V2Zttl*0Rm`zq92kA?mz2%aH>k(iTXq+7(g2P2i;$5V zCPD}z)V!cJMWUy?phYu5K8jF)!t@YJ0_M@$!cXqAsE8$h*;9thmy{fZau(aWwy?c! z)VmckpQ{n(by|@f18@a`(G!!8^C}h^)$q%@NMtnmOqXbkZ{8xSFu9%K>8%*!Q<`Hl z2_YjnI!w!FybW(hk`sp`&wz@eo-b{CDevy;u*^mB3rFRp;qER3nkcDQdKfA+*jFy8 zBKQ&~;=Hx^n0>8{qiB3V#Q_H^g{ANdF>e7Dh_Dh&jsJ*)YOxCg(y0)hwZ}97rmB*k z_SfoFtbREQR?l4hQ-~A^(y@_Bavs;D9M1;nsVwg?qBSBTRu%}^B=srVP>k*yxf{~? z7>_Sb0fTUv7VI zpFgS&f1*Vb>4?()SbgD`^3q9l?XbG4KM3w6?G199>AQCcF)G=0xcIY* z6K$AD7KI*F0OOp;#DP%L0B$yFS4BT?-&rW&!x1vV_1ff8lwXBz3H7Bc+4OswD2!7h z#*JN!q?_yc$uEDTGRH9Wq%VpTl}N~Y?1spI(wrkVoi6a5mi%&vL+%RkS+JE?S2nTP zCZWIs%IXgb9v3pR&c6Zy{4*8FzszQIfQX?6uP`rCG{;Wa)@W>G>^T-1<%2J@t%+S2 zUEntVyy1MG-6D*pBXD(Rr$;h$TpxDxg&~$*qC2Q?NlY|^``eeOT9gr#c0wrlm%9+E zh`;{AJKGm%{PVz!i>N==9ihqjlR_?ME8P^sr$a$!L;Y$w-FNqRuy)poEBAsW2$&a^ zj>PHo_Uhe0$4^juE33?#dhqHhJL8*mV@SV`>^%5$WMz~>4HplDZdxUvJl!r0zg$Ks3bc=W%JJx49QMQ5jsj8 zUAOr zAeO7rn~NIkF}6@rTb#<>cbGdyyLnZd;*Lf6uj6Cf6IWw=wIQK}gslxiLpH37XjV)g zyy^V)m-k+u5~|BkblSp81Vli?&d3&Cf;-PBboGnNPYeKa<*a?dq|h`Yiv;}8dqvgY zc1bU}jDr{*oj=k-sSPS%X`X%Sv1mi{nK^r|Ge0d44so6*`q30J4-Rlbvr++5#0a9Ke7zEnCA3yLUhLs;-yw~|+hA#PFH-??gVcl;<@$^?I6h#>If@rv#h1*_ zn-Rb2`3QRGAd@sw*?M8o3eyGT5pK?i_>< z>u_vyu5q7s$QPuF>so`+aibV8g;k7Lbv!j*s_yOzmy8A*Bt~IXhl?K0;)H1<)%(cG zgZ?EY_^Ufr?(>5}NU?e^V-0DA8cMB7?>CKcw6c1)UN$=!l?R_tYqwWl2*PLYLA?!p`_0r#vs}c5*J*alCARJD&ej94 znlfpi_2<~8w%3rAR!cJQ1?Q!UxHONjD8F(NnY0}fT=niQLQFyYm6N}5WXt2WsqC7a zfEvDd1t1460MZ^{M|}k=*G5`H9yq)nf@sUYc1Xb%_td=f=oRFkyAY(*AecRy53QR< z8|eH1w+EIO&X|2bNHAU}ge)6Gd%F260uhC+{|#4QK;#aTMunYN8x8mdp+L@IB~$Br=KgORv&7AEHMicf#DCz51Mh{v^Zh+TT=2V!UPW(Il?U zNJt*;rM5wzCAj&3PQPLve~bA5(DUKD+wUO~=q5(~CQR;Rc}B>5LcXdG=34GQtmEqB;n>?G0lk5CbOT(<2zPcpv6hqUALG zq>GRC1-hlA$C$3y%jW13^%bY-X=u9WC@K4R#Zt{ zc^LEg7tUjpGB|-31(eUXK6N0i-#XDzdyyCr(w>rbe-Ono(a_l+>cYJvNFE1i4$#3S*Ot2P*}fklNslBTBFh z&~jkwBANf0V4`7BGrwhK`Hw6`mU+*u>LbqslBbpr%%w%A1;&eC6tW`*)V}*+dE=SL zkkCAw@9rKyx(0Jb6dXA3HUmLqk{}Vy$^pyck`W zeK0FDqH(iE2&?3ckF`o)CJ$b(`IK(ZZ8nV~cq{cM@g%yc2JHG{A*DGv{pIter?)$n zc9twKvZKi#cqv`&0c8B=^MHVl<7TfH@)HvxJv4bO1m8vdpnJTaRbyak|3*t@VMBP& zs=4jrtJQe*4h-;|hdSDJ@yiS)EV1xdd?JUUfABL}`mgmnCh2~!Ytqw6gavI-^5_AV z9*s=2AjBb3@L5ilO9Q2%!#^fJ*zaOmEDYLZTq+KiOT;b@&B=t`W&8y>c!GKo%dg8X zr8w7HmN1w=Y{$sqDWKBg3@9N`fG{iwaLG{jH5iEuV%P|@-j7k@c6?Ev#wz+AhCL_N{b!B@hS=%n$Llby zf7?Av213biA0;I4?nH>O!!IOd1dqDGDR{2XPtSu-uFB&&vgT5s$~>lMd0*|6{m$&h zkAYg`9E)#+!7~f@h1@yAM`M>^P2NvK6 zhqt3%05&nStfVPDU-)MOF&T03q}RN-!Qi@U*D;cXvH4ZZ>K@#$9hN z1-B$c%nLR6_{uJIg`?12t*%ATkaYH?gwYQf{xeKV5EokgP`#p zv06N2_u9V}loa zgZ}KouUM)9Nvr-{w~N>i&w?cX;q}z%DcV~FYaa;tFppqP9`)t&W1-oXcM2O7Pd^Bn|04=k8`KpcIPBMF zK321L>2HkDpia`??H9FAGkOIdx7S&Th^+NdF8y*4!3jnEd}Y0U7i+%7{bH90C~x2o zg=kL{WN4$X$p&q<@L~mgFIiBPc@Awi2)ow8bfG>^^r#}VMOO?wXPC(@Yqq;WHnP3& zv^zCe45#7C(eqD|!$P(`Lq4sXMQ4qgTjL#yRW2+nmbjDkxqIWIkdG^csa{d_D>1;7 z_rFAq#y*JDE*8urRDu3wC(m(2%A!@Di%u?vm=;q;ccP|t5uIWN*4|7y{yj&VMnE*t z%+!E|g(p-x;Yx}O=(e!{I9T1dLjaCg*z#c7!Xot5jQmpY%>zW%NoKa>lndmr#|_iR zIehwn+BeE^&GVDUn)3y!oJ=?r;5=mD+F}I5Y}Hi*-mNs}XYVw!v`E29$r+B|eCFW>eeE->W%04BwAYxyKvQyCE(FC1Jc#%?iV3wh3e7+xv+^M}^F zBWkoKW$)Gqc-vj>Ljq-S%Y4o75^p%8hPJZ<502Z%R0e917?x}hP-*ft1}}v1wXyyt z8y)~L8`gosHj211TH4P*3a1%QYDg{c<;q6n*t=6uejRcCta)WOJ-q8QsS$?ZiVm$Jb{ zh6<;YEz>P$`6Tn3OZQBaW^DQ+Bs~K!n_+|cfoIkx7X`p^cy~W4m|O%Z+V>}M8mIb* zK9o0l=TF9{R?8zh{Wb+aXM(SR5Wb3S~5G$pAqBeOYj|U8^h)E%2U{IZL7ah811^>eq6lkM9H*GY z)FYbVn2+&HEo61t(NaMBepZAqit1o0g$JhlF%8<69JuTg^@9)htVlzsA5S8;eXp*j zIqDzCM{a*m!9@4KKIXC_pCFia|`Co1QPQB5K%@o6c;91md&Zh81x3#I}Z8fL(YIk_O3=tdDXSxBYRgT2Pd$ z?P7$+6ZymGSD;3AIcWLPgX@h!02z0JC=G?G^sX(wMRXbuMDSBoGdeQlkbzk)`229 z#xiBtgCL0E1DC2w?S!QJB)odF(3==iEKUH490HMQ62TDKuYj*IFVhQxrb?G*P^M9> ziT|nSh!}R;NVkP1&u~E8oi!&0U~Iid1zb-i{99?uiP?7i=+ zx%OM|`aRR0hmG{cWF17l$M3ske;G^0S0+l9Hh?*&Cmi(_s1^NVt6MFE1PJX^v25U9 zib{NPp_=c!g-^bKK&R`m)JD1vVj%szua4*%zoU$5m{CKAf}fGosbTdV*U%69qP~Z7 z_$mETh*5I)P9vD-6M<;%3wpC;y;9)s^P;!a-DP1wvLJfO&pw8U0p&9SeV!eyW3&?h{M$sv&E$IZMa;6wFNN+phA`h)!h-C%yqc zrQ*&|_|s){3%nZbatnd@_7gzzV1 znlIBJ<=aU%#gdi~T9|tijR~;~^S&J9GV^`@V5`HCu!2MxD_T?bKTf*uD2hHoU(A)z z`v;mbt4JsnKEQk+n9IA~b^sWwbVBf|+IT;oPZK3kqr-7+(kjO%<{N^#*+SRr7vgizAq66hz%7LVa$;Gn4# zp@U#7l5H!1wjFd_RBY;UIf8I)~D!JXN2P4k6n!b@}UV=H&i5Z zRCCpgI$ip$in*q8Zj5}C?zJ)Yy>euf`>W?CZ~h(`=ej8VLA%P`BOm|3-tYt-j)b{p zBF9-zKIzfbd#WL0=|$}^d{^%!MqJH2Y_79lGM$2g1OcMO*;DgvH|dxp9ns*J9an>m zZ>!^d$X_BqQV2iQk~|Fv9Ro$(@1=lJZ398W3BoJh%&bF(l4pA(v5*X%j3-2+y4WuHr?izN364OQZ5ucnp;nl{kS zhe7RC3N(`vbA4uyvidkgZKzEZ3*Kz>lM81QHHHpJcV%S*ieYqx#t`-4nzk{8dS7j; z05}RRT%z6b-V#>m&+sR|+*Q9CHtFz>Jh&4{1Cdrsv3|j5tQ@cZNxdeIeM~oY53Th6 zFDq~N|KL=E*-&5Ct9tGG-#b}RYsVhWIR5mWQZWwdFXpNh2Tb%r6z}-|7)*1uB1ojl zy%Garj$y|rNN6wS9_a*6!+&H)gtEPl9|V!}3YqRC{B#VRX~@=RRG|*XZb%&vVM{#S zh(8R@4yuzgG2p$ z^Y$`d`cUkUsm7ICnOqj?psz2}`{N4X$9>*;cA$8ioYc@gBYCi}o`l9t1G`_*Vv;dn zwOzIHB*0j?dME9#A4fxOmv^F<>Lg1?1g{wYW#@Tpm9=%Pre&x*UpwU5K&K)QH_1(U zbI6?o7jXIEywhPhKS@76%X=1)?yX#S!yc2o5XIp8ukKa*$;yQVBGn>2ky87#5}E-n z+;F3UP%GQ6BBp_?#ZYd=JTl_aTG=K@eQ47(hmJ5J_DcQ`@dznamP>*@1}Vd<;=Fe# z&Bt=gj8V-nLW^0z!YboQD&yd!j+oye21X2QC8pF$aj%8PnV-X%(&$1)D|bjd^}~1H zSueOe4Y%cpn#YrOMP?UOf&yJXOWr6Vkv}1NfbG~vIx=ytSKhy;shAbpp>hZo6CwFL z`f8809QMU7iv}q{UofF=ApMmjL zqM3oXP{#YX&kGU56&_q6L9>1>UU>eSiCbM2EqSc1qgOBmu85tOEr$mi^x#lDpp4X( z;-LtUYPUi(gb}lXgK=8jB<6Bu7IK_ER&z;@yLEg{59t37qpJLxY3!H}0T>Za!QjdZ?TfnQwg$Cye4zJQpIM4o+(J&7WIyQ!Y9Q!%zJNR@{T{~v zT4&_Ti#<%d$oz0~ZyG_$mw{g~eL~1MkMRfw%w}GL*Hyvk3)WAOfL3To`<;{yWiwZ@ z*I^+9AQH}HNhMQPr&u;~H#pd*3cvJuK8J(x?2d$JkN{^un z6cBs5-Aop+e5oqLdUK@WRLMwpj4s;?@XXqtw%_$x9uY^U`|Tfg`|Z5fZ@-%_MLEpv zrKL0@{~_V7t-c*w2Ir*7e3b+gAnbCkFDotP8e1WTP(9D#3M?#~`CjE?RzuLI*faYB zR@|rn-@qIeA%GQWMNytocRf7kDs4!6OBbMR|@#BY2JvNKaBl7b%oUqy!2q z(B?a4nSqJYIx`64f>8>rg_JT(ek1{Id`t|K>1|32VeymXgaZS<{UO{WM;K$8RNgu9 z2>vvX7Sg7?^PXQHXJ!H8m5eGGs_RF@Mf%kW+uY)y4f&mX`r!L$O(Mfcif9EjT5cyg zIA6$a>_6;1Lp(1`JF7P_##}Z;= zOO)NZf^pj|rwELcE)^p5$I(suxY}C= z^QX$jh|w>T-(5{C%mr*z5Z)91?-47+W_-riRa?i4YAk9_p?rMi>!h)@12Q;r8V&Zb zfFT|K4Guo4d7+DfIwvE-FC9hKTj@nPfNeV&)Y)(qf)PPesVYh`c2*9OtCV$MBiuJG z^VbSdE`_Zny z@O9M@B=kX*WK>Hsij2+2X=bMy0gRO!Zpz9^GJpVtZ=7r3yqp%IIngA9m9f@X05}0c zGTSVfe!5VDnad=d$8b+cjFYuo&ZEgir*-D#%)@K!yBVB8P55D(9_=*tc#d&)E0IG* zyTls=lpSM~-P5SM5BOjDa4;GOZy^bcGX?1pk4gQl(L-_{iGgzc856KMn4OiON{hg8 zrsEkW1r|XJ5K?Bpo+%1FE0g#5OzkDYfoT zCY~v3sU8}X0hwM#!VlkVU~EIO_>qlxEt#hW;Sa&dsHGxqNp5(;>=;aD#_ufC_J^n) z60BI68B_g>6vaWKCA**EX8xa?b)gGL=|W$1*jv>UN$TSYQYjaFf+!UCrCe1>Oglc^ zPC(nzb_bojEF}RD_wj#xOkCNJV{jWbfaY*asSTmox*_&X$@^;I?&gVU5%%*JA2_n5}gT)d;2F`Mzo;201rBI+BPcS(b8^KwcIL4^* zl}|IuGl*YY#Ch_6mHtU%rHI|)>!~$<)KJoULZi{~*?A19`W_Q?mYxu52>)70qK|d> zV)|pKqAU{G`%5{eDVxyqVVWBZu!w{bFF7qe|Csa*S8^Cpj%&hzbeT}W8|ey`$0480 z+6BFCxegnQo0roobXP2qK{T@whrH>PL^%$#yndv1c|`%anU^Fr#XS~VY1EX~oYHg* z<`jn@L`qU=IrV6~cl91g*(L%KWNw-=Lcni$*1GbzFLP5=*s>aS%`~Ux6uwgPM%2Y< za0;WfF#UX~FHaNV65BscI&yk;FL8r+wH#8w2ohZ5Qwa;3175ZZJ-jc%TSszHF7h_q z-h?E^suL*@&U7KTZfVp$iIE-y@;-Ok#wdI!NW5lnWq{G7ND8Y2){Bt}bZ+K|cFgpY ziZe1Zmz2EXLr=|@2cE)f)P9UUBRfJfT*w|Cr49UR(e#6(t3(fr!9<6;I`f9ZCOlyi z@)+-&G{(3$dc#Oa2$jTY7l~ZaN%^Phh$x!tS2jIoHTj5^Ux@!&@m~pV;Oo~l) zW%|3%Wn|?)RAiiX?%9!&AVu;xgA-M zHlc}#Pul5jf!Qo4F&ww<3NwSA*=NcKc0+5xOJ`{x?H~dFKRSWCfJE_Y3aV*dbtZb; ze^(-1tT`?#Gs_c8`Ksn7<0ttZz%w(pLMN@AnMe&_g^QycYyCt!h zU+c&!CbsIIC>5jvjIqs06aM^eeJ4k?pE9-o(Gzk+n{RO(7zn%;sF?}J1$bjRyC`;x z+x*TwkEk$e(Yrpf+vCOVqx>LlNpw@cj1eS~RUsP-o^e$vt8OQZhinP9{>58Kd4T<3 zFK+PSlS>zM3*1bkC! zA5YieZa9621DvKy)_=IVPzqFN&^0|u`4PMJ0xO{)?O+pfV~SkYV~yMn!dn;Z8OwGw z*)gyKr3|Ri0a~J>Z>l5q4ICOrkWx7^Bc65r@Nw&4zqXj(sKBbEEvz3l_Gyo)n=he* zny~`n>cYeTzlr`Tw*~L1=JtCdqn5|8_Vm)JWB~h9ummo-?V74?Vvbr_1_E$?MA)F^ z;`cP3PiK5y&Q$!Q%vj1GTN8n>v(>Ofp$Hz5HEVjTl&Vf9%>s8#%i!NER$m$T!TtiB zW~Dwy&ZgDwVUB>;4-6TD100}i7z*3VXdSkB022GSp*@r|wAmi1R!(PqiNs)yQ!c-E zI!J4;MAO={zmOPtVYo2*@G8WM`4bs?d&lg!hX67sFGqq37H>m{1 zZLKjZ8d-soHAp&%ggfS4=Z<@_86!<~SX0HmMSgG5#z-NU@D`QWsH41+;`22(Xq^V+ zP*I{cg-$;amava4#`pX556U+N+fhw_OC&G&<-Gh#1kiW#hClk;z*oYR6~m&J=(~n8 zCYTLpphbz*xV_{$iNBet16DZoQ}gj0?Lq*gGB{_Cb5L_14D{21$$*`r9Z0iVFDGrwQ|FHv8W0FVqD54ZioGn=hgR$Vg9vb0{Lw7^~>nlvG ztuwON^%t)-)!T)Zcn@?EtWi>-ux!-gtTh>^d!ps5@-_`G9@WXQx-&_)w5Q!-ifhfp z3ATCYHx!PG7g>ht&?!Z>4^!Q?Z0u0xDeICof~P!NVpJeW>HeGV??2u7VYGK!be(<} z-az(!CaE#D*inCESIF*B%o+TsEKf9yISni;-KIS;cTjkrn`sX@rmomBmB~=w04n|o zv>1|UI1;1T6h>dmm-xW2R-Zd)OE%!uKs_6BT4>8tJaZF{Wb71X3p3BkyQ01mSQ^_P zm76kjO3ATOCFO5PnUS9qqY zSM|7NHeXN4!SHC)_GhJaEV*Mzc@+ zZ6?g`fAp>7+>1YX>G5}^R&gqceCuC5j#_l+X$Ukei~USPw)i?%pyqb?VjNY^ey1X- zd`jT9aj{utgLL%MNAc4ieLn%$G$gN#bs5=9@Pdwhafuc@1RYa08&HDQBXJ%U<)$hH z5_Dw(N8vY&t*gaDpFySO+S);)Y4%5XeeWNgmuQ z!LX>8Lf$K3jDXDL;F8o>cXuro= z@fc`5Ome<~FMM7a;5p%h9hUgsgLj-s7u{g+M_iMxQm)7+cQ}-tV*(7=%^h`zfE*nd z7CR;lfqk%Rm`;+BJ}lcuh0A9CYcpx=n~}f~)oQdz%7BX=czmLj$pT$Ax#+x^ z902bvCKen7PD}%h#ic&rXoP##q&?ikMMlaO?x-&R;^G@=51gUF$pqV2%U4ogM_U@ z5|%zc<1?M(c91BKQwzIUhS=X#RPDp6})L zc|j;GjITvJjuT3fs-FKTsDM?`+yvt)1uuoAdKq2)t;WAdS5^;*%#IE|Quwf`&+E6^ zlREHHD6EUtfVv^hyckZ)Qkc*Tr!7ScbU!Di`BN^E$F+otU;4#O8(Z%5AQA zaD*K6A>UiK33CurHFC4^dwf*b0Kwa9qU%X#2=$JR?T#Oq)@5M9;>?tAHt! z+bl6#+I@)%5SuCP@Cz(dd5yOTlNNDC-j!K`tqJmPC`ay#Zs6EaN=I;S!nIqQkp>*z zSH(+RO!tg!Sd4)+b{S%+?i2i~AGyV~BGI(s4)|T+ycH#yHf__gM3uL)s(y407h8&j z%Nld0?580L&gzN6UV>#g0|GohsU>P((o0)Vnxw~j2AFf28RiRp=Jm_AQh^UYs6Ik7 zf;<_o6yq%2)1}&JXy=lu%@8J(3rF&LYuKZRs(pJM2SVqigk4LEzmsf9V^PyjTw9P$ z6thzqQ#Hh7rN(rN(oORrH4p;AEc0dlaf`xLA#(~dB}E%mXL-u?dvi*_Cr(ewluwfJ z{#atIU3=_MjPl$FY}!p#x{FyfY*$}4@1n*g@eT*={(wpPJ(||p=U3W<4K0_r%c3^d z9%Fwm1pGu<^p41S$N;oDzw_>Ow6!v70Yn!~_iM_|DxRluIvH5&9fxzP%&?*q_Dd4n zj0>y$-jhW<8uuX#G+()$?jaIXrMTW{Kg8u@CyjkQ=%BQz)&m}bW>+fKx`6pH5$hm& zxJuOIQ{MT(uY5-$cbILws4eDnh6DD=sAlaR!W1*4u@|`}rb6kfP0M5N4UAg4^1Z^i z34+l9uF`_xD2dScKXEWCa{HoFQ8J6sQVi3|S$xcAr-2bd#a-lOUMZF?9bP^>+6kA>nUOQwhrK zUEvc)Kd8`9BBf+Kn~y*_qTcaUHk3#zD!{^#DurFYJyRx_EVX32p#Gp zriy-!oDn_t3>~pos#T1R4l=N>sg;O&yyK3wO#gUVc2;ZIv#R z?;`@wQ;yrw^l>vQQA0F>F+~J{oIjx_)cxYm83jCy;}siACP~lsidsNOj(a!-uV%0$ zCCgYwYQ7iA8kg=&=owY**MacbzKvV~1PcC%G#tJ2@(#fn*EZ z=4C<()uqE7oL~QIJMy}f?_07`(31XD5og|(9Gg@wxP4br&WIC_)gm6l060OixFBtx z0qla*Fihxk;|2}p*s?|=>kM=BEvKnyKWjWXH?KI^L%e1C7T|p+fVpdT_>sqz>e}=9 zxhIvv31478KO)6mU#Zu3x$wn{pw`2UMmLbLjYzUj`B;-Kr>@S3wq-fqi4(sns`Wam z-t9;_9}Kb;81n`1DR2qJ$4%ZFP>!$EegcijF6AMicL-UVb$DtQjeaEK4u$eOvYl~% zx@yA#Zu5gp!V=B((qVOtV17TuV6IB0ws;G*CHrI=E3>8jGy9z8Q`DTWAxrc-yOr64 zbLFLDg(EB3!m+hOT;}93kvTt7<|RGUn*`(hJyiQrscd{vaV)>_)>m3}`)k$Zo!$V) zGHJo*H7k?yi2|RMiEYWzq$YmJ?RmmgLXwKA@{nh?Ggc}~To83xE2(8}G7DMAZH0*5 z@c+Ti6dF-vO+%kxGg&!l@%(0A0MeGVy7%vMXkh`xDh03sH#eTUqQ>wf$*Wq7(p^@$ z9-=1*4k8p6?&ZufutAyoObPss%E`=nsQ3s?96xh!CO2frmdrOp&ORKNAdyrM>6p}p ziLaVWhXnum zM@xqc;4@L4YZC0DRMZLJd?8o&;XIQ$YUQN}6Vw7h^O}MshLt=Z9j}9y|JCE!TAjf^ zUyu+|JK-24avh1LT1e&bbpY2Jk1^;rm+O|wb~xx`b7;Q3HC7~l{5Is6L&NOYAv9+A z8&nNy@FRh_L|@3}RNbUAk^Kl}=i2FfLMKc8pYVP)6O%lgD$&~G?n$V|JTXZVwMyDr z5t7SFT{$bFO&VzkF}PHgUId12Qp{K_6?!ubpkjBE_)jBRVi%%_2X=-w1ePE10(8ig z1`pR@;V}!iwL0Ee+?8 zeZ)~u3j6#@+@~e$tJgACTL{Lwjzif(W=k=n(oB&Pjr|P$evWyU>_|?^%GpB7CaNS+ z)Am|}w7|=^1SG&xs%3v)>ixxJm^IA1lB4HsCWSTV^dc8B>v4NpyV(z%U1z%0b+DAC z&!;qVjU$8X!i~sF0~cuId;UJL+cmloTPOEWNzKM-$VKI;u}R)dQ;Q=Prf6WILMgF^ z+|z?XeozUkK;LM1tcoIIwah=1>h}QKtk1+sn&S5HR@uibrnc?e=kT<^;Rng?aCfI> zOlNUOVr8{L1GB9-h?eN!JIf4o8yn`k!VS+?L)FeB*NXOaEbcSHNi}mt4i1bEp`O}g z!&XThuW_~r-Ls+a)tXsk_Kr_mXv16$3kS`)ZMxVAUd+z~b$;#O3|QVdhegPyYV?Ln zg{^dEkh>zVP>M8UZm2^3xI9Z6lG)E*2Ba7AuNmB9N#lJidg+zJBJ9kqjMq8el zn+|@>-H$q47*eM_Jmr<^DzUk5`+IeTDSY&6|8Fw>-Ip3lR_4?vXMG+{WW0MnJb0W2 zM_;x4KH@x=ofqjbU>D1k<-&O>w6%SgrNA@AyMmL#Q}|qoB=Kixt$cw4+B|rL1G_p~ zx&>Ne<>j2L8j84?4HCBVbq>X04gn=E#cglr1ftpUJhpoav`(&hdaPM3bLU{!iyE9I z@n7>Bu1FzHAY zogLC|rCR*VHR(3GHrv1Rmhg+gCw3h?(0`&OU2q_Aj8l?y2^KjYN0%ZM$y9Yh9U3(E z^?#ahtp7@P&xvDwotJteSC7S`C#IYfm27*BcF(7EECOBUlHA}1S_YzjzHl3fN-XdJ zaC7t9&j?GLZTkXFjtq|K6b*IHUSev?X)xhbt3U5rh&;<-QeruiXz*JhXsC;37R+uioGAfPFp-{o#0wM+3qGtL z_vR+QzCBTL2-R&=4@(h6n3vj+@^GZ9nRh5Zz>-;HL@^coAjx1y$YpXx9#h(!x8J!zlG&`-Y2*$w*XJ>8gf;x1BfUQSQ#FgKMf%j zy>wuDzt^rLi~hL-2a85;hKU`ju+g~7TU`Rm!#r-zN&A=8f$>G2@wf4yH#(l$A=>Hi z&50t4s0v`>JRGxCA?c+fs^CMUqpIc6#(7G2_C&BLX#H>3XV+5w*2qKCDDKAF|(UAqZVYZ9j5DI)G>iQj4C1Q52(Q6 zhWhieZ0Xoqkxgduc7FvhzX|nW+}R=j%h+;#QHJTX>l!pt3<*6ZQgO)nyzuJ11_Zy& z(^eqfD{1WKP&%iVsz)@WToydQsnOFL({>j>7?#ijf4O2ywlpuX5V5U1AK~DZnnhMR ztTnn)-SfvNgMPg%Fq)MW56-e|0hZKzbbw`;|A`zh#BeN?%#~BdtVrb%5o35g zTn!Y-ZAUC7MW!+!iPK=b>Ovu8tta#|97moac~m!wC)&e?wtEM(M88K(A|zRp0B|Bc*>mR!H1J@6KpR~w*pLVWYnSy&GQ7{ZSvyS!`Jn7+P-Z!3$f}svr=8nD zHRsXzImn&cj?sCfU5gDa*D<<}P{cpAD3megf|N-5WF~TUV-hW>p`*x%d1`3NRXoF^ zd@eYmy%IN64b5;gvf=9=*Alo>7Od5s1_pKMD=8zsti9N2aI0M^xXo7Yb+LVns?Wb z3&B>BHKC{F<^%#BG$@cvPano4FuDSBkB%FyOdmS3l#zB6d=SI>n7-7Ip~PR16&E}J z@C`Xq_2wp}z2upX2tVVfvyzSL1mMrLSJfu@F|>^o5#sbF7DWf}9xs+y3v!=+U{20Q z{__f*C79(>MAbNdaa)Vn-iViluK-ys&{H}P_0BX3m@#C{I(>gx_nkha5<#;IqDc=Nxp?#f2p&~s z!3FllqyH#(mjINOCl!5;_3^k|^1bF>fGkgW_>s**hVM@0_79u+QF6#nG(vTYkjwhm zi$#%#^%7 zc5_K99Xf{r%EiJ${^@heWl5>(?}CfiU|={zs&J-CbTx;BMnTqdE&;7*5=x>`p2kmu zBld6?O{om`c+;qM9SvO@NQH=!<5{~Hu}tWG+{_kdJXr0Fe`znj9(j;tX#8rPbb`Hh z2I*cLw#pq>sX^O#AR$9u*n^b;0f}4BL?}jCHbWKhhnCrDu8uLh<(!U|_67ZtjST{G zJTeVcWU`tuK#(y$FqBc-|^dvir#f(;zZ+-nlcfh zF5C>!j=p)LtK%ALXsoMmZaPTVAXJ%;|DI^vHZrbr1UpVJoLn!lz=fN++Lf-q3i z70tMO22#MxW*GFa_-Id&kbW?+ICnm&S5NV!g@7sZ_-6}F$yA%Ny+6L-C1IhFRx8r! zvxnDf%h;)wr>L=U<6AK|nrzfU zh1Z0zr1b4E_!vVTt8dE>UGLh{cZcQ?%c8J;+R|j8dA4^TkvYRLwxahXX!4__heC5l zGQ}zFnf-NP<}#637T@vB_m;0ErI=Z74UL8cyk2!G-G*-?{itlt6pZHAGR!Bs8p%de z^vl)7W;=h=%Z6JgEnq5Xw)xi6wG1CUKXbQ^5MpjmM5X0Ogj5psAc;Rhv`pX*-N^~J zdAWR&^51c2(4UnVquNyj1-n9pxRt{Jt@?Ztry9V%96aG15|Y8Mffud;rKTk1VA@ae zhh)p^=wul*yH30AvE%6Om@e{$Y77~p)Y1_w4#gb}+EId!Ua^FhF45D&lbu}N#6v+z zoE~rz*u2%kB4GTPHuFlKSC2|CkSBUdV}9U)iQ^A}nCtWdj$~HSkhNGgN5~xm1Le;W zfQ2X!G){vOORHL3r+r)%waB6rL<=Zq6&(OLm?46b8ML5kMZ-um02_dw?vj^s8CnDg z$A|KCO@MiNY$ing#4P?n)P`JiT11=q;L@&;1EQ%`AMs5AS9w>aqpUINn!=t`w+8S{ zEK!9F;h8We8uHSamdSL z!!Cr$p_@oLdid*EAnjnIvKqRDMryNiBB`@ZPf>lFXC}GXc}O)_K#}7^X$f#n*7jX- zQ3f-zp#id%OlXVpNMN=vuxiwVYGpuF>S6Zfb5A7PCg|EH}jY1#g<@Y{+ykYfPuT@AmWjGRWd}#I2KRV{hz)`IWBxIi6vrvT`2^o6Xp8rStB8bo{ik}P8-0vt?e$7u_+V%hi z5*o4-D+^ZB+c~lKiH4d=J>2bC8^LFK~}U91^*50#<^F#gQb z79$t@lRDoDE7Ybh+?czk4o4-KCIVwjFg;DZ#gH7*VOsVc!sGpe9F+i zHPc_B>9AVX-fe=*1>X!)SA#5=@bY-RRFvOF!V(3sm3Uv}DejA}e_F_AuzXi`1u*D& zA}s_t9rzx7Zs6|qWE)Ja|;X48Le|unY!HE<%lE9&z z5?}#<*DR3aCL7dfT_D8hAUJyM{}k-R6r%im*!JxvjZ$3EiI? zgjD-I$_)NOyPS(n+zSdt_Jk9)xavyzLJk{eBaLo()IS}OC>Ati0*aOIL`oM;yI8p3 zp#X>SC+ZpV3u=j7Qrm<~Ka4wNu~g;r}YMc9E7&BS9O($0F_l zY$ZVnT00GOcH1-MVe6%j8bBtkpLa2TR~8|pe*!fC1IY$e7fp(3{3OjG2-?+f#b!`P zGJ&O3ryNb5LGkoQs2rP~L7>jirx%@V>X#CnjhD!9JDo_gY+qpX9AOuX-rWr&#?D>4 z>HA`3m3x)yDpljBuOZ$3D!Wdw5`9 zNMU_L$=?fPibC?*WJPHn`59CtUHr0C0&R4UP@L1yABME;GTcYIl6aVeKM+ICH z9!-LqC1JaoQD6NWvsl`{koHakH*mG#URerinJ1}g(d@6R^WXvk3JxCPIj6CA zi!P*m{8)mSmDZi^DzQ(*>}czVA5cmhfRfsN&9QyuS43yQ&L+ z`|~-6t4I^+3&~lITlVA+*u{1_sYjm^Bwfe>p$R04I~=AW5bnmvenLGWb_-H#S%?rY z@5VknPMwVJG`K7ghpZJAcwEvW$^(;EL}PD1KSXMH%Sj!zp(v_S!)$Z(nmCbAxZ|@WY_}nXu6|N5wh9~tASg*6 ze64^}E*>2UjD?NM?k7_e8)@i@et?aM^Q4)q+7vC-2#lDIG1h2DB`Zhr%L;bQMb8& zmj!w+;_QFb?dXl1lVAGqm_X8-&^{dR#n_I@Trv0L3J2=jw1ws_1V?ngERHTOlI6Nl ze7lsw90&-<6DDVg@`=?0o=~URX~9ixXeaxb8CX}uaOd@0mNXSG)EMXw%hd>13lS=?>DzbxVylnAnCo{gg`-6BPl^gCsgL%-U= z6v>4e$A2p91|=GTW#4(V*3|{u6P|g*t>S8Qh$&j6xC&2Ku@2Mtq;DQ=(i1Vp6`L5=3Am0{$sMlkv%6rq18@ z?1imlO>kTt+16c|AWNQoR$l#W(|L#B)=y;^QrD+R<;ohTvuN>nwzV_bKv&Y5;gRV2 zk5a^eNbTxqXj{~$`HL`SpDc9urd!R7)!f?J>*han#EfgR$VGTHkVI^Fhlsxn=`NP* zD7Xl2wj7Mq9ToZj&)EXCyC_}jWjP5atBSdM_Y7-YmCNuS8l$rZ4M%ZN#wc=xS>-mz z6N#UCIAF|Gw$#xE3DJlSLM9$HOk!tw{X^7Tdh%CK)VDHUCtTSyuaa$pkg^Vo&CVE| z&E}hxCm@*(v|JE zT1z$N_0awD28uDg8Vq68%+Edg{Jmu1fdo=CVXJv~1aLV!N*TQeTG$&%WoEZ2LcFD14R}udW?y1|n>=JReAqBTYu&7^8LGwgMtv=BRFhPaBlvr$j{`5< z7I2U$A)b+epe77;bnSfT0x;z>`}C7n+{x?g6G#nd7+#~6T`FDTNfuTwRV&j-4K5WF z5+`L>QShs zMy^Qq$Q5{^&>6AIVL-g0)5Z9OQ?HRcO>CeSsH1R?DTGnx^}c(+USEZsoq$LXa9Dhi zVd& zLaT=boX#MjZ6V6U>F69qg3cCQ@F$Gduwf9n745+7`X}e($qv5^EK$J-leV2E_jZiR zKEmjZy=(1VDBh^_a$1@~T>p|m^qX@A1!yh~RMhZ{T13xG33gKQR7+L6rebeS5jQ{r zf}qa%4F52wzpOj)l2=UVquZDt4=yyITpZWJ(I2=x9Z3qa3w{G~fob6JZ!fZEWjSEx z*oWEQjG$kgrof_w)uuCt^Q!Y59MTl4Cx4a5&1`jyRF}U?JM~*#b=r5t-dr8K?wlWe zJf1{SB?Mi5gaKewy$eD(Bs-62$Ji5WwSqz=$4n5zoqu%w$lTl$Gw4Yy{|+UIOz2Cx zV<}JHEk_inom!`OExg{JBmVBIqP^&O?|;>eKJ?8uUFMrQsW`d_f_6qX!_B3Y_n(_- zn;z14zJ5DIovg8Pnf6S*b6ZkzeS{hSfyEL(R)J>K~cy^Zs1R%#(s<55X73 zIH$fA{6ChH0AKV%M~ZyvFN6n8Ng=swr77o42?QQ=xW~{HBexNR#ElgfpkimONXk1m zSbMuM)Hq329!uFUUj?UkRlsT2vLjCu+>y|5#-3m*X+iLK+02O;r(k$W;NO=*cgbRg zVD#hmb7zq!YXF!42-eWj9;H#|j5(wr%Tp&973e0=y66QK^=MKia5yLE!yR~^fWw8Q zfCzXW#^M~#E=}SZtPcWcrdQK9A0zvFef?2xffL>U-po6H1@&hY1Vj9(bjk11J>5Bb zF)}dJPfCJIS&tM%88*psG1-ac37^aKmkS5yW5iAZ`Hf&P^ zf_Tt-b0Fa1Aiz&IqyqC)0+jjs48cSE<`XL)Ghd>)_DVg@Z$T9>_~Vs zC4g7T3tyB6R+FiQ~SK@8%-q&l=( zi_;I=p*Aw5oacxCGU{q-bV1_Wu&Z~(Js11~^eTV199^kZ=VFkFC@-A->*mS|1VguI z@idF#u7yZBZ?5xif$(r2mQNPBPSpFz_>t80i3867T}mfEbBA>*XPl*Cy2G*w zx{$H?01MiU>h0>B8@~Cio@<3Tt^l+w1&`4SYveb5lBfLQGt$<)zWD{>yK#|odB%3tWA+}6hCft z^r0n!_ZHMT5yH=hA(-Puzg*k$>X8Q?yG9??mUOxN(HY#)PH+<16K$=2d6#ssxS>Nq znAf-(-5o6Hb(bswkcmL%yQ!3N8Ux1RFr(@%z93{*=BF?^E%BgOG>2@XXs*T z{&ZA9HjH)|(?8mOH5-`u3?&OzvQXKa>)AZ{6#=6SV2RnscF9#%?OSH$TI=D(c@Kia zWU??n+ds|6&R3*_B*>0_I$h_fm5q|eh8WNsM$49;Kkpfr3GUxOi&P?75$%;cFl9&4 zz=PlYU?ACxPenaaz2{S-$MAEFUddyLD?s8Gil=8kwb3`8U;cC&oh!vR0}q1qy8pmh zKRGH&!iR=W%Z=w0>6cHfiraj3W=b<%%4SW}rdC+@!~N)m)>9~+`0ZG9YE|ezkb|!N z-vn<5B8o|~lN|%kxNM`hK{RS4juMTdB9%8D{)XfDT5vtdq6 zc%R)?sA(7jc~}ei@gAJe5-?f-<~^Xc=9+i!B9Tri;@^M$wE9#U+HD`YP|vI@*kE|!K>3mrq}BPb}z3Iv`Ck(r9>Q`thCbCa{nZjSYkioiSD?! z(mHuO;^qqAM}uj{tBT3Yj0qx-k}XJsWbFvy>EXbJk>ivNW)m`+*3-0%g(ff=!pPwf z2}DwuOv`(O=p6@|zCzPr{8=#F){P#+KsXskj#Gn3!6b$9nUoTr!I4^w($Wr=*F_vP z?g8M}ocjwol@O?C{HDJUrA_^BuL&HfDK9uqy4q5$!T(n+waLd!V7V<+YCHD-{e@N> zYdSk}dhqyTGD~ozVl4H+ewU*!TB%lrjbg9a*PV8XP2nuf=h>*>%}9Nzi`i!EVY*7C zjV@-7vF$6a!MhOXm=;Z&OlW$Q<`w-_42Xif_eQN&`)LS-JwDlr$32~LY3?5}RWodz zoj2BY+GfO5epqKs`6n}?>`R0yP*q%#tSTv12lyp_X^4pVr&w9^;5?#7umfBn08l`$ zzhyOy8vrh~BcG4~;N+3)92o#UZBONq0g$SONeE5?cr;^aphs{hKa-a z+$A~u$k#%VC!*UdhN8Nk&P5}1SFQ(U+^nDW?CN9gw|S|lP$z0a_EKxFR=gLZ>fR-I)vS`#lS=p=RyYi{BGC&- z^#?==9!;1YYeI4`T#sj*hHb#@STB~u({|equF#7t{CF+K$8Fqb#Q%tySzJAs+T+Oa z6nkwI9Uz3cw}Y2aQ((K>`0`5p=m*xIL>-|2cL8pdY?S<*FQ)~!eBrjcOtkuXaFD^V zVA?&syp-VW2l^gz?ZTqu@WAhBE?S=L%(i$ewO zWe~7yJ8=kJBAKQGU>j%hq$15@Ix@u_2tiD>t3Kb=1*dg0%z8Hh0u@xkAl$$T`eRiJ z;w)SCp-N2=9bXP;<3duHOyybxlAH<}_Yp!rdWs}BcQIE&lA=rT=}qkQNdW@~2$k%g zzbAeaKintrw{e+C(M8B{ioumx?e?bQYjtlucsweLU)00}E6Cjq8>)n4`h72HQYalc zP7QG(s$>YS)Lpv`7iis}WP=J5rAc1*>11IQxLh;v1h2zC8OY7GGUl3-l}26qIPNw&lL}emVq==lYNPRnMp(9fOD3REZ1^> zbxP#&^Ipkb=a)xzis!m4Q9)Yo{Ny)rIHbHoBGpR-i9}nBE#WvV9F9dgZsACs9MID! z1Dw;xiIAZ{M-n>NWLX-+h*iI|5Iv26qc81TbHM2!**B|oDH=EKnUAzzxKo&rIqu0lYgIZB%3l&#c=oH(}yqN5XT_-7w zFC6)v1zzFaB_9!FHDyn8P)$w}4VM zVYtyS+RsxLTP3FBT(uBZk$b4H7PnI5e(q2%d9?LjnM(EP;%!b5ePjalpcJ$_nWx7= z)`looSI(shsdMX~uRDsuoS@UiU1voKy(;?q1Qu&KQjQO@G}*a+w=I^OdVp*k`un8! zs+?K?B}=!tR1zK>8ijGx63~$Z9KN` z`^+I$^9R7NLq0Nd*<3T!iRuyEgDT*$DiaVU>?a%jGp$3ONG6KH*7c}n0)qjm1sAGj z^Jsm3JaO73Vxg+pJX)XM3o3h<&D((xfNM0$&$NW>YQx>6cT~y04|i+J9zL;6{$AY1 z_5NW4zVnQWgG}=NX2`%#`|IqqZJ_DCq@Zi2It+YhnSOTG=H%Gzt*v%1p;m*vDfNjt zUF6;81cX*lx_{_L5S-gh?z*yv`bs8nt}Pb$StaSSX7#XGI%wSeF{g3is%S`;0wW%cTuo(cwU~>`uK4HqW=>FIkykC?!%qZ4n|t7M)@NL zIipK6psC%eSMUSr7F-;u4}5;5-4A+~m4dg&Y1%;3L+>2>T}F12WxroII;3#`4_C2Y z^qtz`%PtdWX^>-Z^HRWU{38PQqpw!+Sl`PONuT25364Ep6uroNb2c($&_|E~q_&pL zgNX_&T)9g!kjOmUw_o}`?ZDXRrG=O6-b@OmC`q7eY>8yMl845g1wB*AWEUF*HJv+W zC0mVFcjq1nXmpkH33u*X6B)EVpdVA%dwN@!#G>hW^U(A-){'d1Mlv9Dcqdu7tF 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 V=VGRl8m#`%cC;f?eCPlA^&g!Ko?QR{ literal 0 HcmV?d00001 diff --git a/static/lib/highlightjs/cdn-release@11.2.0/build/LICENSE b/static/lib/highlightjs/cdn-release@11.2.0/build/LICENSE deleted file mode 100644 index 2250cc7e..00000000 --- a/static/lib/highlightjs/cdn-release@11.2.0/build/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2006, Ivan Sagalaev. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/static/lib/highlightjs/cdn-release@11.2.0/build/README.md b/static/lib/highlightjs/cdn-release@11.2.0/build/README.md deleted file mode 100644 index 30d84b95..00000000 --- a/static/lib/highlightjs/cdn-release@11.2.0/build/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Highlight.js CDN Assets - -[![install size](https://packagephobia.now.sh/badge?p=highlight.js)](https://packagephobia.now.sh/result?p=highlight.js) - -**This package contains only the CDN build assets of highlight.js.** - -This may be what you want if you'd like to install the pre-built distributable highlight.js client-side assets via NPM. If you're wanting to use highlight.js mainly on the server-side you likely want the [highlight.js][1] package instead. - -To access these files via CDN:
    -https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@latest/build/ - -**If you just want a single .js file with the common languages built-in: -** - ---- - -## Highlight.js - -Highlight.js is a syntax highlighter written in JavaScript. It works in -the browser as well as on the server. It works with pretty much any -markup, doesn’t depend on any framework, and has automatic language -detection. - -If you'd like to read the full README:
    - - -## License - -Highlight.js is released under the BSD License. See [LICENSE][7] file -for details. - -## Links - -The official site for the library is at . - -The Github project may be found at: - -Further in-depth documentation for the API and other topics is at -. - -A list of the Core Team and contributors can be found in the [CONTRIBUTORS.md][8] file. - -[1]: https://www.npmjs.com/package/highlight.js -[7]: https://github.com/highlightjs/highlight.js/blob/main/LICENSE -[8]: https://github.com/highlightjs/highlight.js/blob/main/CONTRIBUTORS.md diff --git a/static/lib/highlightjs/cdn-release@11.2.0/build/es/core.js b/static/lib/highlightjs/cdn-release@11.2.0/build/es/core.js deleted file mode 100644 index ae4a0226..00000000 --- a/static/lib/highlightjs/cdn-release@11.2.0/build/es/core.js +++ /dev/null @@ -1,2503 +0,0 @@ -/*! - Highlight.js v11.2.0 (git: 2a5c592e5e) - (c) 2006-2021 Ivan Sagalaev and other contributors - License: BSD-3-Clause - */ -var deepFreezeEs6 = {exports: {}}; - -function deepFreeze(obj) { - if (obj instanceof Map) { - obj.clear = obj.delete = obj.set = function () { - throw new Error('map is read-only'); - }; - } else if (obj instanceof Set) { - obj.add = obj.clear = obj.delete = function () { - throw new Error('set is read-only'); - }; - } - - // Freeze self - Object.freeze(obj); - - Object.getOwnPropertyNames(obj).forEach(function (name) { - var prop = obj[name]; - - // Freeze prop if it is an object - if (typeof prop == 'object' && !Object.isFrozen(prop)) { - deepFreeze(prop); - } - }); - - return obj; -} - -deepFreezeEs6.exports = deepFreeze; -deepFreezeEs6.exports.default = deepFreeze; - -var deepFreeze$1 = deepFreezeEs6.exports; - -/** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */ -/** @typedef {import('highlight.js').CompiledMode} CompiledMode */ -/** @implements CallbackResponse */ - -class Response { - /** - * @param {CompiledMode} mode - */ - constructor(mode) { - // eslint-disable-next-line no-undefined - if (mode.data === undefined) mode.data = {}; - - this.data = mode.data; - this.isMatchIgnored = false; - } - - ignoreMatch() { - this.isMatchIgnored = true; - } -} - -/** - * @param {string} value - * @returns {string} - */ -function escapeHTML(value) { - return value - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); -} - -/** - * performs a shallow merge of multiple objects into one - * - * @template T - * @param {T} original - * @param {Record[]} objects - * @returns {T} a single new object - */ -function inherit$1(original, ...objects) { - /** @type Record */ - const result = Object.create(null); - - for (const key in original) { - result[key] = original[key]; - } - objects.forEach(function(obj) { - for (const key in obj) { - result[key] = obj[key]; - } - }); - return /** @type {T} */ (result); -} - -/** - * @typedef {object} Renderer - * @property {(text: string) => void} addText - * @property {(node: Node) => void} openNode - * @property {(node: Node) => void} closeNode - * @property {() => string} value - */ - -/** @typedef {{kind?: string, sublanguage?: boolean}} Node */ -/** @typedef {{walk: (r: Renderer) => void}} Tree */ -/** */ - -const SPAN_CLOSE = ''; - -/** - * Determines if a node needs to be wrapped in - * - * @param {Node} node */ -const emitsWrappingTags = (node) => { - return !!node.kind; -}; - -/** - * - * @param {string} name - * @param {{prefix:string}} options - */ -const expandScopeName = (name, { prefix }) => { - if (name.includes(".")) { - const pieces = name.split("."); - return [ - `${prefix}${pieces.shift()}`, - ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`)) - ].join(" "); - } - return `${prefix}${name}`; -}; - -/** @type {Renderer} */ -class HTMLRenderer { - /** - * Creates a new HTMLRenderer - * - * @param {Tree} parseTree - the parse tree (must support `walk` API) - * @param {{classPrefix: string}} options - */ - constructor(parseTree, options) { - this.buffer = ""; - this.classPrefix = options.classPrefix; - parseTree.walk(this); - } - - /** - * Adds texts to the output stream - * - * @param {string} text */ - addText(text) { - this.buffer += escapeHTML(text); - } - - /** - * Adds a node open to the output stream (if needed) - * - * @param {Node} node */ - openNode(node) { - if (!emitsWrappingTags(node)) return; - - let scope = node.kind; - if (node.sublanguage) { - scope = `language-${scope}`; - } else { - scope = expandScopeName(scope, { prefix: this.classPrefix }); - } - this.span(scope); - } - - /** - * Adds a node close to the output stream (if needed) - * - * @param {Node} node */ - closeNode(node) { - if (!emitsWrappingTags(node)) return; - - this.buffer += SPAN_CLOSE; - } - - /** - * returns the accumulated buffer - */ - value() { - return this.buffer; - } - - // helpers - - /** - * Builds a span element - * - * @param {string} className */ - span(className) { - this.buffer += ``; - } -} - -/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} | string} Node */ -/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} } DataNode */ -/** @typedef {import('highlight.js').Emitter} Emitter */ -/** */ - -class TokenTree { - constructor() { - /** @type DataNode */ - this.rootNode = { children: [] }; - this.stack = [this.rootNode]; - } - - get top() { - return this.stack[this.stack.length - 1]; - } - - get root() { return this.rootNode; } - - /** @param {Node} node */ - add(node) { - this.top.children.push(node); - } - - /** @param {string} kind */ - openNode(kind) { - /** @type Node */ - const node = { kind, children: [] }; - this.add(node); - this.stack.push(node); - } - - closeNode() { - if (this.stack.length > 1) { - return this.stack.pop(); - } - // eslint-disable-next-line no-undefined - return undefined; - } - - closeAllNodes() { - while (this.closeNode()); - } - - toJSON() { - return JSON.stringify(this.rootNode, null, 4); - } - - /** - * @typedef { import("./html_renderer").Renderer } Renderer - * @param {Renderer} builder - */ - walk(builder) { - // this does not - return this.constructor._walk(builder, this.rootNode); - // this works - // return TokenTree._walk(builder, this.rootNode); - } - - /** - * @param {Renderer} builder - * @param {Node} node - */ - static _walk(builder, node) { - if (typeof node === "string") { - builder.addText(node); - } else if (node.children) { - builder.openNode(node); - node.children.forEach((child) => this._walk(builder, child)); - builder.closeNode(node); - } - return builder; - } - - /** - * @param {Node} node - */ - static _collapse(node) { - if (typeof node === "string") return; - if (!node.children) return; - - if (node.children.every(el => typeof el === "string")) { - // node.text = node.children.join(""); - // delete node.children; - node.children = [node.children.join("")]; - } else { - node.children.forEach((child) => { - TokenTree._collapse(child); - }); - } - } -} - -/** - Currently this is all private API, but this is the minimal API necessary - that an Emitter must implement to fully support the parser. - - Minimal interface: - - - addKeyword(text, kind) - - addText(text) - - addSublanguage(emitter, subLanguageName) - - finalize() - - openNode(kind) - - closeNode() - - closeAllNodes() - - toHTML() - -*/ - -/** - * @implements {Emitter} - */ -class TokenTreeEmitter extends TokenTree { - /** - * @param {*} options - */ - constructor(options) { - super(); - this.options = options; - } - - /** - * @param {string} text - * @param {string} kind - */ - addKeyword(text, kind) { - if (text === "") { return; } - - this.openNode(kind); - this.addText(text); - this.closeNode(); - } - - /** - * @param {string} text - */ - addText(text) { - if (text === "") { return; } - - this.add(text); - } - - /** - * @param {Emitter & {root: DataNode}} emitter - * @param {string} name - */ - addSublanguage(emitter, name) { - /** @type DataNode */ - const node = emitter.root; - node.kind = name; - node.sublanguage = true; - this.add(node); - } - - toHTML() { - const renderer = new HTMLRenderer(this, this.options); - return renderer.value(); - } - - finalize() { - return true; - } -} - -/** - * @param {string} value - * @returns {RegExp} - * */ - -/** - * @param {RegExp | string } re - * @returns {string} - */ -function source(re) { - if (!re) return null; - if (typeof re === "string") return re; - - return re.source; -} - -/** - * @param {RegExp | string } re - * @returns {string} - */ -function lookahead(re) { - return concat('(?=', re, ')'); -} - -/** - * @param {...(RegExp | string) } args - * @returns {string} - */ -function concat(...args) { - const joined = args.map((x) => source(x)).join(""); - return joined; -} - -function stripOptionsFromArgs(args) { - const opts = args[args.length - 1]; - - if (typeof opts === 'object' && opts.constructor === Object) { - args.splice(args.length - 1, 1); - return opts; - } else { - return {}; - } -} - -/** - * Any of the passed expresssions may match - * - * Creates a huge this | this | that | that match - * @param {(RegExp | string)[] } args - * @returns {string} - */ -function either(...args) { - const opts = stripOptionsFromArgs(args); - const joined = '(' + - (opts.capture ? "" : "?:") + - args.map((x) => source(x)).join("|") + ")"; - return joined; -} - -/** - * @param {RegExp} re - * @returns {number} - */ -function countMatchGroups(re) { - return (new RegExp(re.toString() + '|')).exec('').length - 1; -} - -/** - * Does lexeme start with a regular expression match at the beginning - * @param {RegExp} re - * @param {string} lexeme - */ -function startsWith(re, lexeme) { - const match = re && re.exec(lexeme); - return match && match.index === 0; -} - -// BACKREF_RE matches an open parenthesis or backreference. To avoid -// an incorrect parse, it additionally matches the following: -// - [...] elements, where the meaning of parentheses and escapes change -// - other escape sequences, so we do not misparse escape sequences as -// interesting elements -// - non-matching or lookahead parentheses, which do not capture. These -// follow the '(' with a '?'. -const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./; - -// **INTERNAL** Not intended for outside usage -// join logically computes regexps.join(separator), but fixes the -// backreferences so they continue to match. -// it also places each individual regular expression into it's own -// match group, keeping track of the sequencing of those match groups -// is currently an exercise for the caller. :-) -/** - * @param {(string | RegExp)[]} regexps - * @param {{joinWith: string}} opts - * @returns {string} - */ -function _rewriteBackreferences(regexps, { joinWith }) { - let numCaptures = 0; - - return regexps.map((regex) => { - numCaptures += 1; - const offset = numCaptures; - let re = source(regex); - let out = ''; - - while (re.length > 0) { - const match = BACKREF_RE.exec(re); - if (!match) { - out += re; - break; - } - out += re.substring(0, match.index); - re = re.substring(match.index + match[0].length); - if (match[0][0] === '\\' && match[1]) { - // Adjust the backreference. - out += '\\' + String(Number(match[1]) + offset); - } else { - out += match[0]; - if (match[0] === '(') { - numCaptures++; - } - } - } - return out; - }).map(re => `(${re})`).join(joinWith); -} - -/** @typedef {import('highlight.js').Mode} Mode */ -/** @typedef {import('highlight.js').ModeCallback} ModeCallback */ - -// Common regexps -const MATCH_NOTHING_RE = /\b\B/; -const IDENT_RE = '[a-zA-Z]\\w*'; -const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*'; -const NUMBER_RE = '\\b\\d+(\\.\\d+)?'; -const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float -const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b... -const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~'; - -/** -* @param { Partial & {binary?: string | RegExp} } opts -*/ -const SHEBANG = (opts = {}) => { - const beginShebang = /^#![ ]*\//; - if (opts.binary) { - opts.begin = concat( - beginShebang, - /.*\b/, - opts.binary, - /\b.*/); - } - return inherit$1({ - scope: 'meta', - begin: beginShebang, - end: /$/, - relevance: 0, - /** @type {ModeCallback} */ - "on:begin": (m, resp) => { - if (m.index !== 0) resp.ignoreMatch(); - } - }, opts); -}; - -// Common modes -const BACKSLASH_ESCAPE = { - begin: '\\\\[\\s\\S]', relevance: 0 -}; -const APOS_STRING_MODE = { - scope: 'string', - begin: '\'', - end: '\'', - illegal: '\\n', - contains: [BACKSLASH_ESCAPE] -}; -const QUOTE_STRING_MODE = { - scope: 'string', - begin: '"', - end: '"', - illegal: '\\n', - contains: [BACKSLASH_ESCAPE] -}; -const PHRASAL_WORDS_MODE = { - begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ -}; -/** - * Creates a comment mode - * - * @param {string | RegExp} begin - * @param {string | RegExp} end - * @param {Mode | {}} [modeOptions] - * @returns {Partial} - */ -const COMMENT = function(begin, end, modeOptions = {}) { - const mode = inherit$1( - { - scope: 'comment', - begin, - end, - contains: [] - }, - modeOptions - ); - mode.contains.push({ - scope: 'doctag', - // hack to avoid the space from being included. the space is necessary to - // match here to prevent the plain text rule below from gobbling up doctags - begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)', - end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/, - excludeBegin: true, - relevance: 0 - }); - const ENGLISH_WORD = either( - // list of common 1 and 2 letter words in English - "I", - "a", - "is", - "so", - "us", - "to", - "at", - "if", - "in", - "it", - "on", - // note: this is not an exhaustive list of contractions, just popular ones - /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc - /[A-Za-z]+[-][a-z]+/, // `no-way`, etc. - /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences - ); - // looking like plain text, more likely to be a comment - mode.contains.push( - { - // TODO: how to include ", (, ) without breaking grammars that use these for - // comment delimiters? - // begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/ - // --- - - // this tries to find sequences of 3 english words in a row (without any - // "programming" type syntax) this gives us a strong signal that we've - // TRULY found a comment - vs perhaps scanning with the wrong language. - // It's possible to find something that LOOKS like the start of the - // comment - but then if there is no readable text - good chance it is a - // false match and not a comment. - // - // for a visual example please see: - // https://github.com/highlightjs/highlight.js/issues/2827 - - begin: concat( - /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */ - '(', - ENGLISH_WORD, - /[.]?[:]?([.][ ]|[ ])/, - '){3}') // look for 3 words in a row - } - ); - return mode; -}; -const C_LINE_COMMENT_MODE = COMMENT('//', '$'); -const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/'); -const HASH_COMMENT_MODE = COMMENT('#', '$'); -const NUMBER_MODE = { - scope: 'number', - begin: NUMBER_RE, - relevance: 0 -}; -const C_NUMBER_MODE = { - scope: 'number', - begin: C_NUMBER_RE, - relevance: 0 -}; -const BINARY_NUMBER_MODE = { - scope: 'number', - begin: BINARY_NUMBER_RE, - relevance: 0 -}; -const REGEXP_MODE = { - // this outer rule makes sure we actually have a WHOLE regex and not simply - // an expression such as: - // - // 3 / something - // - // (which will then blow up when regex's `illegal` sees the newline) - begin: /(?=\/[^/\n]*\/)/, - contains: [{ - scope: 'regexp', - begin: /\//, - end: /\/[gimuy]*/, - illegal: /\n/, - contains: [ - BACKSLASH_ESCAPE, - { - begin: /\[/, - end: /\]/, - relevance: 0, - contains: [BACKSLASH_ESCAPE] - } - ] - }] -}; -const TITLE_MODE = { - scope: 'title', - begin: IDENT_RE, - relevance: 0 -}; -const UNDERSCORE_TITLE_MODE = { - scope: 'title', - begin: UNDERSCORE_IDENT_RE, - relevance: 0 -}; -const METHOD_GUARD = { - // excludes method names from keyword processing - begin: '\\.\\s*' + UNDERSCORE_IDENT_RE, - relevance: 0 -}; - -/** - * Adds end same as begin mechanics to a mode - * - * Your mode must include at least a single () match group as that first match - * group is what is used for comparison - * @param {Partial} mode - */ -const END_SAME_AS_BEGIN = function(mode) { - return Object.assign(mode, - { - /** @type {ModeCallback} */ - 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; }, - /** @type {ModeCallback} */ - 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); } - }); -}; - -var MODES = /*#__PURE__*/Object.freeze({ - __proto__: null, - MATCH_NOTHING_RE: MATCH_NOTHING_RE, - IDENT_RE: IDENT_RE, - UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE, - NUMBER_RE: NUMBER_RE, - C_NUMBER_RE: C_NUMBER_RE, - BINARY_NUMBER_RE: BINARY_NUMBER_RE, - RE_STARTERS_RE: RE_STARTERS_RE, - SHEBANG: SHEBANG, - BACKSLASH_ESCAPE: BACKSLASH_ESCAPE, - APOS_STRING_MODE: APOS_STRING_MODE, - QUOTE_STRING_MODE: QUOTE_STRING_MODE, - PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE, - COMMENT: COMMENT, - C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE, - C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE, - HASH_COMMENT_MODE: HASH_COMMENT_MODE, - NUMBER_MODE: NUMBER_MODE, - C_NUMBER_MODE: C_NUMBER_MODE, - BINARY_NUMBER_MODE: BINARY_NUMBER_MODE, - REGEXP_MODE: REGEXP_MODE, - TITLE_MODE: TITLE_MODE, - UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE, - METHOD_GUARD: METHOD_GUARD, - END_SAME_AS_BEGIN: END_SAME_AS_BEGIN -}); - -/** -@typedef {import('highlight.js').CallbackResponse} CallbackResponse -@typedef {import('highlight.js').CompilerExt} CompilerExt -*/ - -// Grammar extensions / plugins -// See: https://github.com/highlightjs/highlight.js/issues/2833 - -// Grammar extensions allow "syntactic sugar" to be added to the grammar modes -// without requiring any underlying changes to the compiler internals. - -// `compileMatch` being the perfect small example of now allowing a grammar -// author to write `match` when they desire to match a single expression rather -// than being forced to use `begin`. The extension then just moves `match` into -// `begin` when it runs. Ie, no features have been added, but we've just made -// the experience of writing (and reading grammars) a little bit nicer. - -// ------ - -// TODO: We need negative look-behind support to do this properly -/** - * Skip a match if it has a preceding dot - * - * This is used for `beginKeywords` to prevent matching expressions such as - * `bob.keyword.do()`. The mode compiler automatically wires this up as a - * special _internal_ 'on:begin' callback for modes with `beginKeywords` - * @param {RegExpMatchArray} match - * @param {CallbackResponse} response - */ -function skipIfHasPrecedingDot(match, response) { - const before = match.input[match.index - 1]; - if (before === ".") { - response.ignoreMatch(); - } -} - -/** - * - * @type {CompilerExt} - */ -function scopeClassName(mode, _parent) { - // eslint-disable-next-line no-undefined - if (mode.className !== undefined) { - mode.scope = mode.className; - delete mode.className; - } -} - -/** - * `beginKeywords` syntactic sugar - * @type {CompilerExt} - */ -function beginKeywords(mode, parent) { - if (!parent) return; - if (!mode.beginKeywords) return; - - // for languages with keywords that include non-word characters checking for - // a word boundary is not sufficient, so instead we check for a word boundary - // or whitespace - this does no harm in any case since our keyword engine - // doesn't allow spaces in keywords anyways and we still check for the boundary - // first - mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)'; - mode.__beforeBegin = skipIfHasPrecedingDot; - mode.keywords = mode.keywords || mode.beginKeywords; - delete mode.beginKeywords; - - // prevents double relevance, the keywords themselves provide - // relevance, the mode doesn't need to double it - // eslint-disable-next-line no-undefined - if (mode.relevance === undefined) mode.relevance = 0; -} - -/** - * Allow `illegal` to contain an array of illegal values - * @type {CompilerExt} - */ -function compileIllegal(mode, _parent) { - if (!Array.isArray(mode.illegal)) return; - - mode.illegal = either(...mode.illegal); -} - -/** - * `match` to match a single expression for readability - * @type {CompilerExt} - */ -function compileMatch(mode, _parent) { - if (!mode.match) return; - if (mode.begin || mode.end) throw new Error("begin & end are not supported with match"); - - mode.begin = mode.match; - delete mode.match; -} - -/** - * provides the default 1 relevance to all modes - * @type {CompilerExt} - */ -function compileRelevance(mode, _parent) { - // eslint-disable-next-line no-undefined - if (mode.relevance === undefined) mode.relevance = 1; -} - -// allow beforeMatch to act as a "qualifier" for the match -// the full match begin must be [beforeMatch][begin] -const beforeMatchExt = (mode, parent) => { - if (!mode.beforeMatch) return; - // starts conflicts with endsParent which we need to make sure the child - // rule is not matched multiple times - if (mode.starts) throw new Error("beforeMatch cannot be used with starts"); - - const originalMode = Object.assign({}, mode); - Object.keys(mode).forEach((key) => { delete mode[key]; }); - - mode.keywords = originalMode.keywords; - mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin)); - mode.starts = { - relevance: 0, - contains: [ - Object.assign(originalMode, { endsParent: true }) - ] - }; - mode.relevance = 0; - - delete originalMode.beforeMatch; -}; - -// keywords that should have no default relevance value -const COMMON_KEYWORDS = [ - 'of', - 'and', - 'for', - 'in', - 'not', - 'or', - 'if', - 'then', - 'parent', // common variable name - 'list', // common variable name - 'value' // common variable name -]; - -const DEFAULT_KEYWORD_SCOPE = "keyword"; - -/** - * Given raw keywords from a language definition, compile them. - * - * @param {string | Record | Array} rawKeywords - * @param {boolean} caseInsensitive - */ -function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) { - /** @type KeywordDict */ - const compiledKeywords = Object.create(null); - - // input can be a string of keywords, an array of keywords, or a object with - // named keys representing scopeName (which can then point to a string or array) - if (typeof rawKeywords === 'string') { - compileList(scopeName, rawKeywords.split(" ")); - } else if (Array.isArray(rawKeywords)) { - compileList(scopeName, rawKeywords); - } else { - Object.keys(rawKeywords).forEach(function(scopeName) { - // collapse all our objects back into the parent object - Object.assign( - compiledKeywords, - compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName) - ); - }); - } - return compiledKeywords; - - // --- - - /** - * Compiles an individual list of keywords - * - * Ex: "for if when while|5" - * - * @param {string} scopeName - * @param {Array} keywordList - */ - function compileList(scopeName, keywordList) { - if (caseInsensitive) { - keywordList = keywordList.map(x => x.toLowerCase()); - } - keywordList.forEach(function(keyword) { - const pair = keyword.split('|'); - compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])]; - }); - } -} - -/** - * Returns the proper score for a given keyword - * - * Also takes into account comment keywords, which will be scored 0 UNLESS - * another score has been manually assigned. - * @param {string} keyword - * @param {string} [providedScore] - */ -function scoreForKeyword(keyword, providedScore) { - // manual scores always win over common keywords - // so you can force a score of 1 if you really insist - if (providedScore) { - return Number(providedScore); - } - - return commonKeyword(keyword) ? 0 : 1; -} - -/** - * Determines if a given keyword is common or not - * - * @param {string} keyword */ -function commonKeyword(keyword) { - return COMMON_KEYWORDS.includes(keyword.toLowerCase()); -} - -/* - -For the reasoning behind this please see: -https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419 - -*/ - -/** - * @type {Record} - */ -const seenDeprecations = {}; - -/** - * @param {string} message - */ -const error = (message) => { - console.error(message); -}; - -/** - * @param {string} message - * @param {any} args - */ -const warn = (message, ...args) => { - console.log(`WARN: ${message}`, ...args); -}; - -/** - * @param {string} version - * @param {string} message - */ -const deprecated = (version, message) => { - if (seenDeprecations[`${version}/${message}`]) return; - - console.log(`Deprecated as of ${version}. ${message}`); - seenDeprecations[`${version}/${message}`] = true; -}; - -/* eslint-disable no-throw-literal */ - -/** -@typedef {import('highlight.js').CompiledMode} CompiledMode -*/ - -const MultiClassError = new Error(); - -/** - * Renumbers labeled scope names to account for additional inner match - * groups that otherwise would break everything. - * - * Lets say we 3 match scopes: - * - * { 1 => ..., 2 => ..., 3 => ... } - * - * So what we need is a clean match like this: - * - * (a)(b)(c) => [ "a", "b", "c" ] - * - * But this falls apart with inner match groups: - * - * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ] - * - * Our scopes are now "out of alignment" and we're repeating `b` 3 times. - * What needs to happen is the numbers are remapped: - * - * { 1 => ..., 2 => ..., 5 => ... } - * - * We also need to know that the ONLY groups that should be output - * are 1, 2, and 5. This function handles this behavior. - * - * @param {CompiledMode} mode - * @param {Array} regexes - * @param {{key: "beginScope"|"endScope"}} opts - */ -function remapScopeNames(mode, regexes, { key }) { - let offset = 0; - const scopeNames = mode[key]; - /** @type Record */ - const emit = {}; - /** @type Record */ - const positions = {}; - - for (let i = 1; i <= regexes.length; i++) { - positions[i + offset] = scopeNames[i]; - emit[i + offset] = true; - offset += countMatchGroups(regexes[i - 1]); - } - // we use _emit to keep track of which match groups are "top-level" to avoid double - // output from inside match groups - mode[key] = positions; - mode[key]._emit = emit; - mode[key]._multi = true; -} - -/** - * @param {CompiledMode} mode - */ -function beginMultiClass(mode) { - if (!Array.isArray(mode.begin)) return; - - if (mode.skip || mode.excludeBegin || mode.returnBegin) { - error("skip, excludeBegin, returnBegin not compatible with beginScope: {}"); - throw MultiClassError; - } - - if (typeof mode.beginScope !== "object" || mode.beginScope === null) { - error("beginScope must be object"); - throw MultiClassError; - } - - remapScopeNames(mode, mode.begin, {key: "beginScope"}); - mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" }); -} - -/** - * @param {CompiledMode} mode - */ -function endMultiClass(mode) { - if (!Array.isArray(mode.end)) return; - - if (mode.skip || mode.excludeEnd || mode.returnEnd) { - error("skip, excludeEnd, returnEnd not compatible with endScope: {}"); - throw MultiClassError; - } - - if (typeof mode.endScope !== "object" || mode.endScope === null) { - error("endScope must be object"); - throw MultiClassError; - } - - remapScopeNames(mode, mode.end, {key: "endScope"}); - mode.end = _rewriteBackreferences(mode.end, { joinWith: "" }); -} - -/** - * this exists only to allow `scope: {}` to be used beside `match:` - * Otherwise `beginScope` would necessary and that would look weird - - { - match: [ /def/, /\w+/ ] - scope: { 1: "keyword" , 2: "title" } - } - - * @param {CompiledMode} mode - */ -function scopeSugar(mode) { - if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) { - mode.beginScope = mode.scope; - delete mode.scope; - } -} - -/** - * @param {CompiledMode} mode - */ -function MultiClass(mode) { - scopeSugar(mode); - - if (typeof mode.beginScope === "string") { - mode.beginScope = { _wrap: mode.beginScope }; - } - if (typeof mode.endScope === "string") { - mode.endScope = { _wrap: mode.endScope }; - } - - beginMultiClass(mode); - endMultiClass(mode); -} - -/** -@typedef {import('highlight.js').Mode} Mode -@typedef {import('highlight.js').CompiledMode} CompiledMode -@typedef {import('highlight.js').Language} Language -@typedef {import('highlight.js').HLJSPlugin} HLJSPlugin -@typedef {import('highlight.js').CompiledLanguage} CompiledLanguage -*/ - -// compilation - -/** - * Compiles a language definition result - * - * Given the raw result of a language definition (Language), compiles this so - * that it is ready for highlighting code. - * @param {Language} language - * @returns {CompiledLanguage} - */ -function compileLanguage(language) { - /** - * Builds a regex with the case sensitivity of the current language - * - * @param {RegExp | string} value - * @param {boolean} [global] - */ - function langRe(value, global) { - return new RegExp( - source(value), - 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '') - ); - } - - /** - Stores multiple regular expressions and allows you to quickly search for - them all in a string simultaneously - returning the first match. It does - this by creating a huge (a|b|c) regex - each individual item wrapped with () - and joined by `|` - using match groups to track position. When a match is - found checking which position in the array has content allows us to figure - out which of the original regexes / match groups triggered the match. - - The match object itself (the result of `Regex.exec`) is returned but also - enhanced by merging in any meta-data that was registered with the regex. - This is how we keep track of which mode matched, and what type of rule - (`illegal`, `begin`, end, etc). - */ - class MultiRegex { - constructor() { - this.matchIndexes = {}; - // @ts-ignore - this.regexes = []; - this.matchAt = 1; - this.position = 0; - } - - // @ts-ignore - addRule(re, opts) { - opts.position = this.position++; - // @ts-ignore - this.matchIndexes[this.matchAt] = opts; - this.regexes.push([opts, re]); - this.matchAt += countMatchGroups(re) + 1; - } - - compile() { - if (this.regexes.length === 0) { - // avoids the need to check length every time exec is called - // @ts-ignore - this.exec = () => null; - } - const terminators = this.regexes.map(el => el[1]); - this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true); - this.lastIndex = 0; - } - - /** @param {string} s */ - exec(s) { - this.matcherRe.lastIndex = this.lastIndex; - const match = this.matcherRe.exec(s); - if (!match) { return null; } - - // eslint-disable-next-line no-undefined - const i = match.findIndex((el, i) => i > 0 && el !== undefined); - // @ts-ignore - const matchData = this.matchIndexes[i]; - // trim off any earlier non-relevant match groups (ie, the other regex - // match groups that make up the multi-matcher) - match.splice(0, i); - - return Object.assign(match, matchData); - } - } - - /* - Created to solve the key deficiently with MultiRegex - there is no way to - test for multiple matches at a single location. Why would we need to do - that? In the future a more dynamic engine will allow certain matches to be - ignored. An example: if we matched say the 3rd regex in a large group but - decided to ignore it - we'd need to started testing again at the 4th - regex... but MultiRegex itself gives us no real way to do that. - - So what this class creates MultiRegexs on the fly for whatever search - position they are needed. - - NOTE: These additional MultiRegex objects are created dynamically. For most - grammars most of the time we will never actually need anything more than the - first MultiRegex - so this shouldn't have too much overhead. - - Say this is our search group, and we match regex3, but wish to ignore it. - - regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0 - - What we need is a new MultiRegex that only includes the remaining - possibilities: - - regex4 | regex5 ' ie, startAt = 3 - - This class wraps all that complexity up in a simple API... `startAt` decides - where in the array of expressions to start doing the matching. It - auto-increments, so if a match is found at position 2, then startAt will be - set to 3. If the end is reached startAt will return to 0. - - MOST of the time the parser will be setting startAt manually to 0. - */ - class ResumableMultiRegex { - constructor() { - // @ts-ignore - this.rules = []; - // @ts-ignore - this.multiRegexes = []; - this.count = 0; - - this.lastIndex = 0; - this.regexIndex = 0; - } - - // @ts-ignore - getMatcher(index) { - if (this.multiRegexes[index]) return this.multiRegexes[index]; - - const matcher = new MultiRegex(); - this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts)); - matcher.compile(); - this.multiRegexes[index] = matcher; - return matcher; - } - - resumingScanAtSamePosition() { - return this.regexIndex !== 0; - } - - considerAll() { - this.regexIndex = 0; - } - - // @ts-ignore - addRule(re, opts) { - this.rules.push([re, opts]); - if (opts.type === "begin") this.count++; - } - - /** @param {string} s */ - exec(s) { - const m = this.getMatcher(this.regexIndex); - m.lastIndex = this.lastIndex; - let result = m.exec(s); - - // The following is because we have no easy way to say "resume scanning at the - // existing position but also skip the current rule ONLY". What happens is - // all prior rules are also skipped which can result in matching the wrong - // thing. Example of matching "booger": - - // our matcher is [string, "booger", number] - // - // ....booger.... - - // if "booger" is ignored then we'd really need a regex to scan from the - // SAME position for only: [string, number] but ignoring "booger" (if it - // was the first match), a simple resume would scan ahead who knows how - // far looking only for "number", ignoring potential string matches (or - // future "booger" matches that might be valid.) - - // So what we do: We execute two matchers, one resuming at the same - // position, but the second full matcher starting at the position after: - - // /--- resume first regex match here (for [number]) - // |/---- full match here for [string, "booger", number] - // vv - // ....booger.... - - // Which ever results in a match first is then used. So this 3-4 step - // process essentially allows us to say "match at this position, excluding - // a prior rule that was ignored". - // - // 1. Match "booger" first, ignore. Also proves that [string] does non match. - // 2. Resume matching for [number] - // 3. Match at index + 1 for [string, "booger", number] - // 4. If #2 and #3 result in matches, which came first? - if (this.resumingScanAtSamePosition()) { - if (result && result.index === this.lastIndex) ; else { // use the second matcher result - const m2 = this.getMatcher(0); - m2.lastIndex = this.lastIndex + 1; - result = m2.exec(s); - } - } - - if (result) { - this.regexIndex += result.position + 1; - if (this.regexIndex === this.count) { - // wrap-around to considering all matches again - this.considerAll(); - } - } - - return result; - } - } - - /** - * Given a mode, builds a huge ResumableMultiRegex that can be used to walk - * the content and find matches. - * - * @param {CompiledMode} mode - * @returns {ResumableMultiRegex} - */ - function buildModeRegex(mode) { - const mm = new ResumableMultiRegex(); - - mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: "begin" })); - - if (mode.terminatorEnd) { - mm.addRule(mode.terminatorEnd, { type: "end" }); - } - if (mode.illegal) { - mm.addRule(mode.illegal, { type: "illegal" }); - } - - return mm; - } - - /** skip vs abort vs ignore - * - * @skip - The mode is still entered and exited normally (and contains rules apply), - * but all content is held and added to the parent buffer rather than being - * output when the mode ends. Mostly used with `sublanguage` to build up - * a single large buffer than can be parsed by sublanguage. - * - * - The mode begin ands ends normally. - * - Content matched is added to the parent mode buffer. - * - The parser cursor is moved forward normally. - * - * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it - * never matched) but DOES NOT continue to match subsequent `contains` - * modes. Abort is bad/suboptimal because it can result in modes - * farther down not getting applied because an earlier rule eats the - * content but then aborts. - * - * - The mode does not begin. - * - Content matched by `begin` is added to the mode buffer. - * - The parser cursor is moved forward accordingly. - * - * @ignore - Ignores the mode (as if it never matched) and continues to match any - * subsequent `contains` modes. Ignore isn't technically possible with - * the current parser implementation. - * - * - The mode does not begin. - * - Content matched by `begin` is ignored. - * - The parser cursor is not moved forward. - */ - - /** - * Compiles an individual mode - * - * This can raise an error if the mode contains certain detectable known logic - * issues. - * @param {Mode} mode - * @param {CompiledMode | null} [parent] - * @returns {CompiledMode | never} - */ - function compileMode(mode, parent) { - const cmode = /** @type CompiledMode */ (mode); - if (mode.isCompiled) return cmode; - - [ - scopeClassName, - // do this early so compiler extensions generally don't have to worry about - // the distinction between match/begin - compileMatch, - MultiClass, - beforeMatchExt - ].forEach(ext => ext(mode, parent)); - - language.compilerExtensions.forEach(ext => ext(mode, parent)); - - // __beforeBegin is considered private API, internal use only - mode.__beforeBegin = null; - - [ - beginKeywords, - // do this later so compiler extensions that come earlier have access to the - // raw array if they wanted to perhaps manipulate it, etc. - compileIllegal, - // default to 1 relevance if not specified - compileRelevance - ].forEach(ext => ext(mode, parent)); - - mode.isCompiled = true; - - let keywordPattern = null; - if (typeof mode.keywords === "object" && mode.keywords.$pattern) { - // we need a copy because keywords might be compiled multiple times - // so we can't go deleting $pattern from the original on the first - // pass - mode.keywords = Object.assign({}, mode.keywords); - keywordPattern = mode.keywords.$pattern; - delete mode.keywords.$pattern; - } - keywordPattern = keywordPattern || /\w+/; - - if (mode.keywords) { - mode.keywords = compileKeywords(mode.keywords, language.case_insensitive); - } - - cmode.keywordPatternRe = langRe(keywordPattern, true); - - if (parent) { - if (!mode.begin) mode.begin = /\B|\b/; - cmode.beginRe = langRe(mode.begin); - if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/; - if (mode.end) cmode.endRe = langRe(mode.end); - cmode.terminatorEnd = source(mode.end) || ''; - if (mode.endsWithParent && parent.terminatorEnd) { - cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd; - } - } - if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal)); - if (!mode.contains) mode.contains = []; - - mode.contains = [].concat(...mode.contains.map(function(c) { - return expandOrCloneMode(c === 'self' ? mode : c); - })); - mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); }); - - if (mode.starts) { - compileMode(mode.starts, parent); - } - - cmode.matcher = buildModeRegex(cmode); - return cmode; - } - - if (!language.compilerExtensions) language.compilerExtensions = []; - - // self is not valid at the top-level - if (language.contains && language.contains.includes('self')) { - throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation."); - } - - // we need a null object, which inherit will guarantee - language.classNameAliases = inherit$1(language.classNameAliases || {}); - - return compileMode(/** @type Mode */ (language)); -} - -/** - * Determines if a mode has a dependency on it's parent or not - * - * If a mode does have a parent dependency then often we need to clone it if - * it's used in multiple places so that each copy points to the correct parent, - * where-as modes without a parent can often safely be re-used at the bottom of - * a mode chain. - * - * @param {Mode | null} mode - * @returns {boolean} - is there a dependency on the parent? - * */ -function dependencyOnParent(mode) { - if (!mode) return false; - - return mode.endsWithParent || dependencyOnParent(mode.starts); -} - -/** - * Expands a mode or clones it if necessary - * - * This is necessary for modes with parental dependenceis (see notes on - * `dependencyOnParent`) and for nodes that have `variants` - which must then be - * exploded into their own individual modes at compile time. - * - * @param {Mode} mode - * @returns {Mode | Mode[]} - * */ -function expandOrCloneMode(mode) { - if (mode.variants && !mode.cachedVariants) { - mode.cachedVariants = mode.variants.map(function(variant) { - return inherit$1(mode, { variants: null }, variant); - }); - } - - // EXPAND - // if we have variants then essentially "replace" the mode with the variants - // this happens in compileMode, where this function is called from - if (mode.cachedVariants) { - return mode.cachedVariants; - } - - // CLONE - // if we have dependencies on parents then we need a unique - // instance of ourselves, so we can be reused with many - // different parents without issue - if (dependencyOnParent(mode)) { - return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null }); - } - - if (Object.isFrozen(mode)) { - return inherit$1(mode); - } - - // no special dependency issues, just return ourselves - return mode; -} - -var version = "11.2.0"; - -/* -Syntax highlighting with language autodetection. -https://highlightjs.org/ -*/ - -/** -@typedef {import('highlight.js').Mode} Mode -@typedef {import('highlight.js').CompiledMode} CompiledMode -@typedef {import('highlight.js').Language} Language -@typedef {import('highlight.js').HLJSApi} HLJSApi -@typedef {import('highlight.js').HLJSPlugin} HLJSPlugin -@typedef {import('highlight.js').PluginEvent} PluginEvent -@typedef {import('highlight.js').HLJSOptions} HLJSOptions -@typedef {import('highlight.js').LanguageFn} LanguageFn -@typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement -@typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext -@typedef {import('highlight.js/private').MatchType} MatchType -@typedef {import('highlight.js/private').KeywordData} KeywordData -@typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch -@typedef {import('highlight.js/private').AnnotatedError} AnnotatedError -@typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult -@typedef {import('highlight.js').HighlightOptions} HighlightOptions -@typedef {import('highlight.js').HighlightResult} HighlightResult -*/ - - -const escape = escapeHTML; -const inherit = inherit$1; -const NO_MATCH = Symbol("nomatch"); -const MAX_KEYWORD_HITS = 7; - -/** - * @param {any} hljs - object that is extended (legacy) - * @returns {HLJSApi} - */ -const HLJS = function(hljs) { - // Global internal variables used within the highlight.js library. - /** @type {Record} */ - const languages = Object.create(null); - /** @type {Record} */ - const aliases = Object.create(null); - /** @type {HLJSPlugin[]} */ - const plugins = []; - - // safe/production mode - swallows more errors, tries to keep running - // even if a single syntax or parse hits a fatal error - let SAFE_MODE = true; - const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?"; - /** @type {Language} */ - const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] }; - - // Global options used when within external APIs. This is modified when - // calling the `hljs.configure` function. - /** @type HLJSOptions */ - let options = { - ignoreUnescapedHTML: false, - noHighlightRe: /^(no-?highlight)$/i, - languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i, - classPrefix: 'hljs-', - cssSelector: 'pre code', - languages: null, - // beta configuration options, subject to change, welcome to discuss - // https://github.com/highlightjs/highlight.js/issues/1086 - __emitter: TokenTreeEmitter - }; - - /* Utility functions */ - - /** - * Tests a language name to see if highlighting should be skipped - * @param {string} languageName - */ - function shouldNotHighlight(languageName) { - return options.noHighlightRe.test(languageName); - } - - /** - * @param {HighlightedHTMLElement} block - the HTML element to determine language for - */ - function blockLanguage(block) { - let classes = block.className + ' '; - - classes += block.parentNode ? block.parentNode.className : ''; - - // language-* takes precedence over non-prefixed class names. - const match = options.languageDetectRe.exec(classes); - if (match) { - const language = getLanguage(match[1]); - if (!language) { - warn(LANGUAGE_NOT_FOUND.replace("{}", match[1])); - warn("Falling back to no-highlight mode for this block.", block); - } - return language ? match[1] : 'no-highlight'; - } - - return classes - .split(/\s+/) - .find((_class) => shouldNotHighlight(_class) || getLanguage(_class)); - } - - /** - * Core highlighting function. - * - * OLD API - * highlight(lang, code, ignoreIllegals, continuation) - * - * NEW API - * highlight(code, {lang, ignoreIllegals}) - * - * @param {string} codeOrLanguageName - the language to use for highlighting - * @param {string | HighlightOptions} optionsOrCode - the code to highlight - * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail - * - * @returns {HighlightResult} Result - an object that represents the result - * @property {string} language - the language name - * @property {number} relevance - the relevance score - * @property {string} value - the highlighted HTML code - * @property {string} code - the original raw code - * @property {CompiledMode} top - top of the current mode stack - * @property {boolean} illegal - indicates whether any illegal matches were found - */ - function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) { - let code = ""; - let languageName = ""; - if (typeof optionsOrCode === "object") { - code = codeOrLanguageName; - ignoreIllegals = optionsOrCode.ignoreIllegals; - languageName = optionsOrCode.language; - } else { - // old API - deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated."); - deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"); - languageName = codeOrLanguageName; - code = optionsOrCode; - } - - // https://github.com/highlightjs/highlight.js/issues/3149 - // eslint-disable-next-line no-undefined - if (ignoreIllegals === undefined) { ignoreIllegals = true; } - - /** @type {BeforeHighlightContext} */ - const context = { - code, - language: languageName - }; - // the plugin can change the desired language or the code to be highlighted - // just be changing the object it was passed - fire("before:highlight", context); - - // a before plugin can usurp the result completely by providing it's own - // in which case we don't even need to call highlight - const result = context.result - ? context.result - : _highlight(context.language, context.code, ignoreIllegals); - - result.code = context.code; - // the plugin can change anything in result to suite it - fire("after:highlight", result); - - return result; - } - - /** - * private highlight that's used internally and does not fire callbacks - * - * @param {string} languageName - the language to use for highlighting - * @param {string} codeToHighlight - the code to highlight - * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail - * @param {CompiledMode?} [continuation] - current continuation mode, if any - * @returns {HighlightResult} - result of the highlight operation - */ - function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) { - const keywordHits = Object.create(null); - - /** - * Return keyword data if a match is a keyword - * @param {CompiledMode} mode - current mode - * @param {string} matchText - the textual match - * @returns {KeywordData | false} - */ - function keywordData(mode, matchText) { - return mode.keywords[matchText]; - } - - function processKeywords() { - if (!top.keywords) { - emitter.addText(modeBuffer); - return; - } - - let lastIndex = 0; - top.keywordPatternRe.lastIndex = 0; - let match = top.keywordPatternRe.exec(modeBuffer); - let buf = ""; - - while (match) { - buf += modeBuffer.substring(lastIndex, match.index); - const word = language.case_insensitive ? match[0].toLowerCase() : match[0]; - const data = keywordData(top, word); - if (data) { - const [kind, keywordRelevance] = data; - emitter.addText(buf); - buf = ""; - - keywordHits[word] = (keywordHits[word] || 0) + 1; - if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance; - if (kind.startsWith("_")) { - // _ implied for relevance only, do not highlight - // by applying a class name - buf += match[0]; - } else { - const cssClass = language.classNameAliases[kind] || kind; - emitter.addKeyword(match[0], cssClass); - } - } else { - buf += match[0]; - } - lastIndex = top.keywordPatternRe.lastIndex; - match = top.keywordPatternRe.exec(modeBuffer); - } - buf += modeBuffer.substr(lastIndex); - emitter.addText(buf); - } - - function processSubLanguage() { - if (modeBuffer === "") return; - /** @type HighlightResult */ - let result = null; - - if (typeof top.subLanguage === 'string') { - if (!languages[top.subLanguage]) { - emitter.addText(modeBuffer); - return; - } - result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]); - continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top); - } else { - result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null); - } - - // Counting embedded language score towards the host language may be disabled - // with zeroing the containing mode relevance. Use case in point is Markdown that - // allows XML everywhere and makes every XML snippet to have a much larger Markdown - // score. - if (top.relevance > 0) { - relevance += result.relevance; - } - emitter.addSublanguage(result._emitter, result.language); - } - - function processBuffer() { - if (top.subLanguage != null) { - processSubLanguage(); - } else { - processKeywords(); - } - modeBuffer = ''; - } - - /** - * @param {CompiledMode} mode - * @param {RegExpMatchArray} match - */ - function emitMultiClass(scope, match) { - let i = 1; - // eslint-disable-next-line no-undefined - while (match[i] !== undefined) { - if (!scope._emit[i]) { i++; continue; } - const klass = language.classNameAliases[scope[i]] || scope[i]; - const text = match[i]; - if (klass) { - emitter.addKeyword(text, klass); - } else { - modeBuffer = text; - processKeywords(); - modeBuffer = ""; - } - i++; - } - } - - /** - * @param {CompiledMode} mode - new mode to start - * @param {RegExpMatchArray} match - */ - function startNewMode(mode, match) { - if (mode.scope && typeof mode.scope === "string") { - emitter.openNode(language.classNameAliases[mode.scope] || mode.scope); - } - if (mode.beginScope) { - // beginScope just wraps the begin match itself in a scope - if (mode.beginScope._wrap) { - emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap); - modeBuffer = ""; - } else if (mode.beginScope._multi) { - // at this point modeBuffer should just be the match - emitMultiClass(mode.beginScope, match); - modeBuffer = ""; - } - } - - top = Object.create(mode, { parent: { value: top } }); - return top; - } - - /** - * @param {CompiledMode } mode - the mode to potentially end - * @param {RegExpMatchArray} match - the latest match - * @param {string} matchPlusRemainder - match plus remainder of content - * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode - */ - function endOfMode(mode, match, matchPlusRemainder) { - let matched = startsWith(mode.endRe, matchPlusRemainder); - - if (matched) { - if (mode["on:end"]) { - const resp = new Response(mode); - mode["on:end"](match, resp); - if (resp.isMatchIgnored) matched = false; - } - - if (matched) { - while (mode.endsParent && mode.parent) { - mode = mode.parent; - } - return mode; - } - } - // even if on:end fires an `ignore` it's still possible - // that we might trigger the end node because of a parent mode - if (mode.endsWithParent) { - return endOfMode(mode.parent, match, matchPlusRemainder); - } - } - - /** - * Handle matching but then ignoring a sequence of text - * - * @param {string} lexeme - string containing full match text - */ - function doIgnore(lexeme) { - if (top.matcher.regexIndex === 0) { - // no more regexes to potentially match here, so we move the cursor forward one - // space - modeBuffer += lexeme[0]; - return 1; - } else { - // no need to move the cursor, we still have additional regexes to try and - // match at this very spot - resumeScanAtSamePosition = true; - return 0; - } - } - - /** - * Handle the start of a new potential mode match - * - * @param {EnhancedMatch} match - the current match - * @returns {number} how far to advance the parse cursor - */ - function doBeginMatch(match) { - const lexeme = match[0]; - const newMode = match.rule; - - const resp = new Response(newMode); - // first internal before callbacks, then the public ones - const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]]; - for (const cb of beforeCallbacks) { - if (!cb) continue; - cb(match, resp); - if (resp.isMatchIgnored) return doIgnore(lexeme); - } - - if (newMode.skip) { - modeBuffer += lexeme; - } else { - if (newMode.excludeBegin) { - modeBuffer += lexeme; - } - processBuffer(); - if (!newMode.returnBegin && !newMode.excludeBegin) { - modeBuffer = lexeme; - } - } - startNewMode(newMode, match); - return newMode.returnBegin ? 0 : lexeme.length; - } - - /** - * Handle the potential end of mode - * - * @param {RegExpMatchArray} match - the current match - */ - function doEndMatch(match) { - const lexeme = match[0]; - const matchPlusRemainder = codeToHighlight.substr(match.index); - - const endMode = endOfMode(top, match, matchPlusRemainder); - if (!endMode) { return NO_MATCH; } - - const origin = top; - if (top.endScope && top.endScope._wrap) { - processBuffer(); - emitter.addKeyword(lexeme, top.endScope._wrap); - } else if (top.endScope && top.endScope._multi) { - processBuffer(); - emitMultiClass(top.endScope, match); - } else if (origin.skip) { - modeBuffer += lexeme; - } else { - if (!(origin.returnEnd || origin.excludeEnd)) { - modeBuffer += lexeme; - } - processBuffer(); - if (origin.excludeEnd) { - modeBuffer = lexeme; - } - } - do { - if (top.scope) { - emitter.closeNode(); - } - if (!top.skip && !top.subLanguage) { - relevance += top.relevance; - } - top = top.parent; - } while (top !== endMode.parent); - if (endMode.starts) { - startNewMode(endMode.starts, match); - } - return origin.returnEnd ? 0 : lexeme.length; - } - - function processContinuations() { - const list = []; - for (let current = top; current !== language; current = current.parent) { - if (current.scope) { - list.unshift(current.scope); - } - } - list.forEach(item => emitter.openNode(item)); - } - - /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */ - let lastMatch = {}; - - /** - * Process an individual match - * - * @param {string} textBeforeMatch - text preceding the match (since the last match) - * @param {EnhancedMatch} [match] - the match itself - */ - function processLexeme(textBeforeMatch, match) { - const lexeme = match && match[0]; - - // add non-matched text to the current mode buffer - modeBuffer += textBeforeMatch; - - if (lexeme == null) { - processBuffer(); - return 0; - } - - // we've found a 0 width match and we're stuck, so we need to advance - // this happens when we have badly behaved rules that have optional matchers to the degree that - // sometimes they can end up matching nothing at all - // Ref: https://github.com/highlightjs/highlight.js/issues/2140 - if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") { - // spit the "skipped" character that our regex choked on back into the output sequence - modeBuffer += codeToHighlight.slice(match.index, match.index + 1); - if (!SAFE_MODE) { - /** @type {AnnotatedError} */ - const err = new Error(`0 width match regex (${languageName})`); - err.languageName = languageName; - err.badRule = lastMatch.rule; - throw err; - } - return 1; - } - lastMatch = match; - - if (match.type === "begin") { - return doBeginMatch(match); - } else if (match.type === "illegal" && !ignoreIllegals) { - // illegal match, we do not continue processing - /** @type {AnnotatedError} */ - const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || '') + '"'); - err.mode = top; - throw err; - } else if (match.type === "end") { - const processed = doEndMatch(match); - if (processed !== NO_MATCH) { - return processed; - } - } - - // edge case for when illegal matches $ (end of line) which is technically - // a 0 width match but not a begin/end match so it's not caught by the - // first handler (when ignoreIllegals is true) - if (match.type === "illegal" && lexeme === "") { - // advance so we aren't stuck in an infinite loop - return 1; - } - - // infinite loops are BAD, this is a last ditch catch all. if we have a - // decent number of iterations yet our index (cursor position in our - // parsing) still 3x behind our index then something is very wrong - // so we bail - if (iterations > 100000 && iterations > match.index * 3) { - const err = new Error('potential infinite loop, way more iterations than matches'); - throw err; - } - - /* - Why might be find ourselves here? An potential end match that was - triggered but could not be completed. IE, `doEndMatch` returned NO_MATCH. - (this could be because a callback requests the match be ignored, etc) - - This causes no real harm other than stopping a few times too many. - */ - - modeBuffer += lexeme; - return lexeme.length; - } - - const language = getLanguage(languageName); - if (!language) { - error(LANGUAGE_NOT_FOUND.replace("{}", languageName)); - throw new Error('Unknown language: "' + languageName + '"'); - } - - const md = compileLanguage(language); - let result = ''; - /** @type {CompiledMode} */ - let top = continuation || md; - /** @type Record */ - const continuations = {}; // keep continuations for sub-languages - const emitter = new options.__emitter(options); - processContinuations(); - let modeBuffer = ''; - let relevance = 0; - let index = 0; - let iterations = 0; - let resumeScanAtSamePosition = false; - - try { - top.matcher.considerAll(); - - for (;;) { - iterations++; - if (resumeScanAtSamePosition) { - // only regexes not matched previously will now be - // considered for a potential match - resumeScanAtSamePosition = false; - } else { - top.matcher.considerAll(); - } - top.matcher.lastIndex = index; - - const match = top.matcher.exec(codeToHighlight); - // console.log("match", match[0], match.rule && match.rule.begin) - - if (!match) break; - - const beforeMatch = codeToHighlight.substring(index, match.index); - const processedCount = processLexeme(beforeMatch, match); - index = match.index + processedCount; - } - processLexeme(codeToHighlight.substr(index)); - emitter.closeAllNodes(); - emitter.finalize(); - result = emitter.toHTML(); - - return { - language: languageName, - value: result, - relevance: relevance, - illegal: false, - _emitter: emitter, - _top: top - }; - } catch (err) { - if (err.message && err.message.includes('Illegal')) { - return { - language: languageName, - value: escape(codeToHighlight), - illegal: true, - relevance: 0, - _illegalBy: { - message: err.message, - index: index, - context: codeToHighlight.slice(index - 100, index + 100), - mode: err.mode, - resultSoFar: result - }, - _emitter: emitter - }; - } else if (SAFE_MODE) { - return { - language: languageName, - value: escape(codeToHighlight), - illegal: false, - relevance: 0, - errorRaised: err, - _emitter: emitter, - _top: top - }; - } else { - throw err; - } - } - } - - /** - * returns a valid highlight result, without actually doing any actual work, - * auto highlight starts with this and it's possible for small snippets that - * auto-detection may not find a better match - * @param {string} code - * @returns {HighlightResult} - */ - function justTextHighlightResult(code) { - const result = { - value: escape(code), - illegal: false, - relevance: 0, - _top: PLAINTEXT_LANGUAGE, - _emitter: new options.__emitter(options) - }; - result._emitter.addText(code); - return result; - } - - /** - Highlighting with language detection. Accepts a string with the code to - highlight. Returns an object with the following properties: - - - language (detected language) - - relevance (int) - - value (an HTML string with highlighting markup) - - secondBest (object with the same structure for second-best heuristically - detected language, may be absent) - - @param {string} code - @param {Array} [languageSubset] - @returns {AutoHighlightResult} - */ - function highlightAuto(code, languageSubset) { - languageSubset = languageSubset || options.languages || Object.keys(languages); - const plaintext = justTextHighlightResult(code); - - const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name => - _highlight(name, code, false) - ); - results.unshift(plaintext); // plaintext is always an option - - const sorted = results.sort((a, b) => { - // sort base on relevance - if (a.relevance !== b.relevance) return b.relevance - a.relevance; - - // always award the tie to the base language - // ie if C++ and Arduino are tied, it's more likely to be C++ - if (a.language && b.language) { - if (getLanguage(a.language).supersetOf === b.language) { - return 1; - } else if (getLanguage(b.language).supersetOf === a.language) { - return -1; - } - } - - // otherwise say they are equal, which has the effect of sorting on - // relevance while preserving the original ordering - which is how ties - // have historically been settled, ie the language that comes first always - // wins in the case of a tie - return 0; - }); - - const [best, secondBest] = sorted; - - /** @type {AutoHighlightResult} */ - const result = best; - result.secondBest = secondBest; - - return result; - } - - /** - * Builds new class name for block given the language name - * - * @param {HTMLElement} element - * @param {string} [currentLang] - * @param {string} [resultLang] - */ - function updateClassName(element, currentLang, resultLang) { - const language = (currentLang && aliases[currentLang]) || resultLang; - - element.classList.add("hljs"); - element.classList.add(`language-${language}`); - } - - /** - * Applies highlighting to a DOM node containing code. - * - * @param {HighlightedHTMLElement} element - the HTML element to highlight - */ - function highlightElement(element) { - /** @type HTMLElement */ - let node = null; - const language = blockLanguage(element); - - if (shouldNotHighlight(language)) return; - - fire("before:highlightElement", - { el: element, language: language }); - - // we should be all text, no child nodes - if (!options.ignoreUnescapedHTML && element.children.length > 0) { - console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."); - console.warn("https://github.com/highlightjs/highlight.js/issues/2886"); - console.warn(element); - } - - node = element; - const text = node.textContent; - const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text); - - element.innerHTML = result.value; - updateClassName(element, language, result.language); - element.result = { - language: result.language, - // TODO: remove with version 11.0 - re: result.relevance, - relevance: result.relevance - }; - if (result.secondBest) { - element.secondBest = { - language: result.secondBest.language, - relevance: result.secondBest.relevance - }; - } - - fire("after:highlightElement", { el: element, result, text }); - } - - /** - * Updates highlight.js global options with the passed options - * - * @param {Partial} userOptions - */ - function configure(userOptions) { - options = inherit(options, userOptions); - } - - // TODO: remove v12, deprecated - const initHighlighting = () => { - highlightAll(); - deprecated("10.6.0", "initHighlighting() deprecated. Use highlightAll() now."); - }; - - // TODO: remove v12, deprecated - function initHighlightingOnLoad() { - highlightAll(); - deprecated("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now."); - } - - let wantsHighlight = false; - - /** - * auto-highlights all pre>code elements on the page - */ - function highlightAll() { - // if we are called too early in the loading process - if (document.readyState === "loading") { - wantsHighlight = true; - return; - } - - const blocks = document.querySelectorAll(options.cssSelector); - blocks.forEach(highlightElement); - } - - function boot() { - // if a highlight was requested before DOM was loaded, do now - if (wantsHighlight) highlightAll(); - } - - // make sure we are in the browser environment - if (typeof window !== 'undefined' && window.addEventListener) { - window.addEventListener('DOMContentLoaded', boot, false); - } - - /** - * Register a language grammar module - * - * @param {string} languageName - * @param {LanguageFn} languageDefinition - */ - function registerLanguage(languageName, languageDefinition) { - let lang = null; - try { - lang = languageDefinition(hljs); - } catch (error$1) { - error("Language definition for '{}' could not be registered.".replace("{}", languageName)); - // hard or soft error - if (!SAFE_MODE) { throw error$1; } else { error(error$1); } - // languages that have serious errors are replaced with essentially a - // "plaintext" stand-in so that the code blocks will still get normal - // css classes applied to them - and one bad language won't break the - // entire highlighter - lang = PLAINTEXT_LANGUAGE; - } - // give it a temporary name if it doesn't have one in the meta-data - if (!lang.name) lang.name = languageName; - languages[languageName] = lang; - lang.rawDefinition = languageDefinition.bind(null, hljs); - - if (lang.aliases) { - registerAliases(lang.aliases, { languageName }); - } - } - - /** - * Remove a language grammar module - * - * @param {string} languageName - */ - function unregisterLanguage(languageName) { - delete languages[languageName]; - for (const alias of Object.keys(aliases)) { - if (aliases[alias] === languageName) { - delete aliases[alias]; - } - } - } - - /** - * @returns {string[]} List of language internal names - */ - function listLanguages() { - return Object.keys(languages); - } - - /** - * @param {string} name - name of the language to retrieve - * @returns {Language | undefined} - */ - function getLanguage(name) { - name = (name || '').toLowerCase(); - return languages[name] || languages[aliases[name]]; - } - - /** - * - * @param {string|string[]} aliasList - single alias or list of aliases - * @param {{languageName: string}} opts - */ - function registerAliases(aliasList, { languageName }) { - if (typeof aliasList === 'string') { - aliasList = [aliasList]; - } - aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; }); - } - - /** - * Determines if a given language has auto-detection enabled - * @param {string} name - name of the language - */ - function autoDetection(name) { - const lang = getLanguage(name); - return lang && !lang.disableAutodetect; - } - - /** - * Upgrades the old highlightBlock plugins to the new - * highlightElement API - * @param {HLJSPlugin} plugin - */ - function upgradePluginAPI(plugin) { - // TODO: remove with v12 - if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) { - plugin["before:highlightElement"] = (data) => { - plugin["before:highlightBlock"]( - Object.assign({ block: data.el }, data) - ); - }; - } - if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) { - plugin["after:highlightElement"] = (data) => { - plugin["after:highlightBlock"]( - Object.assign({ block: data.el }, data) - ); - }; - } - } - - /** - * @param {HLJSPlugin} plugin - */ - function addPlugin(plugin) { - upgradePluginAPI(plugin); - plugins.push(plugin); - } - - /** - * - * @param {PluginEvent} event - * @param {any} args - */ - function fire(event, args) { - const cb = event; - plugins.forEach(function(plugin) { - if (plugin[cb]) { - plugin[cb](args); - } - }); - } - - /** - * DEPRECATED - * @param {HighlightedHTMLElement} el - */ - function deprecateHighlightBlock(el) { - deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0"); - deprecated("10.7.0", "Please use highlightElement now."); - - return highlightElement(el); - } - - /* Interface definition */ - Object.assign(hljs, { - highlight, - highlightAuto, - highlightAll, - highlightElement, - // TODO: Remove with v12 API - highlightBlock: deprecateHighlightBlock, - configure, - initHighlighting, - initHighlightingOnLoad, - registerLanguage, - unregisterLanguage, - listLanguages, - getLanguage, - registerAliases, - autoDetection, - inherit, - addPlugin - }); - - hljs.debugMode = function() { SAFE_MODE = false; }; - hljs.safeMode = function() { SAFE_MODE = true; }; - hljs.versionString = version; - - for (const key in MODES) { - // @ts-ignore - if (typeof MODES[key] === "object") { - // @ts-ignore - deepFreeze$1(MODES[key]); - } - } - - // merge all the modes/regexes into our main object - Object.assign(hljs, MODES); - - return hljs; -}; - -// export an "instance" of the highlighter -var highlight = HLJS({}); - -export default highlight; diff --git a/static/lib/highlightjs/cdn-release@11.2.0/build/es/core.min.js b/static/lib/highlightjs/cdn-release@11.2.0/build/es/core.min.js deleted file mode 100644 index a4f096ab..00000000 --- a/static/lib/highlightjs/cdn-release@11.2.0/build/es/core.min.js +++ /dev/null @@ -1,297 +0,0 @@ -/*! - Highlight.js v11.2.0 (git: 2a5c592e5e) - (c) 2006-2021 Ivan Sagalaev and other contributors - License: BSD-3-Clause - */ -var e={exports:{}};function t(e){ -return e instanceof Map?e.clear=e.delete=e.set=()=>{ -throw Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=()=>{ -throw Error("set is read-only") -}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((n=>{var i=e[n] -;"object"!=typeof i||Object.isFrozen(i)||t(i)})),e} -e.exports=t,e.exports.default=t;var n=e.exports;class i{constructor(e){ -void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} -ignoreMatch(){this.isMatchIgnored=!0}}function r(e){ -return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") -}function s(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t] -;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n}const o=e=>!!e.kind -;class a{constructor(e,t){ -this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){ -this.buffer+=r(e)}openNode(e){if(!o(e))return;let t=e.kind -;t=e.sublanguage?"language-"+t:((e,{prefix:t})=>{if(e.includes(".")){ -const n=e.split(".") -;return[`${t}${n.shift()}`,...n.map(((e,t)=>`${e}${"_".repeat(t+1)}`))].join(" ") -}return`${t}${e}`})(t,{prefix:this.classPrefix}),this.span(t)}closeNode(e){ -o(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ -this.buffer+=``}}class l{constructor(){this.rootNode={ -children:[]},this.stack=[this.rootNode]}get top(){ -return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ -this.top.children.push(e)}openNode(e){const t={kind:e,children:[]} -;this.add(t),this.stack.push(t)}closeNode(){ -if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ -for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} -walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){ -return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t), -t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){ -"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ -l._collapse(e)})))}}class c extends l{constructor(e){super(),this.options=e} -addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())} -addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root -;n.kind=t,n.sublanguage=!0,this.add(n)}toHTML(){ -return new a(this,this.options).value()}finalize(){return!0}}function g(e){ -return e?"string"==typeof e?e:e.source:null}function d(...e){ -return e.map((e=>g(e))).join("")}function u(...e){return"("+((e=>{ -const t=e[e.length-1] -;return"object"==typeof t&&t.constructor===Object?(e.splice(e.length-1,1),t):{} -})(e).capture?"":"?:")+e.map((e=>g(e))).join("|")+")"}function h(e){ -return RegExp(e.toString()+"|").exec("").length-1} -const f=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ -;function p(e,{joinWith:t}){let n=0;return e.map((e=>{n+=1;const t=n -;let i=g(e),r="";for(;i.length>0;){const e=f.exec(i);if(!e){r+=i;break} -r+=i.substring(0,e.index), -i=i.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?r+="\\"+(Number(e[1])+t):(r+=e[0], -"("===e[0]&&n++)}return r})).map((e=>`(${e})`)).join(t)} -const b="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",m={ -begin:"\\\\[\\s\\S]",relevance:0},E={scope:"string",begin:"'",end:"'", -illegal:"\\n",contains:[m]},x={scope:"string",begin:'"',end:'"',illegal:"\\n", -contains:[m]},w=(e,t,n={})=>{const i=s({scope:"comment",begin:e,end:t, -contains:[]},n);i.contains.push({scope:"doctag", -begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", -end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) -;const r=u("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) -;return i.contains.push({begin:d(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i -},y=w("//","$"),_=w("/\\*","\\*/"),v=w("#","$");var O=Object.freeze({ -__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:"[a-zA-Z]\\w*", -UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:b, -BINARY_NUMBER_RE:"\\b(0b[01]+)", -RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", -SHEBANG:(e={})=>{const t=/^#![ ]*\// -;return e.binary&&(e.begin=d(t,/.*\b/,e.binary,/\b.*/)),s({scope:"meta",begin:t, -end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)}, -BACKSLASH_ESCAPE:m,APOS_STRING_MODE:E,QUOTE_STRING_MODE:x,PHRASAL_WORDS_MODE:{ -begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ -},COMMENT:w,C_LINE_COMMENT_MODE:y,C_BLOCK_COMMENT_MODE:_,HASH_COMMENT_MODE:v, -NUMBER_MODE:{scope:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0}, -C_NUMBER_MODE:{scope:"number",begin:b,relevance:0},BINARY_NUMBER_MODE:{ -scope:"number",begin:"\\b(0b[01]+)",relevance:0},REGEXP_MODE:{ -begin:/(?=\/[^/\n]*\/)/,contains:[{scope:"regexp",begin:/\//,end:/\/[gimuy]*/, -illegal:/\n/,contains:[m,{begin:/\[/,end:/\]/,relevance:0,contains:[m]}]}]}, -TITLE_MODE:{scope:"title",begin:"[a-zA-Z]\\w*",relevance:0}, -UNDERSCORE_TITLE_MODE:{scope:"title",begin:"[a-zA-Z_]\\w*",relevance:0}, -METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0}, -END_SAME_AS_BEGIN:e=>Object.assign(e,{"on:begin":(e,t)=>{t.data._beginMatch=e[1] -},"on:end":(e,t)=>{t.data._beginMatch!==e[1]&&t.ignoreMatch()}})}) -;function k(e,t){"."===e.input[e.index-1]&&t.ignoreMatch()}function N(e,t){ -void 0!==e.className&&(e.scope=e.className,delete e.className)}function S(e,t){ -t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", -e.__beforeBegin=k,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, -void 0===e.relevance&&(e.relevance=0))}function R(e,t){ -Array.isArray(e.illegal)&&(e.illegal=u(...e.illegal))}function A(e,t){ -if(e.match){ -if(e.begin||e.end)throw Error("begin & end are not supported with match") -;e.begin=e.match,delete e.match}}function M(e,t){ -void 0===e.relevance&&(e.relevance=1)}const j=(e,t)=>{if(!e.beforeMatch)return -;if(e.starts)throw Error("beforeMatch cannot be used with starts") -;const n=Object.assign({},e);Object.keys(e).forEach((t=>{delete e[t] -})),e.keywords=n.keywords, -e.begin=d(n.beforeMatch,d("(?=",n.begin,")")),e.starts={relevance:0, -contains:[Object.assign(n,{endsParent:!0})]},e.relevance=0,delete n.beforeMatch -},I=["of","and","for","in","not","or","if","then","parent","list","value"] -;function B(e,t,n="keyword"){const i=Object.create(null) -;return"string"==typeof e?r(n,e.split(" ")):Array.isArray(e)?r(n,e):Object.keys(e).forEach((n=>{ -Object.assign(i,B(e[n],t,n))})),i;function r(e,n){ -t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split("|") -;i[n[0]]=[e,T(n[0],n[1])]}))}}function T(e,t){ -return t?Number(t):(e=>I.includes(e.toLowerCase()))(e)?0:1}const L={},D=e=>{ -console.error(e)},P=(e,...t)=>{console.log("WARN: "+e,...t)},C=(e,t)=>{ -L[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),L[`${e}/${t}`]=!0) -},H=Error();function $(e,t,{key:n}){let i=0;const r=e[n],s={},o={} -;for(let e=1;e<=t.length;e++)o[e+i]=r[e],s[e+i]=!0,i+=h(t[e-1]) -;e[n]=o,e[n]._emit=s,e[n]._multi=!0}function U(e){(e=>{ -e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, -delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ -_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope -}),(e=>{if(Array.isArray(e.begin)){ -if(e.skip||e.excludeBegin||e.returnBegin)throw D("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), -H -;if("object"!=typeof e.beginScope||null===e.beginScope)throw D("beginScope must be object"), -H;$(e,e.begin,{key:"beginScope"}),e.begin=p(e.begin,{joinWith:""})}})(e),(e=>{ -if(Array.isArray(e.end)){ -if(e.skip||e.excludeEnd||e.returnEnd)throw D("skip, excludeEnd, returnEnd not compatible with endScope: {}"), -H -;if("object"!=typeof e.endScope||null===e.endScope)throw D("endScope must be object"), -H;$(e,e.end,{key:"endScope"}),e.end=p(e.end,{joinWith:""})}})(e)}function z(e){ -function t(t,n){return RegExp(g(t),"m"+(e.case_insensitive?"i":"")+(n?"g":""))} -class n{constructor(){ -this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} -addRule(e,t){ -t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]), -this.matchAt+=h(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) -;const e=this.regexes.map((e=>e[1]));this.matcherRe=t(p(e,{joinWith:"|" -}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex -;const t=this.matcherRe.exec(e);if(!t)return null -;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n] -;return t.splice(0,n),Object.assign(t,i)}}class i{constructor(){ -this.rules=[],this.multiRegexes=[], -this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ -if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n -;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))), -t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){ -return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){ -this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){ -const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex -;let n=t.exec(e) -;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{ -const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)} -return n&&(this.regexIndex+=n.position+1, -this.regexIndex===this.count&&this.considerAll()),n}} -if(e.compilerExtensions||(e.compilerExtensions=[]), -e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") -;return e.classNameAliases=s(e.classNameAliases||{}),function n(r,o){const a=r -;if(r.isCompiled)return a -;[N,A,U,j].forEach((e=>e(r,o))),e.compilerExtensions.forEach((e=>e(r,o))), -r.__beforeBegin=null,[S,R,M].forEach((e=>e(r,o))),r.isCompiled=!0;let l=null -;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords), -l=r.keywords.$pattern, -delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=B(r.keywords,e.case_insensitive)), -a.keywordPatternRe=t(l,!0), -o&&(r.begin||(r.begin=/\B|\b/),a.beginRe=t(r.begin),r.end||r.endsWithParent||(r.end=/\B|\b/), -r.end&&(a.endRe=t(r.end)), -a.terminatorEnd=g(r.end)||"",r.endsWithParent&&o.terminatorEnd&&(a.terminatorEnd+=(r.end?"|":"")+o.terminatorEnd)), -r.illegal&&(a.illegalRe=t(r.illegal)), -r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>s(e,{ -variants:null},t)))),e.cachedVariants?e.cachedVariants:K(e)?s(e,{ -starts:e.starts?s(e.starts):null -}):Object.isFrozen(e)?s(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{n(e,a) -})),r.starts&&n(r.starts,o),a.matcher=(e=>{const t=new i -;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin" -}))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end" -}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t})(a),a}(e)}function K(e){ -return!!e&&(e.endsWithParent||K(e.starts))}const W=r,X=s,Z=Symbol("nomatch") -;var G=(e=>{const t=Object.create(null),r=Object.create(null),s=[];let o=!0 -;const a="Could not find the language '{}', did you forget to load/include a language module?",l={ -disableAutodetect:!0,name:"Plain text",contains:[]};let g={ -ignoreUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, -languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", -cssSelector:"pre code",languages:null,__emitter:c};function d(e){ -return g.noHighlightRe.test(e)}function u(e,t,n){let i="",r="" -;"object"==typeof t?(i=e, -n=t.ignoreIllegals,r=t.language):(C("10.7.0","highlight(lang, code, ...args) has been deprecated."), -C("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), -r=e,i=t),void 0===n&&(n=!0);const s={code:i,language:r};y("before:highlight",s) -;const o=s.result?s.result:h(s.language,s.code,n) -;return o.code=s.code,y("after:highlight",o),o}function h(e,n,r,s){ -const l=Object.create(null);function c(){if(!k.keywords)return void S.addText(R) -;let e=0;k.keywordPatternRe.lastIndex=0;let t=k.keywordPatternRe.exec(R),n="" -;for(;t;){n+=R.substring(e,t.index) -;const r=_.case_insensitive?t[0].toLowerCase():t[0],s=(i=r,k.keywords[i]);if(s){ -const[e,i]=s -;if(S.addText(n),n="",l[r]=(l[r]||0)+1,l[r]<=7&&(A+=i),e.startsWith("_"))n+=t[0];else{ -const n=_.classNameAliases[e]||e;S.addKeyword(t[0],n)}}else n+=t[0] -;e=k.keywordPatternRe.lastIndex,t=k.keywordPatternRe.exec(R)}var i -;n+=R.substr(e),S.addText(n)}function d(){null!=k.subLanguage?(()=>{ -if(""===R)return;let e=null;if("string"==typeof k.subLanguage){ -if(!t[k.subLanguage])return void S.addText(R) -;e=h(k.subLanguage,R,!0,N[k.subLanguage]),N[k.subLanguage]=e._top -}else e=f(R,k.subLanguage.length?k.subLanguage:null) -;k.relevance>0&&(A+=e.relevance),S.addSublanguage(e._emitter,e.language) -})():c(),R=""}function u(e,t){let n=1;for(;void 0!==t[n];){if(!e._emit[n]){n++ -;continue}const i=_.classNameAliases[e[n]]||e[n],r=t[n] -;i?S.addKeyword(r,i):(R=r,c(),R=""),n++}}function p(e,t){ -return e.scope&&"string"==typeof e.scope&&S.openNode(_.classNameAliases[e.scope]||e.scope), -e.beginScope&&(e.beginScope._wrap?(S.addKeyword(R,_.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), -R=""):e.beginScope._multi&&(u(e.beginScope,t),R="")),k=Object.create(e,{parent:{ -value:k}}),k}function b(e,t,n){let r=((e,t)=>{const n=e&&e.exec(t) -;return n&&0===n.index})(e.endRe,n);if(r){if(e["on:end"]){const n=new i(e) -;e["on:end"](t,n),n.isMatchIgnored&&(r=!1)}if(r){ -for(;e.endsParent&&e.parent;)e=e.parent;return e}} -if(e.endsWithParent)return b(e.parent,t,n)}function m(e){ -return 0===k.matcher.regexIndex?(R+=e[0],1):(I=!0,0)}function x(e){ -const t=e[0],i=n.substr(e.index),r=b(k,e,i);if(!r)return Z;const s=k -;k.endScope&&k.endScope._wrap?(d(), -S.addKeyword(t,k.endScope._wrap)):k.endScope&&k.endScope._multi?(d(), -u(k.endScope,e)):s.skip?R+=t:(s.returnEnd||s.excludeEnd||(R+=t), -d(),s.excludeEnd&&(R=t));do{ -k.scope&&S.closeNode(),k.skip||k.subLanguage||(A+=k.relevance),k=k.parent -}while(k!==r.parent);return r.starts&&p(r.starts,e),s.returnEnd?0:t.length} -let w={};function y(t,s){const a=s&&s[0];if(R+=t,null==a)return d(),0 -;if("begin"===w.type&&"end"===s.type&&w.index===s.index&&""===a){ -if(R+=n.slice(s.index,s.index+1),!o){const t=Error(`0 width match regex (${e})`) -;throw t.languageName=e,t.badRule=w.rule,t}return 1} -if(w=s,"begin"===s.type)return(e=>{ -const t=e[0],n=e.rule,r=new i(n),s=[n.__beforeBegin,n["on:begin"]] -;for(const n of s)if(n&&(n(e,r),r.isMatchIgnored))return m(t) -;return n.skip?R+=t:(n.excludeBegin&&(R+=t), -d(),n.returnBegin||n.excludeBegin||(R=t)),p(n,e),n.returnBegin?0:t.length})(s) -;if("illegal"===s.type&&!r){ -const e=Error('Illegal lexeme "'+a+'" for mode "'+(k.scope||"")+'"') -;throw e.mode=k,e}if("end"===s.type){const e=x(s);if(e!==Z)return e} -if("illegal"===s.type&&""===a)return 1 -;if(j>1e5&&j>3*s.index)throw Error("potential infinite loop, way more iterations than matches") -;return R+=a,a.length}const _=E(e) -;if(!_)throw D(a.replace("{}",e)),Error('Unknown language: "'+e+'"') -;const v=z(_);let O="",k=s||v;const N={},S=new g.__emitter(g);(()=>{const e=[] -;for(let t=k;t!==_;t=t.parent)t.scope&&e.unshift(t.scope) -;e.forEach((e=>S.openNode(e)))})();let R="",A=0,M=0,j=0,I=!1;try{ -for(k.matcher.considerAll();;){ -j++,I?I=!1:k.matcher.considerAll(),k.matcher.lastIndex=M -;const e=k.matcher.exec(n);if(!e)break;const t=y(n.substring(M,e.index),e) -;M=e.index+t}return y(n.substr(M)),S.closeAllNodes(),S.finalize(),O=S.toHTML(),{ -language:e,value:O,relevance:A,illegal:!1,_emitter:S,_top:k}}catch(t){ -if(t.message&&t.message.includes("Illegal"))return{language:e,value:W(n), -illegal:!0,relevance:0,_illegalBy:{message:t.message,index:M, -context:n.slice(M-100,M+100),mode:t.mode,resultSoFar:O},_emitter:S};if(o)return{ -language:e,value:W(n),illegal:!1,relevance:0,errorRaised:t,_emitter:S,_top:k} -;throw t}}function f(e,n){n=n||g.languages||Object.keys(t);const i=(e=>{ -const t={value:W(e),illegal:!1,relevance:0,_top:l,_emitter:new g.__emitter(g)} -;return t._emitter.addText(e),t})(e),r=n.filter(E).filter(w).map((t=>h(t,e,!1))) -;r.unshift(i);const s=r.sort(((e,t)=>{ -if(e.relevance!==t.relevance)return t.relevance-e.relevance -;if(e.language&&t.language){if(E(e.language).supersetOf===t.language)return 1 -;if(E(t.language).supersetOf===e.language)return-1}return 0})),[o,a]=s,c=o -;return c.secondBest=a,c}function p(e){let t=null;const n=(e=>{ -let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"" -;const n=g.languageDetectRe.exec(t);if(n){const t=E(n[1]) -;return t||(P(a.replace("{}",n[1])), -P("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"} -return t.split(/\s+/).find((e=>d(e)||E(e)))})(e);if(d(n))return -;y("before:highlightElement",{el:e,language:n -}),!g.ignoreUnescapedHTML&&e.children.length>0&&(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), -console.warn("https://github.com/highlightjs/highlight.js/issues/2886"), -console.warn(e)),t=e;const i=t.textContent,s=n?u(i,{language:n,ignoreIllegals:!0 -}):f(i);e.innerHTML=s.value,((e,t,n)=>{const i=t&&r[t]||n -;e.classList.add("hljs"),e.classList.add("language-"+i) -})(e,n,s.language),e.result={language:s.language,re:s.relevance, -relevance:s.relevance},s.secondBest&&(e.secondBest={ -language:s.secondBest.language,relevance:s.secondBest.relevance -}),y("after:highlightElement",{el:e,result:s,text:i})}let b=!1;function m(){ -"loading"!==document.readyState?document.querySelectorAll(g.cssSelector).forEach(p):b=!0 -}function E(e){return e=(e||"").toLowerCase(),t[e]||t[r[e]]} -function x(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ -r[e.toLowerCase()]=t}))}function w(e){const t=E(e) -;return t&&!t.disableAutodetect}function y(e,t){const n=e;s.forEach((e=>{ -e[n]&&e[n](t)}))} -"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ -b&&m()}),!1),Object.assign(e,{highlight:u,highlightAuto:f,highlightAll:m, -highlightElement:p, -highlightBlock:e=>(C("10.7.0","highlightBlock will be removed entirely in v12.0"), -C("10.7.0","Please use highlightElement now."),p(e)),configure:e=>{g=X(g,e)}, -initHighlighting:()=>{ -m(),C("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, -initHighlightingOnLoad:()=>{ -m(),C("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") -},registerLanguage:(n,i)=>{let r=null;try{r=i(e)}catch(e){ -if(D("Language definition for '{}' could not be registered.".replace("{}",n)), -!o)throw e;D(e),r=l} -r.name||(r.name=n),t[n]=r,r.rawDefinition=i.bind(null,e),r.aliases&&x(r.aliases,{ -languageName:n})},unregisterLanguage:e=>{delete t[e] -;for(const t of Object.keys(r))r[t]===e&&delete r[t]}, -listLanguages:()=>Object.keys(t),getLanguage:E,registerAliases:x, -autoDetection:w,inherit:X,addPlugin:e=>{(e=>{ -e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{ -e["before:highlightBlock"](Object.assign({block:t.el},t)) -}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{ -e["after:highlightBlock"](Object.assign({block:t.el},t))})})(e),s.push(e)} -}),e.debugMode=()=>{o=!1},e.safeMode=()=>{o=!0},e.versionString="11.2.0" -;for(const e in O)"object"==typeof O[e]&&n(O[e]);return Object.assign(e,O),e -})({});export default G; \ No newline at end of file diff --git a/static/lib/highlightjs/cdn-release@11.2.0/build/es/highlight.js b/static/lib/highlightjs/cdn-release@11.2.0/build/es/highlight.js deleted file mode 100644 index 75bbeb6c..00000000 --- a/static/lib/highlightjs/cdn-release@11.2.0/build/es/highlight.js +++ /dev/null @@ -1,11580 +0,0 @@ -/*! - Highlight.js v11.2.0 (git: 2a5c592e5e) - (c) 2006-2021 Ivan Sagalaev and other contributors - License: BSD-3-Clause - */ -var deepFreezeEs6 = {exports: {}}; - -function deepFreeze(obj) { - if (obj instanceof Map) { - obj.clear = obj.delete = obj.set = function () { - throw new Error('map is read-only'); - }; - } else if (obj instanceof Set) { - obj.add = obj.clear = obj.delete = function () { - throw new Error('set is read-only'); - }; - } - - // Freeze self - Object.freeze(obj); - - Object.getOwnPropertyNames(obj).forEach(function (name) { - var prop = obj[name]; - - // Freeze prop if it is an object - if (typeof prop == 'object' && !Object.isFrozen(prop)) { - deepFreeze(prop); - } - }); - - return obj; -} - -deepFreezeEs6.exports = deepFreeze; -deepFreezeEs6.exports.default = deepFreeze; - -var deepFreeze$1 = deepFreezeEs6.exports; - -/** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */ -/** @typedef {import('highlight.js').CompiledMode} CompiledMode */ -/** @implements CallbackResponse */ - -class Response { - /** - * @param {CompiledMode} mode - */ - constructor(mode) { - // eslint-disable-next-line no-undefined - if (mode.data === undefined) mode.data = {}; - - this.data = mode.data; - this.isMatchIgnored = false; - } - - ignoreMatch() { - this.isMatchIgnored = true; - } -} - -/** - * @param {string} value - * @returns {string} - */ -function escapeHTML(value) { - return value - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); -} - -/** - * performs a shallow merge of multiple objects into one - * - * @template T - * @param {T} original - * @param {Record[]} objects - * @returns {T} a single new object - */ -function inherit$1(original, ...objects) { - /** @type Record */ - const result = Object.create(null); - - for (const key in original) { - result[key] = original[key]; - } - objects.forEach(function(obj) { - for (const key in obj) { - result[key] = obj[key]; - } - }); - return /** @type {T} */ (result); -} - -/** - * @typedef {object} Renderer - * @property {(text: string) => void} addText - * @property {(node: Node) => void} openNode - * @property {(node: Node) => void} closeNode - * @property {() => string} value - */ - -/** @typedef {{kind?: string, sublanguage?: boolean}} Node */ -/** @typedef {{walk: (r: Renderer) => void}} Tree */ -/** */ - -const SPAN_CLOSE = ''; - -/** - * Determines if a node needs to be wrapped in - * - * @param {Node} node */ -const emitsWrappingTags = (node) => { - return !!node.kind; -}; - -/** - * - * @param {string} name - * @param {{prefix:string}} options - */ -const expandScopeName = (name, { prefix }) => { - if (name.includes(".")) { - const pieces = name.split("."); - return [ - `${prefix}${pieces.shift()}`, - ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`)) - ].join(" "); - } - return `${prefix}${name}`; -}; - -/** @type {Renderer} */ -class HTMLRenderer { - /** - * Creates a new HTMLRenderer - * - * @param {Tree} parseTree - the parse tree (must support `walk` API) - * @param {{classPrefix: string}} options - */ - constructor(parseTree, options) { - this.buffer = ""; - this.classPrefix = options.classPrefix; - parseTree.walk(this); - } - - /** - * Adds texts to the output stream - * - * @param {string} text */ - addText(text) { - this.buffer += escapeHTML(text); - } - - /** - * Adds a node open to the output stream (if needed) - * - * @param {Node} node */ - openNode(node) { - if (!emitsWrappingTags(node)) return; - - let scope = node.kind; - if (node.sublanguage) { - scope = `language-${scope}`; - } else { - scope = expandScopeName(scope, { prefix: this.classPrefix }); - } - this.span(scope); - } - - /** - * Adds a node close to the output stream (if needed) - * - * @param {Node} node */ - closeNode(node) { - if (!emitsWrappingTags(node)) return; - - this.buffer += SPAN_CLOSE; - } - - /** - * returns the accumulated buffer - */ - value() { - return this.buffer; - } - - // helpers - - /** - * Builds a span element - * - * @param {string} className */ - span(className) { - this.buffer += ``; - } -} - -/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} | string} Node */ -/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} } DataNode */ -/** @typedef {import('highlight.js').Emitter} Emitter */ -/** */ - -class TokenTree { - constructor() { - /** @type DataNode */ - this.rootNode = { children: [] }; - this.stack = [this.rootNode]; - } - - get top() { - return this.stack[this.stack.length - 1]; - } - - get root() { return this.rootNode; } - - /** @param {Node} node */ - add(node) { - this.top.children.push(node); - } - - /** @param {string} kind */ - openNode(kind) { - /** @type Node */ - const node = { kind, children: [] }; - this.add(node); - this.stack.push(node); - } - - closeNode() { - if (this.stack.length > 1) { - return this.stack.pop(); - } - // eslint-disable-next-line no-undefined - return undefined; - } - - closeAllNodes() { - while (this.closeNode()); - } - - toJSON() { - return JSON.stringify(this.rootNode, null, 4); - } - - /** - * @typedef { import("./html_renderer").Renderer } Renderer - * @param {Renderer} builder - */ - walk(builder) { - // this does not - return this.constructor._walk(builder, this.rootNode); - // this works - // return TokenTree._walk(builder, this.rootNode); - } - - /** - * @param {Renderer} builder - * @param {Node} node - */ - static _walk(builder, node) { - if (typeof node === "string") { - builder.addText(node); - } else if (node.children) { - builder.openNode(node); - node.children.forEach((child) => this._walk(builder, child)); - builder.closeNode(node); - } - return builder; - } - - /** - * @param {Node} node - */ - static _collapse(node) { - if (typeof node === "string") return; - if (!node.children) return; - - if (node.children.every(el => typeof el === "string")) { - // node.text = node.children.join(""); - // delete node.children; - node.children = [node.children.join("")]; - } else { - node.children.forEach((child) => { - TokenTree._collapse(child); - }); - } - } -} - -/** - Currently this is all private API, but this is the minimal API necessary - that an Emitter must implement to fully support the parser. - - Minimal interface: - - - addKeyword(text, kind) - - addText(text) - - addSublanguage(emitter, subLanguageName) - - finalize() - - openNode(kind) - - closeNode() - - closeAllNodes() - - toHTML() - -*/ - -/** - * @implements {Emitter} - */ -class TokenTreeEmitter extends TokenTree { - /** - * @param {*} options - */ - constructor(options) { - super(); - this.options = options; - } - - /** - * @param {string} text - * @param {string} kind - */ - addKeyword(text, kind) { - if (text === "") { return; } - - this.openNode(kind); - this.addText(text); - this.closeNode(); - } - - /** - * @param {string} text - */ - addText(text) { - if (text === "") { return; } - - this.add(text); - } - - /** - * @param {Emitter & {root: DataNode}} emitter - * @param {string} name - */ - addSublanguage(emitter, name) { - /** @type DataNode */ - const node = emitter.root; - node.kind = name; - node.sublanguage = true; - this.add(node); - } - - toHTML() { - const renderer = new HTMLRenderer(this, this.options); - return renderer.value(); - } - - finalize() { - return true; - } -} - -/** - * @param {string} value - * @returns {RegExp} - * */ - -/** - * @param {RegExp | string } re - * @returns {string} - */ -function source(re) { - if (!re) return null; - if (typeof re === "string") return re; - - return re.source; -} - -/** - * @param {RegExp | string } re - * @returns {string} - */ -function lookahead(re) { - return concat('(?=', re, ')'); -} - -/** - * @param {RegExp | string } re - * @returns {string} - */ -function optional(re) { - return concat('(?:', re, ')?'); -} - -/** - * @param {...(RegExp | string) } args - * @returns {string} - */ -function concat(...args) { - const joined = args.map((x) => source(x)).join(""); - return joined; -} - -function stripOptionsFromArgs(args) { - const opts = args[args.length - 1]; - - if (typeof opts === 'object' && opts.constructor === Object) { - args.splice(args.length - 1, 1); - return opts; - } else { - return {}; - } -} - -/** - * Any of the passed expresssions may match - * - * Creates a huge this | this | that | that match - * @param {(RegExp | string)[] } args - * @returns {string} - */ -function either(...args) { - const opts = stripOptionsFromArgs(args); - const joined = '(' + - (opts.capture ? "" : "?:") + - args.map((x) => source(x)).join("|") + ")"; - return joined; -} - -/** - * @param {RegExp} re - * @returns {number} - */ -function countMatchGroups(re) { - return (new RegExp(re.toString() + '|')).exec('').length - 1; -} - -/** - * Does lexeme start with a regular expression match at the beginning - * @param {RegExp} re - * @param {string} lexeme - */ -function startsWith(re, lexeme) { - const match = re && re.exec(lexeme); - return match && match.index === 0; -} - -// BACKREF_RE matches an open parenthesis or backreference. To avoid -// an incorrect parse, it additionally matches the following: -// - [...] elements, where the meaning of parentheses and escapes change -// - other escape sequences, so we do not misparse escape sequences as -// interesting elements -// - non-matching or lookahead parentheses, which do not capture. These -// follow the '(' with a '?'. -const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./; - -// **INTERNAL** Not intended for outside usage -// join logically computes regexps.join(separator), but fixes the -// backreferences so they continue to match. -// it also places each individual regular expression into it's own -// match group, keeping track of the sequencing of those match groups -// is currently an exercise for the caller. :-) -/** - * @param {(string | RegExp)[]} regexps - * @param {{joinWith: string}} opts - * @returns {string} - */ -function _rewriteBackreferences(regexps, { joinWith }) { - let numCaptures = 0; - - return regexps.map((regex) => { - numCaptures += 1; - const offset = numCaptures; - let re = source(regex); - let out = ''; - - while (re.length > 0) { - const match = BACKREF_RE.exec(re); - if (!match) { - out += re; - break; - } - out += re.substring(0, match.index); - re = re.substring(match.index + match[0].length); - if (match[0][0] === '\\' && match[1]) { - // Adjust the backreference. - out += '\\' + String(Number(match[1]) + offset); - } else { - out += match[0]; - if (match[0] === '(') { - numCaptures++; - } - } - } - return out; - }).map(re => `(${re})`).join(joinWith); -} - -/** @typedef {import('highlight.js').Mode} Mode */ -/** @typedef {import('highlight.js').ModeCallback} ModeCallback */ - -// Common regexps -const MATCH_NOTHING_RE = /\b\B/; -const IDENT_RE$1 = '[a-zA-Z]\\w*'; -const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*'; -const NUMBER_RE = '\\b\\d+(\\.\\d+)?'; -const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float -const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b... -const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~'; - -/** -* @param { Partial & {binary?: string | RegExp} } opts -*/ -const SHEBANG = (opts = {}) => { - const beginShebang = /^#![ ]*\//; - if (opts.binary) { - opts.begin = concat( - beginShebang, - /.*\b/, - opts.binary, - /\b.*/); - } - return inherit$1({ - scope: 'meta', - begin: beginShebang, - end: /$/, - relevance: 0, - /** @type {ModeCallback} */ - "on:begin": (m, resp) => { - if (m.index !== 0) resp.ignoreMatch(); - } - }, opts); -}; - -// Common modes -const BACKSLASH_ESCAPE = { - begin: '\\\\[\\s\\S]', relevance: 0 -}; -const APOS_STRING_MODE = { - scope: 'string', - begin: '\'', - end: '\'', - illegal: '\\n', - contains: [BACKSLASH_ESCAPE] -}; -const QUOTE_STRING_MODE = { - scope: 'string', - begin: '"', - end: '"', - illegal: '\\n', - contains: [BACKSLASH_ESCAPE] -}; -const PHRASAL_WORDS_MODE = { - begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ -}; -/** - * Creates a comment mode - * - * @param {string | RegExp} begin - * @param {string | RegExp} end - * @param {Mode | {}} [modeOptions] - * @returns {Partial} - */ -const COMMENT = function(begin, end, modeOptions = {}) { - const mode = inherit$1( - { - scope: 'comment', - begin, - end, - contains: [] - }, - modeOptions - ); - mode.contains.push({ - scope: 'doctag', - // hack to avoid the space from being included. the space is necessary to - // match here to prevent the plain text rule below from gobbling up doctags - begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)', - end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/, - excludeBegin: true, - relevance: 0 - }); - const ENGLISH_WORD = either( - // list of common 1 and 2 letter words in English - "I", - "a", - "is", - "so", - "us", - "to", - "at", - "if", - "in", - "it", - "on", - // note: this is not an exhaustive list of contractions, just popular ones - /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc - /[A-Za-z]+[-][a-z]+/, // `no-way`, etc. - /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences - ); - // looking like plain text, more likely to be a comment - mode.contains.push( - { - // TODO: how to include ", (, ) without breaking grammars that use these for - // comment delimiters? - // begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/ - // --- - - // this tries to find sequences of 3 english words in a row (without any - // "programming" type syntax) this gives us a strong signal that we've - // TRULY found a comment - vs perhaps scanning with the wrong language. - // It's possible to find something that LOOKS like the start of the - // comment - but then if there is no readable text - good chance it is a - // false match and not a comment. - // - // for a visual example please see: - // https://github.com/highlightjs/highlight.js/issues/2827 - - begin: concat( - /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */ - '(', - ENGLISH_WORD, - /[.]?[:]?([.][ ]|[ ])/, - '){3}') // look for 3 words in a row - } - ); - return mode; -}; -const C_LINE_COMMENT_MODE = COMMENT('//', '$'); -const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/'); -const HASH_COMMENT_MODE = COMMENT('#', '$'); -const NUMBER_MODE = { - scope: 'number', - begin: NUMBER_RE, - relevance: 0 -}; -const C_NUMBER_MODE = { - scope: 'number', - begin: C_NUMBER_RE, - relevance: 0 -}; -const BINARY_NUMBER_MODE = { - scope: 'number', - begin: BINARY_NUMBER_RE, - relevance: 0 -}; -const REGEXP_MODE = { - // this outer rule makes sure we actually have a WHOLE regex and not simply - // an expression such as: - // - // 3 / something - // - // (which will then blow up when regex's `illegal` sees the newline) - begin: /(?=\/[^/\n]*\/)/, - contains: [{ - scope: 'regexp', - begin: /\//, - end: /\/[gimuy]*/, - illegal: /\n/, - contains: [ - BACKSLASH_ESCAPE, - { - begin: /\[/, - end: /\]/, - relevance: 0, - contains: [BACKSLASH_ESCAPE] - } - ] - }] -}; -const TITLE_MODE = { - scope: 'title', - begin: IDENT_RE$1, - relevance: 0 -}; -const UNDERSCORE_TITLE_MODE = { - scope: 'title', - begin: UNDERSCORE_IDENT_RE, - relevance: 0 -}; -const METHOD_GUARD = { - // excludes method names from keyword processing - begin: '\\.\\s*' + UNDERSCORE_IDENT_RE, - relevance: 0 -}; - -/** - * Adds end same as begin mechanics to a mode - * - * Your mode must include at least a single () match group as that first match - * group is what is used for comparison - * @param {Partial} mode - */ -const END_SAME_AS_BEGIN = function(mode) { - return Object.assign(mode, - { - /** @type {ModeCallback} */ - 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; }, - /** @type {ModeCallback} */ - 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); } - }); -}; - -var MODES$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - MATCH_NOTHING_RE: MATCH_NOTHING_RE, - IDENT_RE: IDENT_RE$1, - UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE, - NUMBER_RE: NUMBER_RE, - C_NUMBER_RE: C_NUMBER_RE, - BINARY_NUMBER_RE: BINARY_NUMBER_RE, - RE_STARTERS_RE: RE_STARTERS_RE, - SHEBANG: SHEBANG, - BACKSLASH_ESCAPE: BACKSLASH_ESCAPE, - APOS_STRING_MODE: APOS_STRING_MODE, - QUOTE_STRING_MODE: QUOTE_STRING_MODE, - PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE, - COMMENT: COMMENT, - C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE, - C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE, - HASH_COMMENT_MODE: HASH_COMMENT_MODE, - NUMBER_MODE: NUMBER_MODE, - C_NUMBER_MODE: C_NUMBER_MODE, - BINARY_NUMBER_MODE: BINARY_NUMBER_MODE, - REGEXP_MODE: REGEXP_MODE, - TITLE_MODE: TITLE_MODE, - UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE, - METHOD_GUARD: METHOD_GUARD, - END_SAME_AS_BEGIN: END_SAME_AS_BEGIN -}); - -/** -@typedef {import('highlight.js').CallbackResponse} CallbackResponse -@typedef {import('highlight.js').CompilerExt} CompilerExt -*/ - -// Grammar extensions / plugins -// See: https://github.com/highlightjs/highlight.js/issues/2833 - -// Grammar extensions allow "syntactic sugar" to be added to the grammar modes -// without requiring any underlying changes to the compiler internals. - -// `compileMatch` being the perfect small example of now allowing a grammar -// author to write `match` when they desire to match a single expression rather -// than being forced to use `begin`. The extension then just moves `match` into -// `begin` when it runs. Ie, no features have been added, but we've just made -// the experience of writing (and reading grammars) a little bit nicer. - -// ------ - -// TODO: We need negative look-behind support to do this properly -/** - * Skip a match if it has a preceding dot - * - * This is used for `beginKeywords` to prevent matching expressions such as - * `bob.keyword.do()`. The mode compiler automatically wires this up as a - * special _internal_ 'on:begin' callback for modes with `beginKeywords` - * @param {RegExpMatchArray} match - * @param {CallbackResponse} response - */ -function skipIfHasPrecedingDot(match, response) { - const before = match.input[match.index - 1]; - if (before === ".") { - response.ignoreMatch(); - } -} - -/** - * - * @type {CompilerExt} - */ -function scopeClassName(mode, _parent) { - // eslint-disable-next-line no-undefined - if (mode.className !== undefined) { - mode.scope = mode.className; - delete mode.className; - } -} - -/** - * `beginKeywords` syntactic sugar - * @type {CompilerExt} - */ -function beginKeywords(mode, parent) { - if (!parent) return; - if (!mode.beginKeywords) return; - - // for languages with keywords that include non-word characters checking for - // a word boundary is not sufficient, so instead we check for a word boundary - // or whitespace - this does no harm in any case since our keyword engine - // doesn't allow spaces in keywords anyways and we still check for the boundary - // first - mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)'; - mode.__beforeBegin = skipIfHasPrecedingDot; - mode.keywords = mode.keywords || mode.beginKeywords; - delete mode.beginKeywords; - - // prevents double relevance, the keywords themselves provide - // relevance, the mode doesn't need to double it - // eslint-disable-next-line no-undefined - if (mode.relevance === undefined) mode.relevance = 0; -} - -/** - * Allow `illegal` to contain an array of illegal values - * @type {CompilerExt} - */ -function compileIllegal(mode, _parent) { - if (!Array.isArray(mode.illegal)) return; - - mode.illegal = either(...mode.illegal); -} - -/** - * `match` to match a single expression for readability - * @type {CompilerExt} - */ -function compileMatch(mode, _parent) { - if (!mode.match) return; - if (mode.begin || mode.end) throw new Error("begin & end are not supported with match"); - - mode.begin = mode.match; - delete mode.match; -} - -/** - * provides the default 1 relevance to all modes - * @type {CompilerExt} - */ -function compileRelevance(mode, _parent) { - // eslint-disable-next-line no-undefined - if (mode.relevance === undefined) mode.relevance = 1; -} - -// allow beforeMatch to act as a "qualifier" for the match -// the full match begin must be [beforeMatch][begin] -const beforeMatchExt = (mode, parent) => { - if (!mode.beforeMatch) return; - // starts conflicts with endsParent which we need to make sure the child - // rule is not matched multiple times - if (mode.starts) throw new Error("beforeMatch cannot be used with starts"); - - const originalMode = Object.assign({}, mode); - Object.keys(mode).forEach((key) => { delete mode[key]; }); - - mode.keywords = originalMode.keywords; - mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin)); - mode.starts = { - relevance: 0, - contains: [ - Object.assign(originalMode, { endsParent: true }) - ] - }; - mode.relevance = 0; - - delete originalMode.beforeMatch; -}; - -// keywords that should have no default relevance value -const COMMON_KEYWORDS = [ - 'of', - 'and', - 'for', - 'in', - 'not', - 'or', - 'if', - 'then', - 'parent', // common variable name - 'list', // common variable name - 'value' // common variable name -]; - -const DEFAULT_KEYWORD_SCOPE = "keyword"; - -/** - * Given raw keywords from a language definition, compile them. - * - * @param {string | Record | Array} rawKeywords - * @param {boolean} caseInsensitive - */ -function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) { - /** @type KeywordDict */ - const compiledKeywords = Object.create(null); - - // input can be a string of keywords, an array of keywords, or a object with - // named keys representing scopeName (which can then point to a string or array) - if (typeof rawKeywords === 'string') { - compileList(scopeName, rawKeywords.split(" ")); - } else if (Array.isArray(rawKeywords)) { - compileList(scopeName, rawKeywords); - } else { - Object.keys(rawKeywords).forEach(function(scopeName) { - // collapse all our objects back into the parent object - Object.assign( - compiledKeywords, - compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName) - ); - }); - } - return compiledKeywords; - - // --- - - /** - * Compiles an individual list of keywords - * - * Ex: "for if when while|5" - * - * @param {string} scopeName - * @param {Array} keywordList - */ - function compileList(scopeName, keywordList) { - if (caseInsensitive) { - keywordList = keywordList.map(x => x.toLowerCase()); - } - keywordList.forEach(function(keyword) { - const pair = keyword.split('|'); - compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])]; - }); - } -} - -/** - * Returns the proper score for a given keyword - * - * Also takes into account comment keywords, which will be scored 0 UNLESS - * another score has been manually assigned. - * @param {string} keyword - * @param {string} [providedScore] - */ -function scoreForKeyword(keyword, providedScore) { - // manual scores always win over common keywords - // so you can force a score of 1 if you really insist - if (providedScore) { - return Number(providedScore); - } - - return commonKeyword(keyword) ? 0 : 1; -} - -/** - * Determines if a given keyword is common or not - * - * @param {string} keyword */ -function commonKeyword(keyword) { - return COMMON_KEYWORDS.includes(keyword.toLowerCase()); -} - -/* - -For the reasoning behind this please see: -https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419 - -*/ - -/** - * @type {Record} - */ -const seenDeprecations = {}; - -/** - * @param {string} message - */ -const error = (message) => { - console.error(message); -}; - -/** - * @param {string} message - * @param {any} args - */ -const warn = (message, ...args) => { - console.log(`WARN: ${message}`, ...args); -}; - -/** - * @param {string} version - * @param {string} message - */ -const deprecated = (version, message) => { - if (seenDeprecations[`${version}/${message}`]) return; - - console.log(`Deprecated as of ${version}. ${message}`); - seenDeprecations[`${version}/${message}`] = true; -}; - -/* eslint-disable no-throw-literal */ - -/** -@typedef {import('highlight.js').CompiledMode} CompiledMode -*/ - -const MultiClassError = new Error(); - -/** - * Renumbers labeled scope names to account for additional inner match - * groups that otherwise would break everything. - * - * Lets say we 3 match scopes: - * - * { 1 => ..., 2 => ..., 3 => ... } - * - * So what we need is a clean match like this: - * - * (a)(b)(c) => [ "a", "b", "c" ] - * - * But this falls apart with inner match groups: - * - * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ] - * - * Our scopes are now "out of alignment" and we're repeating `b` 3 times. - * What needs to happen is the numbers are remapped: - * - * { 1 => ..., 2 => ..., 5 => ... } - * - * We also need to know that the ONLY groups that should be output - * are 1, 2, and 5. This function handles this behavior. - * - * @param {CompiledMode} mode - * @param {Array} regexes - * @param {{key: "beginScope"|"endScope"}} opts - */ -function remapScopeNames(mode, regexes, { key }) { - let offset = 0; - const scopeNames = mode[key]; - /** @type Record */ - const emit = {}; - /** @type Record */ - const positions = {}; - - for (let i = 1; i <= regexes.length; i++) { - positions[i + offset] = scopeNames[i]; - emit[i + offset] = true; - offset += countMatchGroups(regexes[i - 1]); - } - // we use _emit to keep track of which match groups are "top-level" to avoid double - // output from inside match groups - mode[key] = positions; - mode[key]._emit = emit; - mode[key]._multi = true; -} - -/** - * @param {CompiledMode} mode - */ -function beginMultiClass(mode) { - if (!Array.isArray(mode.begin)) return; - - if (mode.skip || mode.excludeBegin || mode.returnBegin) { - error("skip, excludeBegin, returnBegin not compatible with beginScope: {}"); - throw MultiClassError; - } - - if (typeof mode.beginScope !== "object" || mode.beginScope === null) { - error("beginScope must be object"); - throw MultiClassError; - } - - remapScopeNames(mode, mode.begin, {key: "beginScope"}); - mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" }); -} - -/** - * @param {CompiledMode} mode - */ -function endMultiClass(mode) { - if (!Array.isArray(mode.end)) return; - - if (mode.skip || mode.excludeEnd || mode.returnEnd) { - error("skip, excludeEnd, returnEnd not compatible with endScope: {}"); - throw MultiClassError; - } - - if (typeof mode.endScope !== "object" || mode.endScope === null) { - error("endScope must be object"); - throw MultiClassError; - } - - remapScopeNames(mode, mode.end, {key: "endScope"}); - mode.end = _rewriteBackreferences(mode.end, { joinWith: "" }); -} - -/** - * this exists only to allow `scope: {}` to be used beside `match:` - * Otherwise `beginScope` would necessary and that would look weird - - { - match: [ /def/, /\w+/ ] - scope: { 1: "keyword" , 2: "title" } - } - - * @param {CompiledMode} mode - */ -function scopeSugar(mode) { - if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) { - mode.beginScope = mode.scope; - delete mode.scope; - } -} - -/** - * @param {CompiledMode} mode - */ -function MultiClass(mode) { - scopeSugar(mode); - - if (typeof mode.beginScope === "string") { - mode.beginScope = { _wrap: mode.beginScope }; - } - if (typeof mode.endScope === "string") { - mode.endScope = { _wrap: mode.endScope }; - } - - beginMultiClass(mode); - endMultiClass(mode); -} - -/** -@typedef {import('highlight.js').Mode} Mode -@typedef {import('highlight.js').CompiledMode} CompiledMode -@typedef {import('highlight.js').Language} Language -@typedef {import('highlight.js').HLJSPlugin} HLJSPlugin -@typedef {import('highlight.js').CompiledLanguage} CompiledLanguage -*/ - -// compilation - -/** - * Compiles a language definition result - * - * Given the raw result of a language definition (Language), compiles this so - * that it is ready for highlighting code. - * @param {Language} language - * @returns {CompiledLanguage} - */ -function compileLanguage(language) { - /** - * Builds a regex with the case sensitivity of the current language - * - * @param {RegExp | string} value - * @param {boolean} [global] - */ - function langRe(value, global) { - return new RegExp( - source(value), - 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '') - ); - } - - /** - Stores multiple regular expressions and allows you to quickly search for - them all in a string simultaneously - returning the first match. It does - this by creating a huge (a|b|c) regex - each individual item wrapped with () - and joined by `|` - using match groups to track position. When a match is - found checking which position in the array has content allows us to figure - out which of the original regexes / match groups triggered the match. - - The match object itself (the result of `Regex.exec`) is returned but also - enhanced by merging in any meta-data that was registered with the regex. - This is how we keep track of which mode matched, and what type of rule - (`illegal`, `begin`, end, etc). - */ - class MultiRegex { - constructor() { - this.matchIndexes = {}; - // @ts-ignore - this.regexes = []; - this.matchAt = 1; - this.position = 0; - } - - // @ts-ignore - addRule(re, opts) { - opts.position = this.position++; - // @ts-ignore - this.matchIndexes[this.matchAt] = opts; - this.regexes.push([opts, re]); - this.matchAt += countMatchGroups(re) + 1; - } - - compile() { - if (this.regexes.length === 0) { - // avoids the need to check length every time exec is called - // @ts-ignore - this.exec = () => null; - } - const terminators = this.regexes.map(el => el[1]); - this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true); - this.lastIndex = 0; - } - - /** @param {string} s */ - exec(s) { - this.matcherRe.lastIndex = this.lastIndex; - const match = this.matcherRe.exec(s); - if (!match) { return null; } - - // eslint-disable-next-line no-undefined - const i = match.findIndex((el, i) => i > 0 && el !== undefined); - // @ts-ignore - const matchData = this.matchIndexes[i]; - // trim off any earlier non-relevant match groups (ie, the other regex - // match groups that make up the multi-matcher) - match.splice(0, i); - - return Object.assign(match, matchData); - } - } - - /* - Created to solve the key deficiently with MultiRegex - there is no way to - test for multiple matches at a single location. Why would we need to do - that? In the future a more dynamic engine will allow certain matches to be - ignored. An example: if we matched say the 3rd regex in a large group but - decided to ignore it - we'd need to started testing again at the 4th - regex... but MultiRegex itself gives us no real way to do that. - - So what this class creates MultiRegexs on the fly for whatever search - position they are needed. - - NOTE: These additional MultiRegex objects are created dynamically. For most - grammars most of the time we will never actually need anything more than the - first MultiRegex - so this shouldn't have too much overhead. - - Say this is our search group, and we match regex3, but wish to ignore it. - - regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0 - - What we need is a new MultiRegex that only includes the remaining - possibilities: - - regex4 | regex5 ' ie, startAt = 3 - - This class wraps all that complexity up in a simple API... `startAt` decides - where in the array of expressions to start doing the matching. It - auto-increments, so if a match is found at position 2, then startAt will be - set to 3. If the end is reached startAt will return to 0. - - MOST of the time the parser will be setting startAt manually to 0. - */ - class ResumableMultiRegex { - constructor() { - // @ts-ignore - this.rules = []; - // @ts-ignore - this.multiRegexes = []; - this.count = 0; - - this.lastIndex = 0; - this.regexIndex = 0; - } - - // @ts-ignore - getMatcher(index) { - if (this.multiRegexes[index]) return this.multiRegexes[index]; - - const matcher = new MultiRegex(); - this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts)); - matcher.compile(); - this.multiRegexes[index] = matcher; - return matcher; - } - - resumingScanAtSamePosition() { - return this.regexIndex !== 0; - } - - considerAll() { - this.regexIndex = 0; - } - - // @ts-ignore - addRule(re, opts) { - this.rules.push([re, opts]); - if (opts.type === "begin") this.count++; - } - - /** @param {string} s */ - exec(s) { - const m = this.getMatcher(this.regexIndex); - m.lastIndex = this.lastIndex; - let result = m.exec(s); - - // The following is because we have no easy way to say "resume scanning at the - // existing position but also skip the current rule ONLY". What happens is - // all prior rules are also skipped which can result in matching the wrong - // thing. Example of matching "booger": - - // our matcher is [string, "booger", number] - // - // ....booger.... - - // if "booger" is ignored then we'd really need a regex to scan from the - // SAME position for only: [string, number] but ignoring "booger" (if it - // was the first match), a simple resume would scan ahead who knows how - // far looking only for "number", ignoring potential string matches (or - // future "booger" matches that might be valid.) - - // So what we do: We execute two matchers, one resuming at the same - // position, but the second full matcher starting at the position after: - - // /--- resume first regex match here (for [number]) - // |/---- full match here for [string, "booger", number] - // vv - // ....booger.... - - // Which ever results in a match first is then used. So this 3-4 step - // process essentially allows us to say "match at this position, excluding - // a prior rule that was ignored". - // - // 1. Match "booger" first, ignore. Also proves that [string] does non match. - // 2. Resume matching for [number] - // 3. Match at index + 1 for [string, "booger", number] - // 4. If #2 and #3 result in matches, which came first? - if (this.resumingScanAtSamePosition()) { - if (result && result.index === this.lastIndex) ; else { // use the second matcher result - const m2 = this.getMatcher(0); - m2.lastIndex = this.lastIndex + 1; - result = m2.exec(s); - } - } - - if (result) { - this.regexIndex += result.position + 1; - if (this.regexIndex === this.count) { - // wrap-around to considering all matches again - this.considerAll(); - } - } - - return result; - } - } - - /** - * Given a mode, builds a huge ResumableMultiRegex that can be used to walk - * the content and find matches. - * - * @param {CompiledMode} mode - * @returns {ResumableMultiRegex} - */ - function buildModeRegex(mode) { - const mm = new ResumableMultiRegex(); - - mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: "begin" })); - - if (mode.terminatorEnd) { - mm.addRule(mode.terminatorEnd, { type: "end" }); - } - if (mode.illegal) { - mm.addRule(mode.illegal, { type: "illegal" }); - } - - return mm; - } - - /** skip vs abort vs ignore - * - * @skip - The mode is still entered and exited normally (and contains rules apply), - * but all content is held and added to the parent buffer rather than being - * output when the mode ends. Mostly used with `sublanguage` to build up - * a single large buffer than can be parsed by sublanguage. - * - * - The mode begin ands ends normally. - * - Content matched is added to the parent mode buffer. - * - The parser cursor is moved forward normally. - * - * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it - * never matched) but DOES NOT continue to match subsequent `contains` - * modes. Abort is bad/suboptimal because it can result in modes - * farther down not getting applied because an earlier rule eats the - * content but then aborts. - * - * - The mode does not begin. - * - Content matched by `begin` is added to the mode buffer. - * - The parser cursor is moved forward accordingly. - * - * @ignore - Ignores the mode (as if it never matched) and continues to match any - * subsequent `contains` modes. Ignore isn't technically possible with - * the current parser implementation. - * - * - The mode does not begin. - * - Content matched by `begin` is ignored. - * - The parser cursor is not moved forward. - */ - - /** - * Compiles an individual mode - * - * This can raise an error if the mode contains certain detectable known logic - * issues. - * @param {Mode} mode - * @param {CompiledMode | null} [parent] - * @returns {CompiledMode | never} - */ - function compileMode(mode, parent) { - const cmode = /** @type CompiledMode */ (mode); - if (mode.isCompiled) return cmode; - - [ - scopeClassName, - // do this early so compiler extensions generally don't have to worry about - // the distinction between match/begin - compileMatch, - MultiClass, - beforeMatchExt - ].forEach(ext => ext(mode, parent)); - - language.compilerExtensions.forEach(ext => ext(mode, parent)); - - // __beforeBegin is considered private API, internal use only - mode.__beforeBegin = null; - - [ - beginKeywords, - // do this later so compiler extensions that come earlier have access to the - // raw array if they wanted to perhaps manipulate it, etc. - compileIllegal, - // default to 1 relevance if not specified - compileRelevance - ].forEach(ext => ext(mode, parent)); - - mode.isCompiled = true; - - let keywordPattern = null; - if (typeof mode.keywords === "object" && mode.keywords.$pattern) { - // we need a copy because keywords might be compiled multiple times - // so we can't go deleting $pattern from the original on the first - // pass - mode.keywords = Object.assign({}, mode.keywords); - keywordPattern = mode.keywords.$pattern; - delete mode.keywords.$pattern; - } - keywordPattern = keywordPattern || /\w+/; - - if (mode.keywords) { - mode.keywords = compileKeywords(mode.keywords, language.case_insensitive); - } - - cmode.keywordPatternRe = langRe(keywordPattern, true); - - if (parent) { - if (!mode.begin) mode.begin = /\B|\b/; - cmode.beginRe = langRe(mode.begin); - if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/; - if (mode.end) cmode.endRe = langRe(mode.end); - cmode.terminatorEnd = source(mode.end) || ''; - if (mode.endsWithParent && parent.terminatorEnd) { - cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd; - } - } - if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal)); - if (!mode.contains) mode.contains = []; - - mode.contains = [].concat(...mode.contains.map(function(c) { - return expandOrCloneMode(c === 'self' ? mode : c); - })); - mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); }); - - if (mode.starts) { - compileMode(mode.starts, parent); - } - - cmode.matcher = buildModeRegex(cmode); - return cmode; - } - - if (!language.compilerExtensions) language.compilerExtensions = []; - - // self is not valid at the top-level - if (language.contains && language.contains.includes('self')) { - throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation."); - } - - // we need a null object, which inherit will guarantee - language.classNameAliases = inherit$1(language.classNameAliases || {}); - - return compileMode(/** @type Mode */ (language)); -} - -/** - * Determines if a mode has a dependency on it's parent or not - * - * If a mode does have a parent dependency then often we need to clone it if - * it's used in multiple places so that each copy points to the correct parent, - * where-as modes without a parent can often safely be re-used at the bottom of - * a mode chain. - * - * @param {Mode | null} mode - * @returns {boolean} - is there a dependency on the parent? - * */ -function dependencyOnParent(mode) { - if (!mode) return false; - - return mode.endsWithParent || dependencyOnParent(mode.starts); -} - -/** - * Expands a mode or clones it if necessary - * - * This is necessary for modes with parental dependenceis (see notes on - * `dependencyOnParent`) and for nodes that have `variants` - which must then be - * exploded into their own individual modes at compile time. - * - * @param {Mode} mode - * @returns {Mode | Mode[]} - * */ -function expandOrCloneMode(mode) { - if (mode.variants && !mode.cachedVariants) { - mode.cachedVariants = mode.variants.map(function(variant) { - return inherit$1(mode, { variants: null }, variant); - }); - } - - // EXPAND - // if we have variants then essentially "replace" the mode with the variants - // this happens in compileMode, where this function is called from - if (mode.cachedVariants) { - return mode.cachedVariants; - } - - // CLONE - // if we have dependencies on parents then we need a unique - // instance of ourselves, so we can be reused with many - // different parents without issue - if (dependencyOnParent(mode)) { - return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null }); - } - - if (Object.isFrozen(mode)) { - return inherit$1(mode); - } - - // no special dependency issues, just return ourselves - return mode; -} - -var version = "11.2.0"; - -/* -Syntax highlighting with language autodetection. -https://highlightjs.org/ -*/ - -/** -@typedef {import('highlight.js').Mode} Mode -@typedef {import('highlight.js').CompiledMode} CompiledMode -@typedef {import('highlight.js').Language} Language -@typedef {import('highlight.js').HLJSApi} HLJSApi -@typedef {import('highlight.js').HLJSPlugin} HLJSPlugin -@typedef {import('highlight.js').PluginEvent} PluginEvent -@typedef {import('highlight.js').HLJSOptions} HLJSOptions -@typedef {import('highlight.js').LanguageFn} LanguageFn -@typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement -@typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext -@typedef {import('highlight.js/private').MatchType} MatchType -@typedef {import('highlight.js/private').KeywordData} KeywordData -@typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch -@typedef {import('highlight.js/private').AnnotatedError} AnnotatedError -@typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult -@typedef {import('highlight.js').HighlightOptions} HighlightOptions -@typedef {import('highlight.js').HighlightResult} HighlightResult -*/ - - -const escape = escapeHTML; -const inherit = inherit$1; -const NO_MATCH = Symbol("nomatch"); -const MAX_KEYWORD_HITS = 7; - -/** - * @param {any} hljs - object that is extended (legacy) - * @returns {HLJSApi} - */ -const HLJS = function(hljs) { - // Global internal variables used within the highlight.js library. - /** @type {Record} */ - const languages = Object.create(null); - /** @type {Record} */ - const aliases = Object.create(null); - /** @type {HLJSPlugin[]} */ - const plugins = []; - - // safe/production mode - swallows more errors, tries to keep running - // even if a single syntax or parse hits a fatal error - let SAFE_MODE = true; - const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?"; - /** @type {Language} */ - const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] }; - - // Global options used when within external APIs. This is modified when - // calling the `hljs.configure` function. - /** @type HLJSOptions */ - let options = { - ignoreUnescapedHTML: false, - noHighlightRe: /^(no-?highlight)$/i, - languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i, - classPrefix: 'hljs-', - cssSelector: 'pre code', - languages: null, - // beta configuration options, subject to change, welcome to discuss - // https://github.com/highlightjs/highlight.js/issues/1086 - __emitter: TokenTreeEmitter - }; - - /* Utility functions */ - - /** - * Tests a language name to see if highlighting should be skipped - * @param {string} languageName - */ - function shouldNotHighlight(languageName) { - return options.noHighlightRe.test(languageName); - } - - /** - * @param {HighlightedHTMLElement} block - the HTML element to determine language for - */ - function blockLanguage(block) { - let classes = block.className + ' '; - - classes += block.parentNode ? block.parentNode.className : ''; - - // language-* takes precedence over non-prefixed class names. - const match = options.languageDetectRe.exec(classes); - if (match) { - const language = getLanguage(match[1]); - if (!language) { - warn(LANGUAGE_NOT_FOUND.replace("{}", match[1])); - warn("Falling back to no-highlight mode for this block.", block); - } - return language ? match[1] : 'no-highlight'; - } - - return classes - .split(/\s+/) - .find((_class) => shouldNotHighlight(_class) || getLanguage(_class)); - } - - /** - * Core highlighting function. - * - * OLD API - * highlight(lang, code, ignoreIllegals, continuation) - * - * NEW API - * highlight(code, {lang, ignoreIllegals}) - * - * @param {string} codeOrLanguageName - the language to use for highlighting - * @param {string | HighlightOptions} optionsOrCode - the code to highlight - * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail - * - * @returns {HighlightResult} Result - an object that represents the result - * @property {string} language - the language name - * @property {number} relevance - the relevance score - * @property {string} value - the highlighted HTML code - * @property {string} code - the original raw code - * @property {CompiledMode} top - top of the current mode stack - * @property {boolean} illegal - indicates whether any illegal matches were found - */ - function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) { - let code = ""; - let languageName = ""; - if (typeof optionsOrCode === "object") { - code = codeOrLanguageName; - ignoreIllegals = optionsOrCode.ignoreIllegals; - languageName = optionsOrCode.language; - } else { - // old API - deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated."); - deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"); - languageName = codeOrLanguageName; - code = optionsOrCode; - } - - // https://github.com/highlightjs/highlight.js/issues/3149 - // eslint-disable-next-line no-undefined - if (ignoreIllegals === undefined) { ignoreIllegals = true; } - - /** @type {BeforeHighlightContext} */ - const context = { - code, - language: languageName - }; - // the plugin can change the desired language or the code to be highlighted - // just be changing the object it was passed - fire("before:highlight", context); - - // a before plugin can usurp the result completely by providing it's own - // in which case we don't even need to call highlight - const result = context.result - ? context.result - : _highlight(context.language, context.code, ignoreIllegals); - - result.code = context.code; - // the plugin can change anything in result to suite it - fire("after:highlight", result); - - return result; - } - - /** - * private highlight that's used internally and does not fire callbacks - * - * @param {string} languageName - the language to use for highlighting - * @param {string} codeToHighlight - the code to highlight - * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail - * @param {CompiledMode?} [continuation] - current continuation mode, if any - * @returns {HighlightResult} - result of the highlight operation - */ - function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) { - const keywordHits = Object.create(null); - - /** - * Return keyword data if a match is a keyword - * @param {CompiledMode} mode - current mode - * @param {string} matchText - the textual match - * @returns {KeywordData | false} - */ - function keywordData(mode, matchText) { - return mode.keywords[matchText]; - } - - function processKeywords() { - if (!top.keywords) { - emitter.addText(modeBuffer); - return; - } - - let lastIndex = 0; - top.keywordPatternRe.lastIndex = 0; - let match = top.keywordPatternRe.exec(modeBuffer); - let buf = ""; - - while (match) { - buf += modeBuffer.substring(lastIndex, match.index); - const word = language.case_insensitive ? match[0].toLowerCase() : match[0]; - const data = keywordData(top, word); - if (data) { - const [kind, keywordRelevance] = data; - emitter.addText(buf); - buf = ""; - - keywordHits[word] = (keywordHits[word] || 0) + 1; - if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance; - if (kind.startsWith("_")) { - // _ implied for relevance only, do not highlight - // by applying a class name - buf += match[0]; - } else { - const cssClass = language.classNameAliases[kind] || kind; - emitter.addKeyword(match[0], cssClass); - } - } else { - buf += match[0]; - } - lastIndex = top.keywordPatternRe.lastIndex; - match = top.keywordPatternRe.exec(modeBuffer); - } - buf += modeBuffer.substr(lastIndex); - emitter.addText(buf); - } - - function processSubLanguage() { - if (modeBuffer === "") return; - /** @type HighlightResult */ - let result = null; - - if (typeof top.subLanguage === 'string') { - if (!languages[top.subLanguage]) { - emitter.addText(modeBuffer); - return; - } - result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]); - continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top); - } else { - result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null); - } - - // Counting embedded language score towards the host language may be disabled - // with zeroing the containing mode relevance. Use case in point is Markdown that - // allows XML everywhere and makes every XML snippet to have a much larger Markdown - // score. - if (top.relevance > 0) { - relevance += result.relevance; - } - emitter.addSublanguage(result._emitter, result.language); - } - - function processBuffer() { - if (top.subLanguage != null) { - processSubLanguage(); - } else { - processKeywords(); - } - modeBuffer = ''; - } - - /** - * @param {CompiledMode} mode - * @param {RegExpMatchArray} match - */ - function emitMultiClass(scope, match) { - let i = 1; - // eslint-disable-next-line no-undefined - while (match[i] !== undefined) { - if (!scope._emit[i]) { i++; continue; } - const klass = language.classNameAliases[scope[i]] || scope[i]; - const text = match[i]; - if (klass) { - emitter.addKeyword(text, klass); - } else { - modeBuffer = text; - processKeywords(); - modeBuffer = ""; - } - i++; - } - } - - /** - * @param {CompiledMode} mode - new mode to start - * @param {RegExpMatchArray} match - */ - function startNewMode(mode, match) { - if (mode.scope && typeof mode.scope === "string") { - emitter.openNode(language.classNameAliases[mode.scope] || mode.scope); - } - if (mode.beginScope) { - // beginScope just wraps the begin match itself in a scope - if (mode.beginScope._wrap) { - emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap); - modeBuffer = ""; - } else if (mode.beginScope._multi) { - // at this point modeBuffer should just be the match - emitMultiClass(mode.beginScope, match); - modeBuffer = ""; - } - } - - top = Object.create(mode, { parent: { value: top } }); - return top; - } - - /** - * @param {CompiledMode } mode - the mode to potentially end - * @param {RegExpMatchArray} match - the latest match - * @param {string} matchPlusRemainder - match plus remainder of content - * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode - */ - function endOfMode(mode, match, matchPlusRemainder) { - let matched = startsWith(mode.endRe, matchPlusRemainder); - - if (matched) { - if (mode["on:end"]) { - const resp = new Response(mode); - mode["on:end"](match, resp); - if (resp.isMatchIgnored) matched = false; - } - - if (matched) { - while (mode.endsParent && mode.parent) { - mode = mode.parent; - } - return mode; - } - } - // even if on:end fires an `ignore` it's still possible - // that we might trigger the end node because of a parent mode - if (mode.endsWithParent) { - return endOfMode(mode.parent, match, matchPlusRemainder); - } - } - - /** - * Handle matching but then ignoring a sequence of text - * - * @param {string} lexeme - string containing full match text - */ - function doIgnore(lexeme) { - if (top.matcher.regexIndex === 0) { - // no more regexes to potentially match here, so we move the cursor forward one - // space - modeBuffer += lexeme[0]; - return 1; - } else { - // no need to move the cursor, we still have additional regexes to try and - // match at this very spot - resumeScanAtSamePosition = true; - return 0; - } - } - - /** - * Handle the start of a new potential mode match - * - * @param {EnhancedMatch} match - the current match - * @returns {number} how far to advance the parse cursor - */ - function doBeginMatch(match) { - const lexeme = match[0]; - const newMode = match.rule; - - const resp = new Response(newMode); - // first internal before callbacks, then the public ones - const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]]; - for (const cb of beforeCallbacks) { - if (!cb) continue; - cb(match, resp); - if (resp.isMatchIgnored) return doIgnore(lexeme); - } - - if (newMode.skip) { - modeBuffer += lexeme; - } else { - if (newMode.excludeBegin) { - modeBuffer += lexeme; - } - processBuffer(); - if (!newMode.returnBegin && !newMode.excludeBegin) { - modeBuffer = lexeme; - } - } - startNewMode(newMode, match); - return newMode.returnBegin ? 0 : lexeme.length; - } - - /** - * Handle the potential end of mode - * - * @param {RegExpMatchArray} match - the current match - */ - function doEndMatch(match) { - const lexeme = match[0]; - const matchPlusRemainder = codeToHighlight.substr(match.index); - - const endMode = endOfMode(top, match, matchPlusRemainder); - if (!endMode) { return NO_MATCH; } - - const origin = top; - if (top.endScope && top.endScope._wrap) { - processBuffer(); - emitter.addKeyword(lexeme, top.endScope._wrap); - } else if (top.endScope && top.endScope._multi) { - processBuffer(); - emitMultiClass(top.endScope, match); - } else if (origin.skip) { - modeBuffer += lexeme; - } else { - if (!(origin.returnEnd || origin.excludeEnd)) { - modeBuffer += lexeme; - } - processBuffer(); - if (origin.excludeEnd) { - modeBuffer = lexeme; - } - } - do { - if (top.scope) { - emitter.closeNode(); - } - if (!top.skip && !top.subLanguage) { - relevance += top.relevance; - } - top = top.parent; - } while (top !== endMode.parent); - if (endMode.starts) { - startNewMode(endMode.starts, match); - } - return origin.returnEnd ? 0 : lexeme.length; - } - - function processContinuations() { - const list = []; - for (let current = top; current !== language; current = current.parent) { - if (current.scope) { - list.unshift(current.scope); - } - } - list.forEach(item => emitter.openNode(item)); - } - - /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */ - let lastMatch = {}; - - /** - * Process an individual match - * - * @param {string} textBeforeMatch - text preceding the match (since the last match) - * @param {EnhancedMatch} [match] - the match itself - */ - function processLexeme(textBeforeMatch, match) { - const lexeme = match && match[0]; - - // add non-matched text to the current mode buffer - modeBuffer += textBeforeMatch; - - if (lexeme == null) { - processBuffer(); - return 0; - } - - // we've found a 0 width match and we're stuck, so we need to advance - // this happens when we have badly behaved rules that have optional matchers to the degree that - // sometimes they can end up matching nothing at all - // Ref: https://github.com/highlightjs/highlight.js/issues/2140 - if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") { - // spit the "skipped" character that our regex choked on back into the output sequence - modeBuffer += codeToHighlight.slice(match.index, match.index + 1); - if (!SAFE_MODE) { - /** @type {AnnotatedError} */ - const err = new Error(`0 width match regex (${languageName})`); - err.languageName = languageName; - err.badRule = lastMatch.rule; - throw err; - } - return 1; - } - lastMatch = match; - - if (match.type === "begin") { - return doBeginMatch(match); - } else if (match.type === "illegal" && !ignoreIllegals) { - // illegal match, we do not continue processing - /** @type {AnnotatedError} */ - const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || '') + '"'); - err.mode = top; - throw err; - } else if (match.type === "end") { - const processed = doEndMatch(match); - if (processed !== NO_MATCH) { - return processed; - } - } - - // edge case for when illegal matches $ (end of line) which is technically - // a 0 width match but not a begin/end match so it's not caught by the - // first handler (when ignoreIllegals is true) - if (match.type === "illegal" && lexeme === "") { - // advance so we aren't stuck in an infinite loop - return 1; - } - - // infinite loops are BAD, this is a last ditch catch all. if we have a - // decent number of iterations yet our index (cursor position in our - // parsing) still 3x behind our index then something is very wrong - // so we bail - if (iterations > 100000 && iterations > match.index * 3) { - const err = new Error('potential infinite loop, way more iterations than matches'); - throw err; - } - - /* - Why might be find ourselves here? An potential end match that was - triggered but could not be completed. IE, `doEndMatch` returned NO_MATCH. - (this could be because a callback requests the match be ignored, etc) - - This causes no real harm other than stopping a few times too many. - */ - - modeBuffer += lexeme; - return lexeme.length; - } - - const language = getLanguage(languageName); - if (!language) { - error(LANGUAGE_NOT_FOUND.replace("{}", languageName)); - throw new Error('Unknown language: "' + languageName + '"'); - } - - const md = compileLanguage(language); - let result = ''; - /** @type {CompiledMode} */ - let top = continuation || md; - /** @type Record */ - const continuations = {}; // keep continuations for sub-languages - const emitter = new options.__emitter(options); - processContinuations(); - let modeBuffer = ''; - let relevance = 0; - let index = 0; - let iterations = 0; - let resumeScanAtSamePosition = false; - - try { - top.matcher.considerAll(); - - for (;;) { - iterations++; - if (resumeScanAtSamePosition) { - // only regexes not matched previously will now be - // considered for a potential match - resumeScanAtSamePosition = false; - } else { - top.matcher.considerAll(); - } - top.matcher.lastIndex = index; - - const match = top.matcher.exec(codeToHighlight); - // console.log("match", match[0], match.rule && match.rule.begin) - - if (!match) break; - - const beforeMatch = codeToHighlight.substring(index, match.index); - const processedCount = processLexeme(beforeMatch, match); - index = match.index + processedCount; - } - processLexeme(codeToHighlight.substr(index)); - emitter.closeAllNodes(); - emitter.finalize(); - result = emitter.toHTML(); - - return { - language: languageName, - value: result, - relevance: relevance, - illegal: false, - _emitter: emitter, - _top: top - }; - } catch (err) { - if (err.message && err.message.includes('Illegal')) { - return { - language: languageName, - value: escape(codeToHighlight), - illegal: true, - relevance: 0, - _illegalBy: { - message: err.message, - index: index, - context: codeToHighlight.slice(index - 100, index + 100), - mode: err.mode, - resultSoFar: result - }, - _emitter: emitter - }; - } else if (SAFE_MODE) { - return { - language: languageName, - value: escape(codeToHighlight), - illegal: false, - relevance: 0, - errorRaised: err, - _emitter: emitter, - _top: top - }; - } else { - throw err; - } - } - } - - /** - * returns a valid highlight result, without actually doing any actual work, - * auto highlight starts with this and it's possible for small snippets that - * auto-detection may not find a better match - * @param {string} code - * @returns {HighlightResult} - */ - function justTextHighlightResult(code) { - const result = { - value: escape(code), - illegal: false, - relevance: 0, - _top: PLAINTEXT_LANGUAGE, - _emitter: new options.__emitter(options) - }; - result._emitter.addText(code); - return result; - } - - /** - Highlighting with language detection. Accepts a string with the code to - highlight. Returns an object with the following properties: - - - language (detected language) - - relevance (int) - - value (an HTML string with highlighting markup) - - secondBest (object with the same structure for second-best heuristically - detected language, may be absent) - - @param {string} code - @param {Array} [languageSubset] - @returns {AutoHighlightResult} - */ - function highlightAuto(code, languageSubset) { - languageSubset = languageSubset || options.languages || Object.keys(languages); - const plaintext = justTextHighlightResult(code); - - const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name => - _highlight(name, code, false) - ); - results.unshift(plaintext); // plaintext is always an option - - const sorted = results.sort((a, b) => { - // sort base on relevance - if (a.relevance !== b.relevance) return b.relevance - a.relevance; - - // always award the tie to the base language - // ie if C++ and Arduino are tied, it's more likely to be C++ - if (a.language && b.language) { - if (getLanguage(a.language).supersetOf === b.language) { - return 1; - } else if (getLanguage(b.language).supersetOf === a.language) { - return -1; - } - } - - // otherwise say they are equal, which has the effect of sorting on - // relevance while preserving the original ordering - which is how ties - // have historically been settled, ie the language that comes first always - // wins in the case of a tie - return 0; - }); - - const [best, secondBest] = sorted; - - /** @type {AutoHighlightResult} */ - const result = best; - result.secondBest = secondBest; - - return result; - } - - /** - * Builds new class name for block given the language name - * - * @param {HTMLElement} element - * @param {string} [currentLang] - * @param {string} [resultLang] - */ - function updateClassName(element, currentLang, resultLang) { - const language = (currentLang && aliases[currentLang]) || resultLang; - - element.classList.add("hljs"); - element.classList.add(`language-${language}`); - } - - /** - * Applies highlighting to a DOM node containing code. - * - * @param {HighlightedHTMLElement} element - the HTML element to highlight - */ - function highlightElement(element) { - /** @type HTMLElement */ - let node = null; - const language = blockLanguage(element); - - if (shouldNotHighlight(language)) return; - - fire("before:highlightElement", - { el: element, language: language }); - - // we should be all text, no child nodes - if (!options.ignoreUnescapedHTML && element.children.length > 0) { - console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."); - console.warn("https://github.com/highlightjs/highlight.js/issues/2886"); - console.warn(element); - } - - node = element; - const text = node.textContent; - const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text); - - element.innerHTML = result.value; - updateClassName(element, language, result.language); - element.result = { - language: result.language, - // TODO: remove with version 11.0 - re: result.relevance, - relevance: result.relevance - }; - if (result.secondBest) { - element.secondBest = { - language: result.secondBest.language, - relevance: result.secondBest.relevance - }; - } - - fire("after:highlightElement", { el: element, result, text }); - } - - /** - * Updates highlight.js global options with the passed options - * - * @param {Partial} userOptions - */ - function configure(userOptions) { - options = inherit(options, userOptions); - } - - // TODO: remove v12, deprecated - const initHighlighting = () => { - highlightAll(); - deprecated("10.6.0", "initHighlighting() deprecated. Use highlightAll() now."); - }; - - // TODO: remove v12, deprecated - function initHighlightingOnLoad() { - highlightAll(); - deprecated("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now."); - } - - let wantsHighlight = false; - - /** - * auto-highlights all pre>code elements on the page - */ - function highlightAll() { - // if we are called too early in the loading process - if (document.readyState === "loading") { - wantsHighlight = true; - return; - } - - const blocks = document.querySelectorAll(options.cssSelector); - blocks.forEach(highlightElement); - } - - function boot() { - // if a highlight was requested before DOM was loaded, do now - if (wantsHighlight) highlightAll(); - } - - // make sure we are in the browser environment - if (typeof window !== 'undefined' && window.addEventListener) { - window.addEventListener('DOMContentLoaded', boot, false); - } - - /** - * Register a language grammar module - * - * @param {string} languageName - * @param {LanguageFn} languageDefinition - */ - function registerLanguage(languageName, languageDefinition) { - let lang = null; - try { - lang = languageDefinition(hljs); - } catch (error$1) { - error("Language definition for '{}' could not be registered.".replace("{}", languageName)); - // hard or soft error - if (!SAFE_MODE) { throw error$1; } else { error(error$1); } - // languages that have serious errors are replaced with essentially a - // "plaintext" stand-in so that the code blocks will still get normal - // css classes applied to them - and one bad language won't break the - // entire highlighter - lang = PLAINTEXT_LANGUAGE; - } - // give it a temporary name if it doesn't have one in the meta-data - if (!lang.name) lang.name = languageName; - languages[languageName] = lang; - lang.rawDefinition = languageDefinition.bind(null, hljs); - - if (lang.aliases) { - registerAliases(lang.aliases, { languageName }); - } - } - - /** - * Remove a language grammar module - * - * @param {string} languageName - */ - function unregisterLanguage(languageName) { - delete languages[languageName]; - for (const alias of Object.keys(aliases)) { - if (aliases[alias] === languageName) { - delete aliases[alias]; - } - } - } - - /** - * @returns {string[]} List of language internal names - */ - function listLanguages() { - return Object.keys(languages); - } - - /** - * @param {string} name - name of the language to retrieve - * @returns {Language | undefined} - */ - function getLanguage(name) { - name = (name || '').toLowerCase(); - return languages[name] || languages[aliases[name]]; - } - - /** - * - * @param {string|string[]} aliasList - single alias or list of aliases - * @param {{languageName: string}} opts - */ - function registerAliases(aliasList, { languageName }) { - if (typeof aliasList === 'string') { - aliasList = [aliasList]; - } - aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; }); - } - - /** - * Determines if a given language has auto-detection enabled - * @param {string} name - name of the language - */ - function autoDetection(name) { - const lang = getLanguage(name); - return lang && !lang.disableAutodetect; - } - - /** - * Upgrades the old highlightBlock plugins to the new - * highlightElement API - * @param {HLJSPlugin} plugin - */ - function upgradePluginAPI(plugin) { - // TODO: remove with v12 - if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) { - plugin["before:highlightElement"] = (data) => { - plugin["before:highlightBlock"]( - Object.assign({ block: data.el }, data) - ); - }; - } - if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) { - plugin["after:highlightElement"] = (data) => { - plugin["after:highlightBlock"]( - Object.assign({ block: data.el }, data) - ); - }; - } - } - - /** - * @param {HLJSPlugin} plugin - */ - function addPlugin(plugin) { - upgradePluginAPI(plugin); - plugins.push(plugin); - } - - /** - * - * @param {PluginEvent} event - * @param {any} args - */ - function fire(event, args) { - const cb = event; - plugins.forEach(function(plugin) { - if (plugin[cb]) { - plugin[cb](args); - } - }); - } - - /** - * DEPRECATED - * @param {HighlightedHTMLElement} el - */ - function deprecateHighlightBlock(el) { - deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0"); - deprecated("10.7.0", "Please use highlightElement now."); - - return highlightElement(el); - } - - /* Interface definition */ - Object.assign(hljs, { - highlight, - highlightAuto, - highlightAll, - highlightElement, - // TODO: Remove with v12 API - highlightBlock: deprecateHighlightBlock, - configure, - initHighlighting, - initHighlightingOnLoad, - registerLanguage, - unregisterLanguage, - listLanguages, - getLanguage, - registerAliases, - autoDetection, - inherit, - addPlugin - }); - - hljs.debugMode = function() { SAFE_MODE = false; }; - hljs.safeMode = function() { SAFE_MODE = true; }; - hljs.versionString = version; - - for (const key in MODES$1) { - // @ts-ignore - if (typeof MODES$1[key] === "object") { - // @ts-ignore - deepFreeze$1(MODES$1[key]); - } - } - - // merge all the modes/regexes into our main object - Object.assign(hljs, MODES$1); - - return hljs; -}; - -// export an "instance" of the highlighter -var HighlightJS = HLJS({}); - -/* -Language: Bash -Author: vah -Contributrors: Benjamin Pannell -Website: https://www.gnu.org/software/bash/ -Category: common -*/ - -/** @type LanguageFn */ -function bash(hljs) { - const VAR = {}; - const BRACED_VAR = { - begin: /\$\{/, - end:/\}/, - contains: [ - "self", - { - begin: /:-/, - contains: [ VAR ] - } // default values - ] - }; - Object.assign(VAR,{ - className: 'variable', - variants: [ - {begin: concat(/\$[\w\d#@][\w\d_]*/, - // negative look-ahead tries to avoid matching patterns that are not - // Perl at all like $ident$, @ident@, etc. - `(?![\\w\\d])(?![$])`) }, - BRACED_VAR - ] - }); - - const SUBST = { - className: 'subst', - begin: /\$\(/, end: /\)/, - contains: [hljs.BACKSLASH_ESCAPE] - }; - const HERE_DOC = { - begin: /<<-?\s*(?=\w+)/, - starts: { - contains: [ - hljs.END_SAME_AS_BEGIN({ - begin: /(\w+)/, - end: /(\w+)/, - className: 'string' - }) - ] - } - }; - const QUOTE_STRING = { - className: 'string', - begin: /"/, end: /"/, - contains: [ - hljs.BACKSLASH_ESCAPE, - VAR, - SUBST - ] - }; - SUBST.contains.push(QUOTE_STRING); - const ESCAPED_QUOTE = { - className: '', - begin: /\\"/ - - }; - const APOS_STRING = { - className: 'string', - begin: /'/, end: /'/ - }; - const ARITHMETIC = { - begin: /\$\(\(/, - end: /\)\)/, - contains: [ - { begin: /\d+#[0-9a-f]+/, className: "number" }, - hljs.NUMBER_MODE, - VAR - ] - }; - const SH_LIKE_SHELLS = [ - "fish", - "bash", - "zsh", - "sh", - "csh", - "ksh", - "tcsh", - "dash", - "scsh", - ]; - const KNOWN_SHEBANG = hljs.SHEBANG({ - binary: `(${SH_LIKE_SHELLS.join("|")})`, - relevance: 10 - }); - const FUNCTION = { - className: 'function', - begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/, - returnBegin: true, - contains: [hljs.inherit(hljs.TITLE_MODE, {begin: /\w[\w\d_]*/})], - relevance: 0 - }; - - const KEYWORDS = [ - "if", - "then", - "else", - "elif", - "fi", - "for", - "while", - "in", - "do", - "done", - "case", - "esac", - "function" - ]; - - const LITERALS = [ - "true", - "false" - ]; - - return { - name: 'Bash', - aliases: ['sh'], - keywords: { - $pattern: /\b[a-z._-]+\b/, - keyword: KEYWORDS, - literal: LITERALS, - built_in: - // Shell built-ins - // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html - 'break cd continue eval exec exit export getopts hash pwd readonly return shift test times ' + - 'trap umask unset ' + - // Bash built-ins - 'alias bind builtin caller command declare echo enable help let local logout mapfile printf ' + - 'read readarray source type typeset ulimit unalias ' + - // Shell modifiers - 'set shopt ' + - // Zsh built-ins - 'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' + - 'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' + - 'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' + - 'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' + - 'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' + - 'zpty zregexparse zsocket zstyle ztcp' - }, - contains: [ - KNOWN_SHEBANG, // to catch known shells and boost relevancy - hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang - FUNCTION, - ARITHMETIC, - hljs.HASH_COMMENT_MODE, - HERE_DOC, - QUOTE_STRING, - ESCAPED_QUOTE, - APOS_STRING, - VAR - ] - }; -} - -/* -Language: C -Category: common, system -Website: https://en.wikipedia.org/wiki/C_(programming_language) -*/ - -/** @type LanguageFn */ -function c(hljs) { - // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does - // not include such support nor can we be sure all the grammars depending - // on it would desire this behavior - const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { - contains: [ - { - begin: /\\\n/ - } - ] - }); - const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)'; - const NAMESPACE_RE = '[a-zA-Z_]\\w*::'; - const TEMPLATE_ARGUMENT_RE = '<[^<>]+>'; - const FUNCTION_TYPE_RE = '(' + - DECLTYPE_AUTO_RE + '|' + - optional(NAMESPACE_RE) + - '[a-zA-Z_]\\w*' + optional(TEMPLATE_ARGUMENT_RE) + - ')'; - - - const TYPES = { - className: 'type', - variants: [ - { begin: '\\b[a-z\\d_]*_t\\b' }, - { match: /\batomic_[a-z]{3,6}\b/} - ] - - }; - - // https://en.cppreference.com/w/cpp/language/escape - // \\ \x \xFF \u2837 \u00323747 \374 - const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)'; - const STRINGS = { - className: 'string', - variants: [ - { - begin: '(u8?|U|L)?"', - end: '"', - illegal: '\\n', - contains: [ hljs.BACKSLASH_ESCAPE ] - }, - { - begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)", - end: '\'', - illegal: '.' - }, - hljs.END_SAME_AS_BEGIN({ - begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/, - end: /\)([^()\\ ]{0,16})"/ - }) - ] - }; - - const NUMBERS = { - className: 'number', - variants: [ - { - begin: '\\b(0b[01\']+)' - }, - { - begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)' - }, - { - begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' - } - ], - relevance: 0 - }; - - const PREPROCESSOR = { - className: 'meta', - begin: /#\s*[a-z]+\b/, - end: /$/, - keywords: { - keyword: - 'if else elif endif define undef warning error line ' + - 'pragma _Pragma ifdef ifndef include' - }, - contains: [ - { - begin: /\\\n/, - relevance: 0 - }, - hljs.inherit(STRINGS, { - className: 'string' - }), - { - className: 'string', - begin: /<.*?>/ - }, - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }; - - const TITLE_MODE = { - className: 'title', - begin: optional(NAMESPACE_RE) + hljs.IDENT_RE, - relevance: 0 - }; - - const FUNCTION_TITLE = optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\('; - - const C_KEYWORDS = [ - "asm", - "auto", - "break", - "case", - "const", - "continue", - "default", - "do", - "else", - "enum", - "extern", - "for", - "fortran", - "goto", - "if", - "inline", - "register", - "restrict", - "return", - "sizeof", - "static", - "struct", - "switch", - "typedef", - "union", - "volatile", - "while", - "_Alignas", - "_Alignof", - "_Atomic", - "_Generic", - "_Noreturn", - "_Static_assert", - "_Thread_local", - // aliases - "alignas", - "alignof", - "noreturn", - "static_assert", - "thread_local", - // not a C keyword but is, for all intents and purposes, treated exactly like one. - "_Pragma" - ]; - - const C_TYPES = [ - "float", - "double", - "signed", - "unsigned", - "int", - "short", - "long", - "char", - "void", - "_Bool", - "_Complex", - "_Imaginary", - "_Decimal32", - "_Decimal64", - "_Decimal128", - // aliases - "complex", - "bool", - "imaginary" - ]; - - const KEYWORDS = { - keyword: C_KEYWORDS, - type: C_TYPES, - literal: 'true false NULL', - // TODO: apply hinting work similar to what was done in cpp.js - built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream ' + - 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set ' + - 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos ' + - 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp ' + - 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper ' + - 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow ' + - 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp ' + - 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan ' + - 'vfprintf vprintf vsprintf endl initializer_list unique_ptr', - }; - - const EXPRESSION_CONTAINS = [ - PREPROCESSOR, - TYPES, - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - NUMBERS, - STRINGS - ]; - - const EXPRESSION_CONTEXT = { - // This mode covers expression context where we can't expect a function - // definition and shouldn't highlight anything that looks like one: - // `return some()`, `else if()`, `(x*sum(1, 2))` - variants: [ - { - begin: /=/, - end: /;/ - }, - { - begin: /\(/, - end: /\)/ - }, - { - beginKeywords: 'new throw return else', - end: /;/ - } - ], - keywords: KEYWORDS, - contains: EXPRESSION_CONTAINS.concat([ - { - begin: /\(/, - end: /\)/, - keywords: KEYWORDS, - contains: EXPRESSION_CONTAINS.concat([ 'self' ]), - relevance: 0 - } - ]), - relevance: 0 - }; - - const FUNCTION_DECLARATION = { - begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE, - returnBegin: true, - end: /[{;=]/, - excludeEnd: true, - keywords: KEYWORDS, - illegal: /[^\w\s\*&:<>.]/, - contains: [ - { // to prevent it from being confused as the function title - begin: DECLTYPE_AUTO_RE, - keywords: KEYWORDS, - relevance: 0 - }, - { - begin: FUNCTION_TITLE, - returnBegin: true, - contains: [ - hljs.inherit(TITLE_MODE, { className: "title.function" }) - ], - relevance: 0 - }, - // allow for multiple declarations, e.g.: - // extern void f(int), g(char); - { - relevance: 0, - match: /,/ - }, - { - className: 'params', - begin: /\(/, - end: /\)/, - keywords: KEYWORDS, - relevance: 0, - contains: [ - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - STRINGS, - NUMBERS, - TYPES, - // Count matching parentheses. - { - begin: /\(/, - end: /\)/, - keywords: KEYWORDS, - relevance: 0, - contains: [ - 'self', - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - STRINGS, - NUMBERS, - TYPES - ] - } - ] - }, - TYPES, - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - PREPROCESSOR - ] - }; - - return { - name: "C", - aliases: [ - 'h' - ], - keywords: KEYWORDS, - // Until differentiations are added between `c` and `cpp`, `c` will - // not be auto-detected to avoid auto-detect conflicts between C and C++ - disableAutodetect: true, - illegal: '=]/, - contains: [ - { - beginKeywords: "final class struct" - }, - hljs.TITLE_MODE - ] - } - ]), - exports: { - preprocessor: PREPROCESSOR, - strings: STRINGS, - keywords: KEYWORDS - } - }; -} - -/* -Language: C++ -Category: common, system -Website: https://isocpp.org -*/ - -/** @type LanguageFn */ -function cpp(hljs) { - // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does - // not include such support nor can we be sure all the grammars depending - // on it would desire this behavior - const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { - contains: [ - { - begin: /\\\n/ - } - ] - }); - const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)'; - const NAMESPACE_RE = '[a-zA-Z_]\\w*::'; - const TEMPLATE_ARGUMENT_RE = '<[^<>]+>'; - const FUNCTION_TYPE_RE = '(?!struct)(' + - DECLTYPE_AUTO_RE + '|' + - optional(NAMESPACE_RE) + - '[a-zA-Z_]\\w*' + optional(TEMPLATE_ARGUMENT_RE) + - ')'; - - const CPP_PRIMITIVE_TYPES = { - className: 'type', - begin: '\\b[a-z\\d_]*_t\\b' - }; - - // https://en.cppreference.com/w/cpp/language/escape - // \\ \x \xFF \u2837 \u00323747 \374 - const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)'; - const STRINGS = { - className: 'string', - variants: [ - { - begin: '(u8?|U|L)?"', - end: '"', - illegal: '\\n', - contains: [ hljs.BACKSLASH_ESCAPE ] - }, - { - begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + '|.)', - end: '\'', - illegal: '.' - }, - hljs.END_SAME_AS_BEGIN({ - begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/, - end: /\)([^()\\ ]{0,16})"/ - }) - ] - }; - - const NUMBERS = { - className: 'number', - variants: [ - { - begin: '\\b(0b[01\']+)' - }, - { - begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)' - }, - { - begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' - } - ], - relevance: 0 - }; - - const PREPROCESSOR = { - className: 'meta', - begin: /#\s*[a-z]+\b/, - end: /$/, - keywords: { - keyword: - 'if else elif endif define undef warning error line ' + - 'pragma _Pragma ifdef ifndef include' - }, - contains: [ - { - begin: /\\\n/, - relevance: 0 - }, - hljs.inherit(STRINGS, { - className: 'string' - }), - { - className: 'string', - begin: /<.*?>/ - }, - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }; - - const TITLE_MODE = { - className: 'title', - begin: optional(NAMESPACE_RE) + hljs.IDENT_RE, - relevance: 0 - }; - - const FUNCTION_TITLE = optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\('; - - // https://en.cppreference.com/w/cpp/keyword - const RESERVED_KEYWORDS = [ - 'alignas', - 'alignof', - 'and', - 'and_eq', - 'asm', - 'atomic_cancel', - 'atomic_commit', - 'atomic_noexcept', - 'auto', - 'bitand', - 'bitor', - 'break', - 'case', - 'catch', - 'class', - 'co_await', - 'co_return', - 'co_yield', - 'compl', - 'concept', - 'const', - 'const_cast|10', - 'consteval', - 'constexpr', - 'constinit', - 'continue', - 'decltype', - 'default', - 'delete', - 'do', - 'dynamic_cast|10', - 'else', - 'enum', - 'explicit', - 'export', - 'extern', - 'false', - 'final', - 'for', - 'friend', - 'goto', - 'if', - 'import', - 'inline', - 'module', - 'mutable', - 'namespace', - 'new', - 'noexcept', - 'not', - 'not_eq', - 'nullptr', - 'operator', - 'or', - 'or_eq', - 'override', - 'private', - 'protected', - 'public', - 'reflexpr', - 'register', - 'reinterpret_cast|10', - 'requires', - 'return', - 'signed', - 'sizeof', - 'static', - 'static_assert', - 'static_cast|10', - 'struct', - 'switch', - 'synchronized', - 'template', - 'this', - 'thread_local', - 'throw', - 'transaction_safe', - 'transaction_safe_dynamic', - 'true', - 'try', - 'typedef', - 'typeid', - 'typename', - 'union', - 'unsigned', - 'using', - 'virtual', - 'volatile', - 'while', - 'xor', - 'xor_eq,' - ]; - - // https://en.cppreference.com/w/cpp/keyword - const RESERVED_TYPES = [ - 'bool', - 'char', - 'char16_t', - 'char32_t', - 'char8_t', - 'double', - 'float', - 'int', - 'long', - 'short', - 'void', - 'wchar_t' - ]; - - const TYPE_HINTS = [ - 'any', - 'auto_ptr', - 'barrier', - 'binary_semaphore', - 'bitset', - 'complex', - 'condition_variable', - 'condition_variable_any', - 'counting_semaphore', - 'deque', - 'false_type', - 'future', - 'imaginary', - 'initializer_list', - 'istringstream', - 'jthread', - 'latch', - 'lock_guard', - 'multimap', - 'multiset', - 'mutex', - 'optional', - 'ostringstream', - 'packaged_task', - 'pair', - 'promise', - 'priority_queue', - 'queue', - 'recursive_mutex', - 'recursive_timed_mutex', - 'scoped_lock', - 'set', - 'shared_future', - 'shared_lock', - 'shared_mutex', - 'shared_timed_mutex', - 'shared_ptr', - 'stack', - 'string_view', - 'stringstream', - 'timed_mutex', - 'thread', - 'true_type', - 'tuple', - 'unique_lock', - 'unique_ptr', - 'unordered_map', - 'unordered_multimap', - 'unordered_multiset', - 'unordered_set', - 'variant', - 'vector', - 'weak_ptr', - 'wstring', - 'wstring_view' - ]; - - const FUNCTION_HINTS = [ - 'abort', - 'abs', - 'acos', - 'apply', - 'as_const', - 'asin', - 'atan', - 'atan2', - 'calloc', - 'ceil', - 'cerr', - 'cin', - 'clog', - 'cos', - 'cosh', - 'cout', - 'declval', - 'endl', - 'exchange', - 'exit', - 'exp', - 'fabs', - 'floor', - 'fmod', - 'forward', - 'fprintf', - 'fputs', - 'free', - 'frexp', - 'fscanf', - 'future', - 'invoke', - 'isalnum', - 'isalpha', - 'iscntrl', - 'isdigit', - 'isgraph', - 'islower', - 'isprint', - 'ispunct', - 'isspace', - 'isupper', - 'isxdigit', - 'labs', - 'launder', - 'ldexp', - 'log', - 'log10', - 'make_pair', - 'make_shared', - 'make_shared_for_overwrite', - 'make_tuple', - 'make_unique', - 'malloc', - 'memchr', - 'memcmp', - 'memcpy', - 'memset', - 'modf', - 'move', - 'pow', - 'printf', - 'putchar', - 'puts', - 'realloc', - 'scanf', - 'sin', - 'sinh', - 'snprintf', - 'sprintf', - 'sqrt', - 'sscanf', - 'std', - 'stderr', - 'stdin', - 'stdout', - 'strcat', - 'strchr', - 'strcmp', - 'strcpy', - 'strcspn', - 'strlen', - 'strncat', - 'strncmp', - 'strncpy', - 'strpbrk', - 'strrchr', - 'strspn', - 'strstr', - 'swap', - 'tan', - 'tanh', - 'terminate', - 'to_underlying', - 'tolower', - 'toupper', - 'vfprintf', - 'visit', - 'vprintf', - 'vsprintf' - ]; - - const LITERALS = [ - 'NULL', - 'false', - 'nullopt', - 'nullptr', - 'true' - ]; - - // https://en.cppreference.com/w/cpp/keyword - const BUILT_IN = [ - '_Pragma' - ]; - - const CPP_KEYWORDS = { - type: RESERVED_TYPES, - keyword: RESERVED_KEYWORDS, - literal: LITERALS, - built_in: BUILT_IN, - _type_hints: TYPE_HINTS - }; - - const FUNCTION_DISPATCH = { - className: 'function.dispatch', - relevance: 0, - keywords: { - // Only for relevance, not highlighting. - _hint: FUNCTION_HINTS - }, - begin: concat( - /\b/, - /(?!decltype)/, - /(?!if)/, - /(?!for)/, - /(?!while)/, - hljs.IDENT_RE, - lookahead(/(<[^<>]+>|)\s*\(/)) - }; - - const EXPRESSION_CONTAINS = [ - FUNCTION_DISPATCH, - PREPROCESSOR, - CPP_PRIMITIVE_TYPES, - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - NUMBERS, - STRINGS - ]; - - const EXPRESSION_CONTEXT = { - // This mode covers expression context where we can't expect a function - // definition and shouldn't highlight anything that looks like one: - // `return some()`, `else if()`, `(x*sum(1, 2))` - variants: [ - { - begin: /=/, - end: /;/ - }, - { - begin: /\(/, - end: /\)/ - }, - { - beginKeywords: 'new throw return else', - end: /;/ - } - ], - keywords: CPP_KEYWORDS, - contains: EXPRESSION_CONTAINS.concat([ - { - begin: /\(/, - end: /\)/, - keywords: CPP_KEYWORDS, - contains: EXPRESSION_CONTAINS.concat([ 'self' ]), - relevance: 0 - } - ]), - relevance: 0 - }; - - const FUNCTION_DECLARATION = { - className: 'function', - begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE, - returnBegin: true, - end: /[{;=]/, - excludeEnd: true, - keywords: CPP_KEYWORDS, - illegal: /[^\w\s\*&:<>.]/, - contains: [ - { // to prevent it from being confused as the function title - begin: DECLTYPE_AUTO_RE, - keywords: CPP_KEYWORDS, - relevance: 0 - }, - { - begin: FUNCTION_TITLE, - returnBegin: true, - contains: [ TITLE_MODE ], - relevance: 0 - }, - // needed because we do not have look-behind on the below rule - // to prevent it from grabbing the final : in a :: pair - { - begin: /::/, - relevance: 0 - }, - // initializers - { - begin: /:/, - endsWithParent: true, - contains: [ - STRINGS, - NUMBERS - ] - }, - // allow for multiple declarations, e.g.: - // extern void f(int), g(char); - { - relevance: 0, - match: /,/ - }, - { - className: 'params', - begin: /\(/, - end: /\)/, - keywords: CPP_KEYWORDS, - relevance: 0, - contains: [ - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - STRINGS, - NUMBERS, - CPP_PRIMITIVE_TYPES, - // Count matching parentheses. - { - begin: /\(/, - end: /\)/, - keywords: CPP_KEYWORDS, - relevance: 0, - contains: [ - 'self', - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - STRINGS, - NUMBERS, - CPP_PRIMITIVE_TYPES - ] - } - ] - }, - CPP_PRIMITIVE_TYPES, - C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - PREPROCESSOR - ] - }; - - return { - name: 'C++', - aliases: [ - 'cc', - 'c++', - 'h++', - 'hpp', - 'hh', - 'hxx', - 'cxx' - ], - keywords: CPP_KEYWORDS, - illegal: ' rooms (9);` - begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<', - end: '>', - keywords: CPP_KEYWORDS, - contains: [ - 'self', - CPP_PRIMITIVE_TYPES - ] - }, - { - begin: hljs.IDENT_RE + '::', - keywords: CPP_KEYWORDS - }, - { - match: [ - // extra complexity to deal with `enum class` and `enum struct` - /\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/, - /\s+/, - /\w+/ - ], - className: { - 1: 'keyword', - 3: 'title.class' - } - } - ]) - }; -} - -/* -Language: C# -Author: Jason Diamond -Contributor: Nicolas LLOBERA , Pieter Vantorre , David Pine -Website: https://docs.microsoft.com/en-us/dotnet/csharp/ -Category: common -*/ - -/** @type LanguageFn */ -function csharp(hljs) { - const BUILT_IN_KEYWORDS = [ - 'bool', - 'byte', - 'char', - 'decimal', - 'delegate', - 'double', - 'dynamic', - 'enum', - 'float', - 'int', - 'long', - 'nint', - 'nuint', - 'object', - 'sbyte', - 'short', - 'string', - 'ulong', - 'uint', - 'ushort' - ]; - const FUNCTION_MODIFIERS = [ - 'public', - 'private', - 'protected', - 'static', - 'internal', - 'protected', - 'abstract', - 'async', - 'extern', - 'override', - 'unsafe', - 'virtual', - 'new', - 'sealed', - 'partial' - ]; - const LITERAL_KEYWORDS = [ - 'default', - 'false', - 'null', - 'true' - ]; - const NORMAL_KEYWORDS = [ - 'abstract', - 'as', - 'base', - 'break', - 'case', - 'catch', - 'class', - 'const', - 'continue', - 'do', - 'else', - 'event', - 'explicit', - 'extern', - 'finally', - 'fixed', - 'for', - 'foreach', - 'goto', - 'if', - 'implicit', - 'in', - 'interface', - 'internal', - 'is', - 'lock', - 'namespace', - 'new', - 'operator', - 'out', - 'override', - 'params', - 'private', - 'protected', - 'public', - 'readonly', - 'record', - 'ref', - 'return', - 'sealed', - 'sizeof', - 'stackalloc', - 'static', - 'struct', - 'switch', - 'this', - 'throw', - 'try', - 'typeof', - 'unchecked', - 'unsafe', - 'using', - 'virtual', - 'void', - 'volatile', - 'while' - ]; - const CONTEXTUAL_KEYWORDS = [ - 'add', - 'alias', - 'and', - 'ascending', - 'async', - 'await', - 'by', - 'descending', - 'equals', - 'from', - 'get', - 'global', - 'group', - 'init', - 'into', - 'join', - 'let', - 'nameof', - 'not', - 'notnull', - 'on', - 'or', - 'orderby', - 'partial', - 'remove', - 'select', - 'set', - 'unmanaged', - 'value|0', - 'var', - 'when', - 'where', - 'with', - 'yield' - ]; - - const KEYWORDS = { - keyword: NORMAL_KEYWORDS.concat(CONTEXTUAL_KEYWORDS), - built_in: BUILT_IN_KEYWORDS, - literal: LITERAL_KEYWORDS - }; - const TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, { - begin: '[a-zA-Z](\\.?\\w)*' - }); - const NUMBERS = { - className: 'number', - variants: [ - { - begin: '\\b(0b[01\']+)' - }, - { - begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)(u|U|l|L|ul|UL|f|F|b|B)' - }, - { - begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' - } - ], - relevance: 0 - }; - const VERBATIM_STRING = { - className: 'string', - begin: '@"', - end: '"', - contains: [ - { - begin: '""' - } - ] - }; - const VERBATIM_STRING_NO_LF = hljs.inherit(VERBATIM_STRING, { - illegal: /\n/ - }); - const SUBST = { - className: 'subst', - begin: /\{/, - end: /\}/, - keywords: KEYWORDS - }; - const SUBST_NO_LF = hljs.inherit(SUBST, { - illegal: /\n/ - }); - const INTERPOLATED_STRING = { - className: 'string', - begin: /\$"/, - end: '"', - illegal: /\n/, - contains: [ - { - begin: /\{\{/ - }, - { - begin: /\}\}/ - }, - hljs.BACKSLASH_ESCAPE, - SUBST_NO_LF - ] - }; - const INTERPOLATED_VERBATIM_STRING = { - className: 'string', - begin: /\$@"/, - end: '"', - contains: [ - { - begin: /\{\{/ - }, - { - begin: /\}\}/ - }, - { - begin: '""' - }, - SUBST - ] - }; - const INTERPOLATED_VERBATIM_STRING_NO_LF = hljs.inherit(INTERPOLATED_VERBATIM_STRING, { - illegal: /\n/, - contains: [ - { - begin: /\{\{/ - }, - { - begin: /\}\}/ - }, - { - begin: '""' - }, - SUBST_NO_LF - ] - }); - SUBST.contains = [ - INTERPOLATED_VERBATIM_STRING, - INTERPOLATED_STRING, - VERBATIM_STRING, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - NUMBERS, - hljs.C_BLOCK_COMMENT_MODE - ]; - SUBST_NO_LF.contains = [ - INTERPOLATED_VERBATIM_STRING_NO_LF, - INTERPOLATED_STRING, - VERBATIM_STRING_NO_LF, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - NUMBERS, - hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, { - illegal: /\n/ - }) - ]; - const STRING = { - variants: [ - INTERPOLATED_VERBATIM_STRING, - INTERPOLATED_STRING, - VERBATIM_STRING, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE - ] - }; - - const GENERIC_MODIFIER = { - begin: "<", - end: ">", - contains: [ - { - beginKeywords: "in out" - }, - TITLE_MODE - ] - }; - const TYPE_IDENT_RE = hljs.IDENT_RE + '(<' + hljs.IDENT_RE + '(\\s*,\\s*' + hljs.IDENT_RE + ')*>)?(\\[\\])?'; - const AT_IDENTIFIER = { - // prevents expressions like `@class` from incorrect flagging - // `class` as a keyword - begin: "@" + hljs.IDENT_RE, - relevance: 0 - }; - - return { - name: 'C#', - aliases: [ - 'cs', - 'c#' - ], - keywords: KEYWORDS, - illegal: /::/, - contains: [ - hljs.COMMENT( - '///', - '$', - { - returnBegin: true, - contains: [ - { - className: 'doctag', - variants: [ - { - begin: '///', - relevance: 0 - }, - { - begin: '' - }, - { - begin: '' - } - ] - } - ] - } - ), - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - { - className: 'meta', - begin: '#', - end: '$', - keywords: { - keyword: 'if else elif endif define undef warning error line region endregion pragma checksum' - } - }, - STRING, - NUMBERS, - { - beginKeywords: 'class interface', - relevance: 0, - end: /[{;=]/, - illegal: /[^\s:,]/, - contains: [ - { - beginKeywords: "where class" - }, - TITLE_MODE, - GENERIC_MODIFIER, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - { - beginKeywords: 'namespace', - relevance: 0, - end: /[{;=]/, - illegal: /[^\s:]/, - contains: [ - TITLE_MODE, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - { - beginKeywords: 'record', - relevance: 0, - end: /[{;=]/, - illegal: /[^\s:]/, - contains: [ - TITLE_MODE, - GENERIC_MODIFIER, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - { - // [Attributes("")] - className: 'meta', - begin: '^\\s*\\[(?=[\\w])', - excludeBegin: true, - end: '\\]', - excludeEnd: true, - contains: [ - { - className: 'string', - begin: /"/, - end: /"/ - } - ] - }, - { - // Expression keywords prevent 'keyword Name(...)' from being - // recognized as a function definition - beginKeywords: 'new return throw await else', - relevance: 0 - }, - { - className: 'function', - begin: '(' + TYPE_IDENT_RE + '\\s+)+' + hljs.IDENT_RE + '\\s*(<.+>\\s*)?\\(', - returnBegin: true, - end: /\s*[{;=]/, - excludeEnd: true, - keywords: KEYWORDS, - contains: [ - // prevents these from being highlighted `title` - { - beginKeywords: FUNCTION_MODIFIERS.join(" "), - relevance: 0 - }, - { - begin: hljs.IDENT_RE + '\\s*(<.+>\\s*)?\\(', - returnBegin: true, - contains: [ - hljs.TITLE_MODE, - GENERIC_MODIFIER - ], - relevance: 0 - }, - { - className: 'params', - begin: /\(/, - end: /\)/, - excludeBegin: true, - excludeEnd: true, - keywords: KEYWORDS, - relevance: 0, - contains: [ - STRING, - NUMBERS, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - AT_IDENTIFIER - ] - }; -} - -const MODES = (hljs) => { - return { - IMPORTANT: { - scope: 'meta', - begin: '!important' - }, - HEXCOLOR: { - scope: 'number', - begin: '#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})' - }, - ATTRIBUTE_SELECTOR_MODE: { - scope: 'selector-attr', - begin: /\[/, - end: /\]/, - illegal: '$', - contains: [ - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE - ] - }, - CSS_NUMBER_MODE: { - scope: 'number', - begin: hljs.NUMBER_RE + '(' + - '%|em|ex|ch|rem' + - '|vw|vh|vmin|vmax' + - '|cm|mm|in|pt|pc|px' + - '|deg|grad|rad|turn' + - '|s|ms' + - '|Hz|kHz' + - '|dpi|dpcm|dppx' + - ')?', - relevance: 0 - }, - CSS_VARIABLE: { - className: "attr", - begin: /--[A-Za-z][A-Za-z0-9_-]*/ - } - }; -}; - -const TAGS = [ - 'a', - 'abbr', - 'address', - 'article', - 'aside', - 'audio', - 'b', - 'blockquote', - 'body', - 'button', - 'canvas', - 'caption', - 'cite', - 'code', - 'dd', - 'del', - 'details', - 'dfn', - 'div', - 'dl', - 'dt', - 'em', - 'fieldset', - 'figcaption', - 'figure', - 'footer', - 'form', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'header', - 'hgroup', - 'html', - 'i', - 'iframe', - 'img', - 'input', - 'ins', - 'kbd', - 'label', - 'legend', - 'li', - 'main', - 'mark', - 'menu', - 'nav', - 'object', - 'ol', - 'p', - 'q', - 'quote', - 'samp', - 'section', - 'span', - 'strong', - 'summary', - 'sup', - 'table', - 'tbody', - 'td', - 'textarea', - 'tfoot', - 'th', - 'thead', - 'time', - 'tr', - 'ul', - 'var', - 'video' -]; - -const MEDIA_FEATURES = [ - 'any-hover', - 'any-pointer', - 'aspect-ratio', - 'color', - 'color-gamut', - 'color-index', - 'device-aspect-ratio', - 'device-height', - 'device-width', - 'display-mode', - 'forced-colors', - 'grid', - 'height', - 'hover', - 'inverted-colors', - 'monochrome', - 'orientation', - 'overflow-block', - 'overflow-inline', - 'pointer', - 'prefers-color-scheme', - 'prefers-contrast', - 'prefers-reduced-motion', - 'prefers-reduced-transparency', - 'resolution', - 'scan', - 'scripting', - 'update', - 'width', - // TODO: find a better solution? - 'min-width', - 'max-width', - 'min-height', - 'max-height' -]; - -// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes -const PSEUDO_CLASSES = [ - 'active', - 'any-link', - 'blank', - 'checked', - 'current', - 'default', - 'defined', - 'dir', // dir() - 'disabled', - 'drop', - 'empty', - 'enabled', - 'first', - 'first-child', - 'first-of-type', - 'fullscreen', - 'future', - 'focus', - 'focus-visible', - 'focus-within', - 'has', // has() - 'host', // host or host() - 'host-context', // host-context() - 'hover', - 'indeterminate', - 'in-range', - 'invalid', - 'is', // is() - 'lang', // lang() - 'last-child', - 'last-of-type', - 'left', - 'link', - 'local-link', - 'not', // not() - 'nth-child', // nth-child() - 'nth-col', // nth-col() - 'nth-last-child', // nth-last-child() - 'nth-last-col', // nth-last-col() - 'nth-last-of-type', //nth-last-of-type() - 'nth-of-type', //nth-of-type() - 'only-child', - 'only-of-type', - 'optional', - 'out-of-range', - 'past', - 'placeholder-shown', - 'read-only', - 'read-write', - 'required', - 'right', - 'root', - 'scope', - 'target', - 'target-within', - 'user-invalid', - 'valid', - 'visited', - 'where' // where() -]; - -// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements -const PSEUDO_ELEMENTS = [ - 'after', - 'backdrop', - 'before', - 'cue', - 'cue-region', - 'first-letter', - 'first-line', - 'grammar-error', - 'marker', - 'part', - 'placeholder', - 'selection', - 'slotted', - 'spelling-error' -]; - -const ATTRIBUTES = [ - 'align-content', - 'align-items', - 'align-self', - 'animation', - 'animation-delay', - 'animation-direction', - 'animation-duration', - 'animation-fill-mode', - 'animation-iteration-count', - 'animation-name', - 'animation-play-state', - 'animation-timing-function', - 'auto', - 'backface-visibility', - 'background', - 'background-attachment', - 'background-clip', - 'background-color', - 'background-image', - 'background-origin', - 'background-position', - 'background-repeat', - 'background-size', - 'border', - 'border-bottom', - 'border-bottom-color', - 'border-bottom-left-radius', - 'border-bottom-right-radius', - 'border-bottom-style', - 'border-bottom-width', - 'border-collapse', - 'border-color', - 'border-image', - 'border-image-outset', - 'border-image-repeat', - 'border-image-slice', - 'border-image-source', - 'border-image-width', - 'border-left', - 'border-left-color', - 'border-left-style', - 'border-left-width', - 'border-radius', - 'border-right', - 'border-right-color', - 'border-right-style', - 'border-right-width', - 'border-spacing', - 'border-style', - 'border-top', - 'border-top-color', - 'border-top-left-radius', - 'border-top-right-radius', - 'border-top-style', - 'border-top-width', - 'border-width', - 'bottom', - 'box-decoration-break', - 'box-shadow', - 'box-sizing', - 'break-after', - 'break-before', - 'break-inside', - 'caption-side', - 'clear', - 'clip', - 'clip-path', - 'color', - 'column-count', - 'column-fill', - 'column-gap', - 'column-rule', - 'column-rule-color', - 'column-rule-style', - 'column-rule-width', - 'column-span', - 'column-width', - 'columns', - 'content', - 'counter-increment', - 'counter-reset', - 'cursor', - 'direction', - 'display', - 'empty-cells', - 'filter', - 'flex', - 'flex-basis', - 'flex-direction', - 'flex-flow', - 'flex-grow', - 'flex-shrink', - 'flex-wrap', - 'float', - 'font', - 'font-display', - 'font-family', - 'font-feature-settings', - 'font-kerning', - 'font-language-override', - 'font-size', - 'font-size-adjust', - 'font-smoothing', - 'font-stretch', - 'font-style', - 'font-variant', - 'font-variant-ligatures', - 'font-variation-settings', - 'font-weight', - 'height', - 'hyphens', - 'icon', - 'image-orientation', - 'image-rendering', - 'image-resolution', - 'ime-mode', - 'inherit', - 'initial', - 'justify-content', - 'left', - 'letter-spacing', - 'line-height', - 'list-style', - 'list-style-image', - 'list-style-position', - 'list-style-type', - 'margin', - 'margin-bottom', - 'margin-left', - 'margin-right', - 'margin-top', - 'marks', - 'mask', - 'max-height', - 'max-width', - 'min-height', - 'min-width', - 'nav-down', - 'nav-index', - 'nav-left', - 'nav-right', - 'nav-up', - 'none', - 'normal', - 'object-fit', - 'object-position', - 'opacity', - 'order', - 'orphans', - 'outline', - 'outline-color', - 'outline-offset', - 'outline-style', - 'outline-width', - 'overflow', - 'overflow-wrap', - 'overflow-x', - 'overflow-y', - 'padding', - 'padding-bottom', - 'padding-left', - 'padding-right', - 'padding-top', - 'page-break-after', - 'page-break-before', - 'page-break-inside', - 'perspective', - 'perspective-origin', - 'pointer-events', - 'position', - 'quotes', - 'resize', - 'right', - 'src', // @font-face - 'tab-size', - 'table-layout', - 'text-align', - 'text-align-last', - 'text-decoration', - 'text-decoration-color', - 'text-decoration-line', - 'text-decoration-style', - 'text-indent', - 'text-overflow', - 'text-rendering', - 'text-shadow', - 'text-transform', - 'text-underline-position', - 'top', - 'transform', - 'transform-origin', - 'transform-style', - 'transition', - 'transition-delay', - 'transition-duration', - 'transition-property', - 'transition-timing-function', - 'unicode-bidi', - 'vertical-align', - 'visibility', - 'white-space', - 'widows', - 'width', - 'word-break', - 'word-spacing', - 'word-wrap', - 'z-index' - // reverse makes sure longer attributes `font-weight` are matched fully - // instead of getting false positives on say `font` -].reverse(); - -// some grammars use them all as a single group -const PSEUDO_SELECTORS = PSEUDO_CLASSES.concat(PSEUDO_ELEMENTS); - -/* -Language: CSS -Category: common, css, web -Website: https://developer.mozilla.org/en-US/docs/Web/CSS -*/ - -/** @type LanguageFn */ -function css(hljs) { - const modes = MODES(hljs); - const FUNCTION_DISPATCH = { - className: "built_in", - begin: /[\w-]+(?=\()/ - }; - const VENDOR_PREFIX = { - begin: /-(webkit|moz|ms|o)-(?=[a-z])/ - }; - const AT_MODIFIERS = "and or not only"; - const AT_PROPERTY_RE = /@-?\w[\w]*(-\w+)*/; // @-webkit-keyframes - const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*'; - const STRINGS = [ - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE - ]; - - return { - name: 'CSS', - case_insensitive: true, - illegal: /[=|'\$]/, - keywords: { - keyframePosition: "from to" - }, - classNameAliases: { - // for visual continuity with `tag {}` and because we - // don't have a great class for this? - keyframePosition: "selector-tag" - }, - contains: [ - hljs.C_BLOCK_COMMENT_MODE, - VENDOR_PREFIX, - // to recognize keyframe 40% etc which are outside the scope of our - // attribute value mode - modes.CSS_NUMBER_MODE, - { - className: 'selector-id', - begin: /#[A-Za-z0-9_-]+/, - relevance: 0 - }, - { - className: 'selector-class', - begin: '\\.' + IDENT_RE, - relevance: 0 - }, - modes.ATTRIBUTE_SELECTOR_MODE, - { - className: 'selector-pseudo', - variants: [ - { - begin: ':(' + PSEUDO_CLASSES.join('|') + ')' - }, - { - begin: '::(' + PSEUDO_ELEMENTS.join('|') + ')' - } - ] - }, - // we may actually need this (12/2020) - // { // pseudo-selector params - // begin: /\(/, - // end: /\)/, - // contains: [ hljs.CSS_NUMBER_MODE ] - // }, - modes.CSS_VARIABLE, - { - className: 'attribute', - begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b' - }, - // attribute values - { - begin: ':', - end: '[;}]', - contains: [ - modes.HEXCOLOR, - modes.IMPORTANT, - modes.CSS_NUMBER_MODE, - ...STRINGS, - // needed to highlight these as strings and to avoid issues with - // illegal characters that might be inside urls that would tigger the - // languages illegal stack - { - begin: /(url|data-uri)\(/, - end: /\)/, - relevance: 0, // from keywords - keywords: { - built_in: "url data-uri" - }, - contains: [ - { - className: "string", - // any character other than `)` as in `url()` will be the start - // of a string, which ends with `)` (from the parent mode) - begin: /[^)]/, - endsWithParent: true, - excludeEnd: true - } - ] - }, - FUNCTION_DISPATCH - ] - }, - { - begin: lookahead(/@/), - end: '[{;]', - relevance: 0, - illegal: /:/, // break on Less variables @var: ... - contains: [ - { - className: 'keyword', - begin: AT_PROPERTY_RE - }, - { - begin: /\s/, - endsWithParent: true, - excludeEnd: true, - relevance: 0, - keywords: { - $pattern: /[a-z-]+/, - keyword: AT_MODIFIERS, - attribute: MEDIA_FEATURES.join(" ") - }, - contains: [ - { - begin: /[a-z-]+(?=:)/, - className: "attribute" - }, - ...STRINGS, - modes.CSS_NUMBER_MODE - ] - } - ] - }, - { - className: 'selector-tag', - begin: '\\b(' + TAGS.join('|') + ')\\b' - } - ] - }; -} - -/* -Language: Diff -Description: Unified and context diff -Author: Vasily Polovnyov -Website: https://www.gnu.org/software/diffutils/ -Category: common -*/ - -/** @type LanguageFn */ -function diff(hljs) { - return { - name: 'Diff', - aliases: ['patch'], - contains: [ - { - className: 'meta', - relevance: 10, - match: either( - /^@@ +-\d+,\d+ +\+\d+,\d+ +@@/, - /^\*\*\* +\d+,\d+ +\*\*\*\*$/, - /^--- +\d+,\d+ +----$/ - ) - }, - { - className: 'comment', - variants: [ - { - begin: either( - /Index: /, - /^index/, - /={3,}/, - /^-{3}/, - /^\*{3} /, - /^\+{3}/, - /^diff --git/ - ), - end: /$/ - }, - { - match: /^\*{15}$/ - } - ] - }, - { - className: 'addition', - begin: /^\+/, - end: /$/ - }, - { - className: 'deletion', - begin: /^-/, - end: /$/ - }, - { - className: 'addition', - begin: /^!/, - end: /$/ - } - ] - }; -} - -/* -Language: Go -Author: Stephan Kountso aka StepLg -Contributors: Evgeny Stepanischev -Description: Google go language (golang). For info about language -Website: http://golang.org/ -Category: common, system -*/ - -function go(hljs) { - const LITERALS = [ - "true", - "false", - "iota", - "nil" - ]; - const BUILT_INS = [ - "append", - "cap", - "close", - "complex", - "copy", - "imag", - "len", - "make", - "new", - "panic", - "print", - "println", - "real", - "recover", - "delete" - ]; - const KWS = [ - "break", - "default", - "func", - "interface", - "select", - "case", - "map", - "struct", - "chan", - "else", - "goto", - "package", - "switch", - "const", - "fallthrough", - "if", - "range", - "type", - "continue", - "for", - "import", - "return", - "var", - "go", - "defer", - "bool", - "byte", - "complex64", - "complex128", - "float32", - "float64", - "int8", - "int16", - "int32", - "int64", - "string", - "uint8", - "uint16", - "uint32", - "uint64", - "int", - "uint", - "uintptr", - "rune" - ]; - const KEYWORDS = { - keyword: KWS, - literal: LITERALS, - built_in: BUILT_INS - }; - return { - name: 'Go', - aliases: ['golang'], - keywords: KEYWORDS, - illegal: ' -Category: common, config -Website: https://github.com/toml-lang/toml -*/ - -function ini(hljs) { - const NUMBERS = { - className: 'number', - relevance: 0, - variants: [ - { - begin: /([+-]+)?[\d]+_[\d_]+/ - }, - { - begin: hljs.NUMBER_RE - } - ] - }; - const COMMENTS = hljs.COMMENT(); - COMMENTS.variants = [ - { - begin: /;/, - end: /$/ - }, - { - begin: /#/, - end: /$/ - } - ]; - const VARIABLES = { - className: 'variable', - variants: [ - { - begin: /\$[\w\d"][\w\d_]*/ - }, - { - begin: /\$\{(.*?)\}/ - } - ] - }; - const LITERALS = { - className: 'literal', - begin: /\bon|off|true|false|yes|no\b/ - }; - const STRINGS = { - className: "string", - contains: [hljs.BACKSLASH_ESCAPE], - variants: [ - { - begin: "'''", - end: "'''", - relevance: 10 - }, - { - begin: '"""', - end: '"""', - relevance: 10 - }, - { - begin: '"', - end: '"' - }, - { - begin: "'", - end: "'" - } - ] - }; - const ARRAY = { - begin: /\[/, - end: /\]/, - contains: [ - COMMENTS, - LITERALS, - VARIABLES, - STRINGS, - NUMBERS, - 'self' - ], - relevance: 0 - }; - - const BARE_KEY = /[A-Za-z0-9_-]+/; - const QUOTED_KEY_DOUBLE_QUOTE = /"(\\"|[^"])*"/; - const QUOTED_KEY_SINGLE_QUOTE = /'[^']*'/; - const ANY_KEY = either( - BARE_KEY, QUOTED_KEY_DOUBLE_QUOTE, QUOTED_KEY_SINGLE_QUOTE - ); - const DOTTED_KEY = concat( - ANY_KEY, '(\\s*\\.\\s*', ANY_KEY, ')*', - lookahead(/\s*=\s*[^#\s]/) - ); - - return { - name: 'TOML, also INI', - aliases: ['toml'], - case_insensitive: true, - illegal: /\S/, - contains: [ - COMMENTS, - { - className: 'section', - begin: /\[+/, - end: /\]+/ - }, - { - begin: DOTTED_KEY, - className: 'attr', - starts: { - end: /$/, - contains: [ - COMMENTS, - ARRAY, - LITERALS, - VARIABLES, - STRINGS, - NUMBERS - ] - } - } - ] - }; -} - -// https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10 -var decimalDigits = '[0-9](_*[0-9])*'; -var frac = `\\.(${decimalDigits})`; -var hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*'; -var NUMERIC = { - className: 'number', - variants: [ - // DecimalFloatingPointLiteral - // including ExponentPart - { begin: `(\\b(${decimalDigits})((${frac})|\\.)?|(${frac}))` + - `[eE][+-]?(${decimalDigits})[fFdD]?\\b` }, - // excluding ExponentPart - { begin: `\\b(${decimalDigits})((${frac})[fFdD]?\\b|\\.([fFdD]\\b)?)` }, - { begin: `(${frac})[fFdD]?\\b` }, - { begin: `\\b(${decimalDigits})[fFdD]\\b` }, - - // HexadecimalFloatingPointLiteral - { begin: `\\b0[xX]((${hexDigits})\\.?|(${hexDigits})?\\.(${hexDigits}))` + - `[pP][+-]?(${decimalDigits})[fFdD]?\\b` }, - - // DecimalIntegerLiteral - { begin: '\\b(0|[1-9](_*[0-9])*)[lL]?\\b' }, - - // HexIntegerLiteral - { begin: `\\b0[xX](${hexDigits})[lL]?\\b` }, - - // OctalIntegerLiteral - { begin: '\\b0(_*[0-7])*[lL]?\\b' }, - - // BinaryIntegerLiteral - { begin: '\\b0[bB][01](_*[01])*[lL]?\\b' }, - ], - relevance: 0 -}; - -/* -Language: Java -Author: Vsevolod Solovyov -Category: common, enterprise -Website: https://www.java.com/ -*/ - -/** - * Allows recursive regex expressions to a given depth - * - * ie: recurRegex("(abc~~~)", /~~~/g, 2) becomes: - * (abc(abc(abc))) - * - * @param {string} re - * @param {RegExp} substitution (should be a g mode regex) - * @param {number} depth - * @returns {string}`` - */ -function recurRegex(re, substitution, depth) { - if (depth === -1) return ""; - - return re.replace(substitution, _ => { - return recurRegex(re, substitution, depth - 1); - }); -} - -/** @type LanguageFn */ -function java(hljs) { - const JAVA_IDENT_RE = '[\u00C0-\u02B8a-zA-Z_$][\u00C0-\u02B8a-zA-Z_$0-9]*'; - const GENERIC_IDENT_RE = JAVA_IDENT_RE + - recurRegex('(?:<' + JAVA_IDENT_RE + '~~~(?:\\s*,\\s*' + JAVA_IDENT_RE + '~~~)*>)?', /~~~/g, 2); - const MAIN_KEYWORDS = [ - 'synchronized', - 'abstract', - 'private', - 'var', - 'static', - 'if', - 'const ', - 'for', - 'while', - 'strictfp', - 'finally', - 'protected', - 'import', - 'native', - 'final', - 'void', - 'enum', - 'else', - 'break', - 'transient', - 'catch', - 'instanceof', - 'volatile', - 'case', - 'assert', - 'package', - 'default', - 'public', - 'try', - 'switch', - 'continue', - 'throws', - 'protected', - 'public', - 'private', - 'module', - 'requires', - 'exports', - 'do' - ]; - - const BUILT_INS = [ - 'super', - 'this' - ]; - - const LITERALS = [ - 'false', - 'true', - 'null' - ]; - - const TYPES = [ - 'char', - 'boolean', - 'long', - 'float', - 'int', - 'byte', - 'short', - 'double' - ]; - - const KEYWORDS = { - keyword: MAIN_KEYWORDS, - literal: LITERALS, - type: TYPES, - built_in: BUILT_INS - }; - - const ANNOTATION = { - className: 'meta', - begin: '@' + JAVA_IDENT_RE, - contains: [ - { - begin: /\(/, - end: /\)/, - contains: [ "self" ] // allow nested () inside our annotation - } - ] - }; - const PARAMS = { - className: 'params', - begin: /\(/, - end: /\)/, - keywords: KEYWORDS, - relevance: 0, - contains: [ - hljs.C_BLOCK_COMMENT_MODE - ], - endsParent: true - }; - - return { - name: 'Java', - aliases: [ 'jsp' ], - keywords: KEYWORDS, - illegal: /<\/|#/, - contains: [ - hljs.COMMENT( - '/\\*\\*', - '\\*/', - { - relevance: 0, - contains: [ - { - // eat up @'s in emails to prevent them to be recognized as doctags - begin: /\w+@/, - relevance: 0 - }, - { - className: 'doctag', - begin: '@[A-Za-z]+' - } - ] - } - ), - // relevance boost - { - begin: /import java\.[a-z]+\./, - keywords: "import", - relevance: 2 - }, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - { - match: [ - /\b(?:class|interface|enum|extends|implements|new)/, - /\s+/, - JAVA_IDENT_RE - ], - className: { - 1: "keyword", - 3: "title.class" - } - }, - { - begin: [ - JAVA_IDENT_RE, - /\s+/, - JAVA_IDENT_RE, - /\s+/, - /=/ - ], - className: { - 1: "type", - 3: "variable", - 5: "operator" - } - }, - { - begin: [ - /record/, - /\s+/, - JAVA_IDENT_RE - ], - className: { - 1: "keyword", - 3: "title.class" - }, - contains: [ - PARAMS, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - { - // Expression keywords prevent 'keyword Name(...)' from being - // recognized as a function definition - beginKeywords: 'new throw return else', - relevance: 0 - }, - { - begin: [ - '(?:' + GENERIC_IDENT_RE + '\\s+)', - hljs.UNDERSCORE_IDENT_RE, - /\s*(?=\()/ - ], - className: { - 2: "title.function" - }, - keywords: KEYWORDS, - contains: [ - { - className: 'params', - begin: /\(/, - end: /\)/, - keywords: KEYWORDS, - relevance: 0, - contains: [ - ANNOTATION, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - NUMERIC, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ] - }, - NUMERIC, - ANNOTATION - ] - }; -} - -const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*'; -const KEYWORDS = [ - "as", // for exports - "in", - "of", - "if", - "for", - "while", - "finally", - "var", - "new", - "function", - "do", - "return", - "void", - "else", - "break", - "catch", - "instanceof", - "with", - "throw", - "case", - "default", - "try", - "switch", - "continue", - "typeof", - "delete", - "let", - "yield", - "const", - "class", - // JS handles these with a special rule - // "get", - // "set", - "debugger", - "async", - "await", - "static", - "import", - "from", - "export", - "extends" -]; -const LITERALS = [ - "true", - "false", - "null", - "undefined", - "NaN", - "Infinity" -]; - -const TYPES = [ - "Intl", - "DataView", - "Number", - "Math", - "Date", - "String", - "RegExp", - "Object", - "Function", - "Boolean", - "Error", - "Symbol", - "Set", - "Map", - "WeakSet", - "WeakMap", - "Proxy", - "Reflect", - "JSON", - "Promise", - "Float64Array", - "Int16Array", - "Int32Array", - "Int8Array", - "Uint16Array", - "Uint32Array", - "Float32Array", - "Array", - "Uint8Array", - "Uint8ClampedArray", - "ArrayBuffer", - "BigInt64Array", - "BigUint64Array", - "BigInt" -]; - -const ERROR_TYPES = [ - "EvalError", - "InternalError", - "RangeError", - "ReferenceError", - "SyntaxError", - "TypeError", - "URIError" -]; - -const BUILT_IN_GLOBALS = [ - "setInterval", - "setTimeout", - "clearInterval", - "clearTimeout", - - "require", - "exports", - - "eval", - "isFinite", - "isNaN", - "parseFloat", - "parseInt", - "decodeURI", - "decodeURIComponent", - "encodeURI", - "encodeURIComponent", - "escape", - "unescape" -]; - -const BUILT_IN_VARIABLES = [ - "arguments", - "this", - "super", - "console", - "window", - "document", - "localStorage", - "module", - "global" // Node.js -]; - -const BUILT_INS = [].concat( - BUILT_IN_GLOBALS, - TYPES, - ERROR_TYPES -); - -/* -Language: JavaScript -Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions. -Category: common, scripting, web -Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript -*/ - -/** @type LanguageFn */ -function javascript(hljs) { - /** - * Takes a string like " { - const tag = "', - end: '' - }; - const XML_TAG = { - begin: /<[A-Za-z0-9\\._:-]+/, - end: /\/[A-Za-z0-9\\._:-]+>|\/>/, - /** - * @param {RegExpMatchArray} match - * @param {CallbackResponse} response - */ - isTrulyOpeningTag: (match, response) => { - const afterMatchIndex = match[0].length + match.index; - const nextChar = match.input[afterMatchIndex]; - // nested type? - // HTML should not include another raw `<` inside a tag - // But a type might: `>`, etc. - if (nextChar === "<") { - response.ignoreMatch(); - return; - } - // - // This is now either a tag or a type. - if (nextChar === ">") { - // if we cannot find a matching closing tag, then we - // will ignore it - if (!hasClosingTag(match, { after: afterMatchIndex })) { - response.ignoreMatch(); - } - } - } - }; - const KEYWORDS$1 = { - $pattern: IDENT_RE, - keyword: KEYWORDS, - literal: LITERALS, - built_in: BUILT_INS, - "variable.language": BUILT_IN_VARIABLES - }; - - // https://tc39.es/ecma262/#sec-literals-numeric-literals - const decimalDigits = '[0-9](_?[0-9])*'; - const frac = `\\.(${decimalDigits})`; - // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral - // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals - const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`; - const NUMBER = { - className: 'number', - variants: [ - // DecimalLiteral - { begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))` + - `[eE][+-]?(${decimalDigits})\\b` }, - { begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` }, - - // DecimalBigIntegerLiteral - { begin: `\\b(0|[1-9](_?[0-9])*)n\\b` }, - - // NonDecimalIntegerLiteral - { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" }, - { begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" }, - { begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" }, - - // LegacyOctalIntegerLiteral (does not include underscore separators) - // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals - { begin: "\\b0[0-7]+n?\\b" }, - ], - relevance: 0 - }; - - const SUBST = { - className: 'subst', - begin: '\\$\\{', - end: '\\}', - keywords: KEYWORDS$1, - contains: [] // defined later - }; - const HTML_TEMPLATE = { - begin: 'html`', - end: '', - starts: { - end: '`', - returnEnd: false, - contains: [ - hljs.BACKSLASH_ESCAPE, - SUBST - ], - subLanguage: 'xml' - } - }; - const CSS_TEMPLATE = { - begin: 'css`', - end: '', - starts: { - end: '`', - returnEnd: false, - contains: [ - hljs.BACKSLASH_ESCAPE, - SUBST - ], - subLanguage: 'css' - } - }; - const TEMPLATE_STRING = { - className: 'string', - begin: '`', - end: '`', - contains: [ - hljs.BACKSLASH_ESCAPE, - SUBST - ] - }; - const JSDOC_COMMENT = hljs.COMMENT( - /\/\*\*(?!\/)/, - '\\*/', - { - relevance: 0, - contains: [ - { - begin: '(?=@[A-Za-z]+)', - relevance: 0, - contains: [ - { - className: 'doctag', - begin: '@[A-Za-z]+' - }, - { - className: 'type', - begin: '\\{', - end: '\\}', - excludeEnd: true, - excludeBegin: true, - relevance: 0 - }, - { - className: 'variable', - begin: IDENT_RE$1 + '(?=\\s*(-)|$)', - endsParent: true, - relevance: 0 - }, - // eat spaces (not newlines) so we can find - // types or variables - { - begin: /(?=[^\n])\s/, - relevance: 0 - } - ] - } - ] - } - ); - const COMMENT = { - className: "comment", - variants: [ - JSDOC_COMMENT, - hljs.C_BLOCK_COMMENT_MODE, - hljs.C_LINE_COMMENT_MODE - ] - }; - const SUBST_INTERNALS = [ - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - HTML_TEMPLATE, - CSS_TEMPLATE, - TEMPLATE_STRING, - NUMBER, - hljs.REGEXP_MODE - ]; - SUBST.contains = SUBST_INTERNALS - .concat({ - // we need to pair up {} inside our subst to prevent - // it from ending too early by matching another } - begin: /\{/, - end: /\}/, - keywords: KEYWORDS$1, - contains: [ - "self" - ].concat(SUBST_INTERNALS) - }); - const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains); - const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([ - // eat recursive parens in sub expressions - { - begin: /\(/, - end: /\)/, - keywords: KEYWORDS$1, - contains: ["self"].concat(SUBST_AND_COMMENTS) - } - ]); - const PARAMS = { - className: 'params', - begin: /\(/, - end: /\)/, - excludeBegin: true, - excludeEnd: true, - keywords: KEYWORDS$1, - contains: PARAMS_CONTAINS - }; - - // ES6 classes - const CLASS_OR_EXTENDS = { - variants: [ - { - match: [ - /class/, - /\s+/, - IDENT_RE$1 - ], - scope: { - 1: "keyword", - 3: "title.class" - } - }, - { - match: [ - /extends/, - /\s+/, - concat(IDENT_RE$1, "(", concat(/\./, IDENT_RE$1), ")*") - ], - scope: { - 1: "keyword", - 3: "title.class.inherited" - } - } - ] - }; - - const CLASS_REFERENCE = { - relevance: 0, - match: /\b[A-Z][a-z]+([A-Z][a-z]+)*/, - className: "title.class", - keywords: { - _: [ - // se we still get relevance credit for JS library classes - ...TYPES, - ...ERROR_TYPES - ] - } - }; - - const USE_STRICT = { - label: "use_strict", - className: 'meta', - relevance: 10, - begin: /^\s*['"]use (strict|asm)['"]/ - }; - - const FUNCTION_DEFINITION = { - variants: [ - { - match: [ - /function/, - /\s+/, - IDENT_RE$1, - /(?=\s*\()/ - ] - }, - // anonymous function - { - match: [ - /function/, - /\s*(?=\()/ - ] - } - ], - className: { - 1: "keyword", - 3: "title.function" - }, - label: "func.def", - contains: [ PARAMS ], - illegal: /%/ - }; - - const UPPER_CASE_CONSTANT = { - relevance: 0, - match: /\b[A-Z][A-Z_0-9]+\b/, - className: "variable.constant" - }; - - function noneOf(list) { - return concat("(?!", list.join("|"), ")"); - } - - const FUNCTION_CALL = { - match: concat( - /\b/, - noneOf([ - ...BUILT_IN_GLOBALS, - "super" - ]), - IDENT_RE$1, lookahead(/\(/)), - className: "title.function", - relevance: 0 - }; - - const PROPERTY_ACCESS = { - begin: concat(/\./, lookahead( - concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/) - )), - end: IDENT_RE$1, - excludeBegin: true, - keywords: "prototype", - className: "property", - relevance: 0 - }; - - const GETTER_OR_SETTER = { - match: [ - /get|set/, - /\s+/, - IDENT_RE$1, - /(?=\()/ - ], - className: { - 1: "keyword", - 3: "title.function" - }, - contains: [ - { // eat to avoid empty params - begin: /\(\)/ - }, - PARAMS - ] - }; - - const FUNC_LEAD_IN_RE = '(\\(' + - '[^()]*(\\(' + - '[^()]*(\\(' + - '[^()]*' + - '\\)[^()]*)*' + - '\\)[^()]*)*' + - '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>'; - - const FUNCTION_VARIABLE = { - match: [ - /const|var|let/, /\s+/, - IDENT_RE$1, /\s*/, - /=\s*/, - lookahead(FUNC_LEAD_IN_RE) - ], - className: { - 1: "keyword", - 3: "title.function" - }, - contains: [ - PARAMS - ] - }; - - return { - name: 'Javascript', - aliases: ['js', 'jsx', 'mjs', 'cjs'], - keywords: KEYWORDS$1, - // this will be extended by TypeScript - exports: { PARAMS_CONTAINS }, - illegal: /#(?![$_A-z])/, - contains: [ - hljs.SHEBANG({ - label: "shebang", - binary: "node", - relevance: 5 - }), - USE_STRICT, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - HTML_TEMPLATE, - CSS_TEMPLATE, - TEMPLATE_STRING, - COMMENT, - NUMBER, - CLASS_REFERENCE, - { - className: 'attr', - begin: IDENT_RE$1 + lookahead(':'), - relevance: 0 - }, - FUNCTION_VARIABLE, - { // "value" container - begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*', - keywords: 'return throw case', - relevance: 0, - contains: [ - COMMENT, - hljs.REGEXP_MODE, - { - className: 'function', - // we have to count the parens to make sure we actually have the - // correct bounding ( ) before the =>. There could be any number of - // sub-expressions inside also surrounded by parens. - begin: FUNC_LEAD_IN_RE, - returnBegin: true, - end: '\\s*=>', - contains: [ - { - className: 'params', - variants: [ - { - begin: hljs.UNDERSCORE_IDENT_RE, - relevance: 0 - }, - { - className: null, - begin: /\(\s*\)/, - skip: true - }, - { - begin: /\(/, - end: /\)/, - excludeBegin: true, - excludeEnd: true, - keywords: KEYWORDS$1, - contains: PARAMS_CONTAINS - } - ] - } - ] - }, - { // could be a comma delimited list of params to a function call - begin: /,/, - relevance: 0 - }, - { - match: /\s+/, - relevance: 0 - }, - { // JSX - variants: [ - { begin: FRAGMENT.begin, end: FRAGMENT.end }, - { - begin: XML_TAG.begin, - // we carefully check the opening tag to see if it truly - // is a tag and not a false positive - 'on:begin': XML_TAG.isTrulyOpeningTag, - end: XML_TAG.end - } - ], - subLanguage: 'xml', - contains: [ - { - begin: XML_TAG.begin, - end: XML_TAG.end, - skip: true, - contains: ['self'] - } - ] - } - ], - }, - FUNCTION_DEFINITION, - { - // prevent this from getting swallowed up by function - // since they appear "function like" - beginKeywords: "while if switch catch for" - }, - { - // we have to count the parens to make sure we actually have the correct - // bounding ( ). There could be any number of sub-expressions inside - // also surrounded by parens. - begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE + - '\\(' + // first parens - '[^()]*(\\(' + - '[^()]*(\\(' + - '[^()]*' + - '\\)[^()]*)*' + - '\\)[^()]*)*' + - '\\)\\s*\\{', // end parens - returnBegin:true, - label: "func.def", - contains: [ - PARAMS, - hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title.function" }) - ] - }, - // catch ... so it won't trigger the property rule below - { - match: /\.\.\./, - relevance: 0 - }, - PROPERTY_ACCESS, - // hack: prevents detection of keywords in some circumstances - // .keyword() - // $keyword = x - { - match: '\\$' + IDENT_RE$1, - relevance: 0 - }, - { - match: [ /\bconstructor(?=\s*\()/ ], - className: { 1: "title.function" }, - contains: [ PARAMS ] - }, - FUNCTION_CALL, - UPPER_CASE_CONSTANT, - CLASS_OR_EXTENDS, - GETTER_OR_SETTER, - { - match: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something` - } - ] - }; -} - -/* -Language: JSON -Description: JSON (JavaScript Object Notation) is a lightweight data-interchange format. -Author: Ivan Sagalaev -Website: http://www.json.org -Category: common, protocols, web -*/ - -function json(hljs) { - const ATTRIBUTE = { - className: 'attr', - begin: /"(\\.|[^\\"\r\n])*"(?=\s*:)/, - relevance: 1.01 - }; - const PUNCTUATION = { - match: /[{}[\],:]/, - className: "punctuation", - relevance: 0 - }; - // normally we would rely on `keywords` for this but using a mode here allows us - // to use the very tight `illegal: \S` rule later to flag any other character - // as illegal indicating that despite looking like JSON we do not truly have - // JSON and thus improve false-positively greatly since JSON will try and claim - // all sorts of JSON looking stuff - const LITERALS = { - beginKeywords: [ - "true", - "false", - "null" - ].join(" ") - }; - - return { - name: 'JSON', - contains: [ - ATTRIBUTE, - PUNCTUATION, - hljs.QUOTE_STRING_MODE, - LITERALS, - hljs.C_NUMBER_MODE, - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE - ], - illegal: '\\S' - }; -} - -/* - Language: Kotlin - Description: Kotlin is an OSS statically typed programming language that targets the JVM, Android, JavaScript and Native. - Author: Sergey Mashkov - Website: https://kotlinlang.org - Category: common - */ - -function kotlin(hljs) { - const KEYWORDS = { - keyword: - 'abstract as val var vararg get set class object open private protected public noinline ' + - 'crossinline dynamic final enum if else do while for when throw try catch finally ' + - 'import package is in fun override companion reified inline lateinit init ' + - 'interface annotation data sealed internal infix operator out by constructor super ' + - 'tailrec where const inner suspend typealias external expect actual', - built_in: - 'Byte Short Char Int Long Boolean Float Double Void Unit Nothing', - literal: - 'true false null' - }; - const KEYWORDS_WITH_LABEL = { - className: 'keyword', - begin: /\b(break|continue|return|this)\b/, - starts: { - contains: [ - { - className: 'symbol', - begin: /@\w+/ - } - ] - } - }; - const LABEL = { - className: 'symbol', - begin: hljs.UNDERSCORE_IDENT_RE + '@' - }; - - // for string templates - const SUBST = { - className: 'subst', - begin: /\$\{/, - end: /\}/, - contains: [ hljs.C_NUMBER_MODE ] - }; - const VARIABLE = { - className: 'variable', - begin: '\\$' + hljs.UNDERSCORE_IDENT_RE - }; - const STRING = { - className: 'string', - variants: [ - { - begin: '"""', - end: '"""(?=[^"])', - contains: [ - VARIABLE, - SUBST - ] - }, - // Can't use built-in modes easily, as we want to use STRING in the meta - // context as 'meta-string' and there's no syntax to remove explicitly set - // classNames in built-in modes. - { - begin: '\'', - end: '\'', - illegal: /\n/, - contains: [ hljs.BACKSLASH_ESCAPE ] - }, - { - begin: '"', - end: '"', - illegal: /\n/, - contains: [ - hljs.BACKSLASH_ESCAPE, - VARIABLE, - SUBST - ] - } - ] - }; - SUBST.contains.push(STRING); - - const ANNOTATION_USE_SITE = { - className: 'meta', - begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?' - }; - const ANNOTATION = { - className: 'meta', - begin: '@' + hljs.UNDERSCORE_IDENT_RE, - contains: [ - { - begin: /\(/, - end: /\)/, - contains: [ - hljs.inherit(STRING, { - className: 'string' - }) - ] - } - ] - }; - - // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals - // According to the doc above, the number mode of kotlin is the same as java 8, - // so the code below is copied from java.js - const KOTLIN_NUMBER_MODE = NUMERIC; - const KOTLIN_NESTED_COMMENT = hljs.COMMENT( - '/\\*', '\\*/', - { - contains: [ hljs.C_BLOCK_COMMENT_MODE ] - } - ); - const KOTLIN_PAREN_TYPE = { - variants: [ - { - className: 'type', - begin: hljs.UNDERSCORE_IDENT_RE - }, - { - begin: /\(/, - end: /\)/, - contains: [] // defined later - } - ] - }; - const KOTLIN_PAREN_TYPE2 = KOTLIN_PAREN_TYPE; - KOTLIN_PAREN_TYPE2.variants[1].contains = [ KOTLIN_PAREN_TYPE ]; - KOTLIN_PAREN_TYPE.variants[1].contains = [ KOTLIN_PAREN_TYPE2 ]; - - return { - name: 'Kotlin', - aliases: [ 'kt', 'kts' ], - keywords: KEYWORDS, - contains: [ - hljs.COMMENT( - '/\\*\\*', - '\\*/', - { - relevance: 0, - contains: [ - { - className: 'doctag', - begin: '@[A-Za-z]+' - } - ] - } - ), - hljs.C_LINE_COMMENT_MODE, - KOTLIN_NESTED_COMMENT, - KEYWORDS_WITH_LABEL, - LABEL, - ANNOTATION_USE_SITE, - ANNOTATION, - { - className: 'function', - beginKeywords: 'fun', - end: '[(]|$', - returnBegin: true, - excludeEnd: true, - keywords: KEYWORDS, - relevance: 5, - contains: [ - { - begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', - returnBegin: true, - relevance: 0, - contains: [ hljs.UNDERSCORE_TITLE_MODE ] - }, - { - className: 'type', - begin: //, - keywords: 'reified', - relevance: 0 - }, - { - className: 'params', - begin: /\(/, - end: /\)/, - endsParent: true, - keywords: KEYWORDS, - relevance: 0, - contains: [ - { - begin: /:/, - end: /[=,\/]/, - endsWithParent: true, - contains: [ - KOTLIN_PAREN_TYPE, - hljs.C_LINE_COMMENT_MODE, - KOTLIN_NESTED_COMMENT - ], - relevance: 0 - }, - hljs.C_LINE_COMMENT_MODE, - KOTLIN_NESTED_COMMENT, - ANNOTATION_USE_SITE, - ANNOTATION, - STRING, - hljs.C_NUMBER_MODE - ] - }, - KOTLIN_NESTED_COMMENT - ] - }, - { - className: 'class', - beginKeywords: 'class interface trait', // remove 'trait' when removed from KEYWORDS - end: /[:\{(]|$/, - excludeEnd: true, - illegal: 'extends implements', - contains: [ - { - beginKeywords: 'public protected internal private constructor' - }, - hljs.UNDERSCORE_TITLE_MODE, - { - className: 'type', - begin: //, - excludeBegin: true, - excludeEnd: true, - relevance: 0 - }, - { - className: 'type', - begin: /[,:]\s*/, - end: /[<\(,]|$/, - excludeBegin: true, - returnEnd: true - }, - ANNOTATION_USE_SITE, - ANNOTATION - ] - }, - STRING, - { - className: 'meta', - begin: "^#!/usr/bin/env", - end: '$', - illegal: '\n' - }, - KOTLIN_NUMBER_MODE - ] - }; -} - -/* -Language: Less -Description: It's CSS, with just a little more. -Author: Max Mikhailov -Website: http://lesscss.org -Category: common, css, web -*/ - -/** @type LanguageFn */ -function less(hljs) { - const modes = MODES(hljs); - const PSEUDO_SELECTORS$1 = PSEUDO_SELECTORS; - - const AT_MODIFIERS = "and or not only"; - const IDENT_RE = '[\\w-]+'; // yes, Less identifiers may begin with a digit - const INTERP_IDENT_RE = '(' + IDENT_RE + '|@\\{' + IDENT_RE + '\\})'; - - /* Generic Modes */ - - const RULES = []; const VALUE_MODES = []; // forward def. for recursive modes - - const STRING_MODE = function(c) { - return { - // Less strings are not multiline (also include '~' for more consistent coloring of "escaped" strings) - className: 'string', - begin: '~?' + c + '.*?' + c - }; - }; - - const IDENT_MODE = function(name, begin, relevance) { - return { - className: name, - begin: begin, - relevance: relevance - }; - }; - - const AT_KEYWORDS = { - $pattern: /[a-z-]+/, - keyword: AT_MODIFIERS, - attribute: MEDIA_FEATURES.join(" ") - }; - - const PARENS_MODE = { - // used only to properly balance nested parens inside mixin call, def. arg list - begin: '\\(', - end: '\\)', - contains: VALUE_MODES, - keywords: AT_KEYWORDS, - relevance: 0 - }; - - // generic Less highlighter (used almost everywhere except selectors): - VALUE_MODES.push( - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - STRING_MODE("'"), - STRING_MODE('"'), - modes.CSS_NUMBER_MODE, // fixme: it does not include dot for numbers like .5em :( - { - begin: '(url|data-uri)\\(', - starts: { - className: 'string', - end: '[\\)\\n]', - excludeEnd: true - } - }, - modes.HEXCOLOR, - PARENS_MODE, - IDENT_MODE('variable', '@@?' + IDENT_RE, 10), - IDENT_MODE('variable', '@\\{' + IDENT_RE + '\\}'), - IDENT_MODE('built_in', '~?`[^`]*?`'), // inline javascript (or whatever host language) *multiline* string - { // @media features (it’s here to not duplicate things in AT_RULE_MODE with extra PARENS_MODE overriding): - className: 'attribute', - begin: IDENT_RE + '\\s*:', - end: ':', - returnBegin: true, - excludeEnd: true - }, - modes.IMPORTANT - ); - - const VALUE_WITH_RULESETS = VALUE_MODES.concat({ - begin: /\{/, - end: /\}/, - contains: RULES - }); - - const MIXIN_GUARD_MODE = { - beginKeywords: 'when', - endsWithParent: true, - contains: [ - { - beginKeywords: 'and not' - } - ].concat(VALUE_MODES) // using this form to override VALUE’s 'function' match - }; - - /* Rule-Level Modes */ - - const RULE_MODE = { - begin: INTERP_IDENT_RE + '\\s*:', - returnBegin: true, - end: /[;}]/, - relevance: 0, - contains: [ - { - begin: /-(webkit|moz|ms|o)-/ - }, - modes.CSS_VARIABLE, - { - className: 'attribute', - begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b', - end: /(?=:)/, - starts: { - endsWithParent: true, - illegal: '[<=$]', - relevance: 0, - contains: VALUE_MODES - } - } - ] - }; - - const AT_RULE_MODE = { - className: 'keyword', - begin: '@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b', - starts: { - end: '[;{}]', - keywords: AT_KEYWORDS, - returnEnd: true, - contains: VALUE_MODES, - relevance: 0 - } - }; - - // variable definitions and calls - const VAR_RULE_MODE = { - className: 'variable', - variants: [ - // using more strict pattern for higher relevance to increase chances of Less detection. - // this is *the only* Less specific statement used in most of the sources, so... - // (we’ll still often loose to the css-parser unless there's '//' comment, - // simply because 1 variable just can't beat 99 properties :) - { - begin: '@' + IDENT_RE + '\\s*:', - relevance: 15 - }, - { - begin: '@' + IDENT_RE - } - ], - starts: { - end: '[;}]', - returnEnd: true, - contains: VALUE_WITH_RULESETS - } - }; - - const SELECTOR_MODE = { - // first parse unambiguous selectors (i.e. those not starting with tag) - // then fall into the scary lookahead-discriminator variant. - // this mode also handles mixin definitions and calls - variants: [ - { - begin: '[\\.#:&\\[>]', - end: '[;{}]' // mixin calls end with ';' - }, - { - begin: INTERP_IDENT_RE, - end: /\{/ - } - ], - returnBegin: true, - returnEnd: true, - illegal: '[<=\'$"]', - relevance: 0, - contains: [ - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - MIXIN_GUARD_MODE, - IDENT_MODE('keyword', 'all\\b'), - IDENT_MODE('variable', '@\\{' + IDENT_RE + '\\}'), // otherwise it’s identified as tag - { - begin: '\\b(' + TAGS.join('|') + ')\\b', - className: 'selector-tag' - }, - IDENT_MODE('selector-tag', INTERP_IDENT_RE + '%?', 0), // '%' for more consistent coloring of @keyframes "tags" - IDENT_MODE('selector-id', '#' + INTERP_IDENT_RE), - IDENT_MODE('selector-class', '\\.' + INTERP_IDENT_RE, 0), - IDENT_MODE('selector-tag', '&', 0), - modes.ATTRIBUTE_SELECTOR_MODE, - { - className: 'selector-pseudo', - begin: ':(' + PSEUDO_CLASSES.join('|') + ')' - }, - { - className: 'selector-pseudo', - begin: '::(' + PSEUDO_ELEMENTS.join('|') + ')' - }, - { - begin: /\(/, - end: /\)/, - relevance: 0, - contains: VALUE_WITH_RULESETS - }, // argument list of parametric mixins - { - begin: '!important' - } // eat !important after mixin call or it will be colored as tag - ] - }; - - const PSEUDO_SELECTOR_MODE = { - begin: IDENT_RE + ':(:)?' + `(${PSEUDO_SELECTORS$1.join('|')})`, - returnBegin: true, - contains: [ SELECTOR_MODE ] - }; - - RULES.push( - hljs.C_LINE_COMMENT_MODE, - hljs.C_BLOCK_COMMENT_MODE, - AT_RULE_MODE, - VAR_RULE_MODE, - PSEUDO_SELECTOR_MODE, - RULE_MODE, - SELECTOR_MODE - ); - - return { - name: 'Less', - case_insensitive: true, - illegal: '[=>\'/<($"]', - contains: RULES - }; -} - -/* -Language: Lua -Description: Lua is a powerful, efficient, lightweight, embeddable scripting language. -Author: Andrew Fedorov -Category: common, scripting -Website: https://www.lua.org -*/ - -function lua(hljs) { - const OPENING_LONG_BRACKET = '\\[=*\\['; - const CLOSING_LONG_BRACKET = '\\]=*\\]'; - const LONG_BRACKETS = { - begin: OPENING_LONG_BRACKET, - end: CLOSING_LONG_BRACKET, - contains: ['self'] - }; - const COMMENTS = [ - hljs.COMMENT('--(?!' + OPENING_LONG_BRACKET + ')', '$'), - hljs.COMMENT( - '--' + OPENING_LONG_BRACKET, - CLOSING_LONG_BRACKET, - { - contains: [LONG_BRACKETS], - relevance: 10 - } - ) - ]; - return { - name: 'Lua', - keywords: { - $pattern: hljs.UNDERSCORE_IDENT_RE, - literal: "true false nil", - keyword: "and break do else elseif end for goto if in local not or repeat return then until while", - built_in: - // Metatags and globals: - '_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len ' + - '__gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert ' + - // Standard methods and properties: - 'collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring ' + - 'module next pairs pcall print rawequal rawget rawset require select setfenv ' + - 'setmetatable tonumber tostring type unpack xpcall arg self ' + - // Library methods and properties (one line per library): - 'coroutine resume yield status wrap create running debug getupvalue ' + - 'debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv ' + - 'io lines write close flush open output type read stderr stdin input stdout popen tmpfile ' + - 'math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan ' + - 'os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall ' + - 'string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower ' + - 'table setn insert getn foreachi maxn foreach concat sort remove' - }, - contains: COMMENTS.concat([ - { - className: 'function', - beginKeywords: 'function', - end: '\\)', - contains: [ - hljs.inherit(hljs.TITLE_MODE, { - begin: '([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*' - }), - { - className: 'params', - begin: '\\(', - endsWithParent: true, - contains: COMMENTS - } - ].concat(COMMENTS) - }, - hljs.C_NUMBER_MODE, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - { - className: 'string', - begin: OPENING_LONG_BRACKET, - end: CLOSING_LONG_BRACKET, - contains: [LONG_BRACKETS], - relevance: 5 - } - ]) - }; -} - -/* -Language: Makefile -Author: Ivan Sagalaev -Contributors: Joël Porquet -Website: https://www.gnu.org/software/make/manual/html_node/Introduction.html -Category: common -*/ - -function makefile(hljs) { - /* Variables: simple (eg $(var)) and special (eg $@) */ - const VARIABLE = { - className: 'variable', - variants: [ - { - begin: '\\$\\(' + hljs.UNDERSCORE_IDENT_RE + '\\)', - contains: [ hljs.BACKSLASH_ESCAPE ] - }, - { - begin: /\$[@%`]+/ - } - ] - } - ] - } - ] - }; - return { - name: 'HTML, XML', - aliases: [ - 'html', - 'xhtml', - 'rss', - 'atom', - 'xjb', - 'xsd', - 'xsl', - 'plist', - 'wsf', - 'svg' - ], - case_insensitive: true, - contains: [ - { - className: 'meta', - begin: //, - relevance: 10, - contains: [ - XML_META_KEYWORDS, - QUOTE_META_STRING_MODE, - APOS_META_STRING_MODE, - XML_META_PAR_KEYWORDS, - { - begin: /\[/, - end: /\]/, - contains: [ - { - className: 'meta', - begin: //, - contains: [ - XML_META_KEYWORDS, - XML_META_PAR_KEYWORDS, - QUOTE_META_STRING_MODE, - APOS_META_STRING_MODE - ] - } - ] - } - ] - }, - hljs.COMMENT( - //, - { - relevance: 10 - } - ), - { - begin: //, - relevance: 10 - }, - XML_ENTITIES, - { - className: 'meta', - begin: /<\?xml/, - end: /\?>/, - relevance: 10 - }, - { - className: 'tag', - /* - The lookahead pattern (?=...) ensures that 'begin' only matches - ')/, - end: />/, - keywords: { - name: 'style' - }, - contains: [ TAG_INTERNALS ], - starts: { - end: /<\/style>/, - returnEnd: true, - subLanguage: [ - 'css', - 'xml' - ] - } - }, - { - className: 'tag', - // See the comment in the - +
    -{{- if ne .RedirectUrl "login"}} +{{- if ne $.redirect_url "login"}} +{{$OpenCommon := false}} +{{- if eq $.redirect_url "common"}} + {{$OpenCommon = true}} +{{- else if eq $.redirect_url "appearance"}} + {{$OpenCommon = true}} +{{- else if eq $.redirect_url "view"}} + {{$OpenCommon = true}} +{{- else}} +{{end}} +{{$OpenSafe := false}} +{{- if eq $.redirect_url "pwd"}} + {{$OpenSafe = true}} +{{- else if eq $.redirect_url "hide"}} + {{$OpenSafe = true}} +{{- else if eq $.redirect_url "safety"}} + {{$OpenSafe = true}} +{{- else}} +{{end}}
    - {{- end}}
    - {{- if eq .RedirectUrl "common"}} + {{- if eq $.redirect_url "common"}} {{block "admin-common" .}}{{end}} - {{- else if eq .RedirectUrl "appearance"}} + {{- else if eq $.redirect_url "appearance"}} {{block "admin-appearance" .}}{{end}} - {{- else if eq .RedirectUrl "security"}} + {{- else if eq $.redirect_url "security"}} {{block "admin-security" .}}{{end}} - {{- else if eq .RedirectUrl "view"}} + {{- else if eq $.redirect_url "view"}} {{block "admin-view" .}}{{end}} - {{- else if eq .RedirectUrl "login"}} + {{- else if eq $.redirect_url "login"}} {{block "admin-login" .}}{{end}} - {{- else if eq .RedirectUrl "pwd"}} + {{- else if eq $.redirect_url "pwd"}} {{block "admin-pwd" .}}{{end}} - {{- else if eq .RedirectUrl "hide"}} + {{- else if eq $.redirect_url "hide"}} {{block "admin-hide" .}}{{end}} - {{- else if eq .RedirectUrl "safety"}} + {{- else if eq $.redirect_url "safety"}} {{block "admin-safety" .}}{{end}} - {{- else if eq .RedirectUrl "disk"}} + {{- else if eq $.redirect_url "disk"}} {{block "admin-disk" .}}{{end}} - {{- else}} + {{- else if eq $.redirect_url "bypass"}} + {{block "admin-bypass" .}}{{end}} + {{- else if eq $.redirect_url "cache"}} + {{block "admin-cache" .}}{{end}} + {{- else if eq $.redirect_url "webdav"}} + {{block "admin-webdav" .}}{{end}} {{- end}}
    - - + + diff --git a/templates/pan/admin/bypass.html b/templates/pan/admin/bypass.html new file mode 100644 index 00000000..c284eff2 --- /dev/null +++ b/templates/pan/admin/bypass.html @@ -0,0 +1,74 @@ +{{define "templates/pan/admin/bypass.html"}} + {{template "templates/pan/admin/base.html" .}} +{{end}} +{{define "admin-bypass"}} +
    +
    +

    分流下载 多账号分流访问&下载

    +
    +
    + + + + + + + + + + {{- range $bp := $.config.BypassList}} + + + + + {{- end}} + +
    分流名称绑定网盘
    {{$bp.Name}} + {{- range $ac := $bp.Accounts}} +
    + {{$ac.Name}} +
    + {{- end}} +
    +
    +
    +
    +
    +
    +
    添加
    +
    + + + +
    用于替代访问路径中的网盘名称, 添加后DB缓存策略的网盘需重新缓存
    +
    + +
    + {{- range $.config.Accounts}} + + {{- end}} +
    +
    +
    + +
    +
    +
    +{{end}} \ No newline at end of file diff --git a/templates/pan/admin/cache.html b/templates/pan/admin/cache.html new file mode 100644 index 00000000..d7554233 --- /dev/null +++ b/templates/pan/admin/cache.html @@ -0,0 +1,78 @@ +{{define "templates/pan/admin/cache.html"}} + {{template "templates/pan/admin/base.html" .}} +{{end}} +{{define "admin-cache"}} +
    +
    +

    缓存管理 列表只展示部分信息,更详细的信息请使用搜索功能

    +
    +
    +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + {{- range $.cache}} + + + + + + + {{- end}} + +
    文件(夹)路径缓存策略缓存时间操作
    {{.FilePath}}{{.CachePolicy}}{{.CacheTime}} + + clear + + + pageview + +
    +
    +
    +
    +
    +
    +
    清理条件
    +
    + + +
    db缓存策略,清理后会重建
    +
    +
    + +
    + + +
    +
    +
    +
    + +
    +
    +
    +{{end}} \ No newline at end of file diff --git a/templates/pan/admin/common.html b/templates/pan/admin/common.html index 9e9912ea..13db27ee 100644 --- a/templates/pan/admin/common.html +++ b/templates/pan/admin/common.html @@ -1,5 +1,5 @@ -{{define "pan/admin/common.html"}} - {{template "pan/admin/base.html" .}} +{{define "templates/pan/admin/common.html"}} + {{template "templates/pan/admin/base.html" .}} {{end}} {{define "admin-common"}}
    @@ -7,31 +7,26 @@

    基础配置

    -
    - - -
    重启生效
    -
    -
    - - -
    重启生效
    -
    - +
    显示优先于网盘名称
    +
    + + +
    自定义后台地址,默认为/admin
    +
    @@ -39,26 +34,42 @@

    基础配置

    - +
    如果是第一次运行,请务必修改默认密码!
    -
    - - -
    +
    + +
    + + + +
    +
    +
    insert_link
    +
    + web + + +
    folder_open
    -
    - schedule - - -
    为空将关闭定时缓存,cron表达式在线生成
    -
    -
    - folder_open - - -
    定时任务只更新某个目录的缓存, 默认缓存全部
    -
    -
    +
    +
    + insert_link + + +
    为空将在本机中转, 多个,分隔
    +
    @@ -246,6 +263,51 @@

    网盘挂载 拖动头像修改显示顺序

    +
    +
    +
    +
    缓存配置
    +
    + + + +
    +
    + schedule + + +
    单位是小时
    +
    +
    + schedule + + +
    为空将关闭定时缓存,cron表达式在线生成
    +
    +
    + folder_open + + +
    定时任务只更新某个目录的缓存, 默认缓存全部
    +
    +
    + +
    +
    +
    + + +
    +
    +
    刷新缓存
    @@ -255,7 +317,7 @@

    网盘挂载 拖动头像修改显示顺序

    -
    这里是PanIndex的虚拟路径,不需要带盘符/d_0
    +
    PanIndex的虚拟路径,格式:/{name}/a/b
    @@ -278,7 +340,7 @@

    网盘挂载 拖动头像修改显示顺序

    -
    这里是PanIndex的虚拟路径,不需要带盘符/d_0
    +
    PanIndex的虚拟路径,格式:/{name}/a/b
    diff --git a/templates/pan/admin/hide.html b/templates/pan/admin/hide.html index 00b75381..c071c67f 100644 --- a/templates/pan/admin/hide.html +++ b/templates/pan/admin/hide.html @@ -1,5 +1,5 @@ -{{define "pan/admin/hide.html"}} - {{template "pan/admin/base.html" .}} +{{define "templates/pan/admin/hide.html"}} + {{template "templates/pan/admin/base.html" .}} {{end}} {{define "admin-hide"}}
    @@ -18,17 +18,15 @@

    隐藏文件(夹) 隐藏部分文件或文件夹

    - + - {{- if gt (len .HideFiles) 0 }} - {{- range .HideFiles}} + {{- range $filePath, $value := $.config.HideFiles}} - + {{- end}} - {{- end}}
    文件(夹)ID文件(夹)路径
    {{.}}{{$filePath}}
    @@ -37,16 +35,15 @@

    隐藏文件(夹) 隐藏部分文件或文件夹

    添加
    -
    folder_open - - -
    网盘中的原始文件ID,不同的网盘类型格式可能不同,获取方式
    + + +
    PanIndex的虚拟路径,格式:/{name}/a/b
    - +
    diff --git a/templates/pan/admin/login.html b/templates/pan/admin/login.html index fd574caf..ba36de94 100644 --- a/templates/pan/admin/login.html +++ b/templates/pan/admin/login.html @@ -1,10 +1,10 @@ -{{define "pan/admin/login.html"}} - {{template "pan/admin/base.html" .}} +{{define "templates/pan/admin/login.html"}} + {{template "templates/pan/admin/base.html" .}} {{end}} {{define "admin-login"}}
    -
    +

    登录

    https @@ -20,11 +20,10 @@

    登录

    {{end}} \ No newline at end of file diff --git a/templates/pan/admin/pwd.html b/templates/pan/admin/pwd.html index dbe7681f..769380b7 100644 --- a/templates/pan/admin/pwd.html +++ b/templates/pan/admin/pwd.html @@ -1,5 +1,5 @@ -{{define "pan/admin/pwd.html"}} - {{template "pan/admin/base.html" .}} +{{define "templates/pan/admin/pwd.html"}} + {{template "templates/pan/admin/base.html" .}} {{end}} {{define "admin-pwd"}}
    @@ -21,43 +21,39 @@

    密码文件(夹) 文件夹设置密码访问,设置后的文 - + - {{- if gt (len .PwdDirs) 0 }} - {{- range .PwdDirs}} + {{- range $filePath, $password := $.config.PwdFiles}} - - + + {{- end}} - {{- end}}
    文件(夹)ID文件(夹)路径 访问密码
    {{.FileId}}{{.Password}}{{$filePath}}{{$password}}

    - +
    添加
    -
    folder_open - - -
    网盘中的原始文件ID,不同的网盘类型格式可能不同,获取方式
    + + +
    PanIndex的虚拟路径,格式:/{name}/a/b
    lock_outline - +
    -
    - +
    diff --git a/templates/pan/admin/safety.html b/templates/pan/admin/safety.html index fcc66fb5..e3598a7c 100644 --- a/templates/pan/admin/safety.html +++ b/templates/pan/admin/safety.html @@ -1,5 +1,5 @@ -{{define "pan/admin/safety.html"}} - {{template "pan/admin/base.html" .}} +{{define "templates/pan/admin/safety.html"}} + {{template "templates/pan/admin/base.html" .}} {{end}} {{define "admin-safety"}}
    @@ -9,21 +9,21 @@

    防盗链 通过Referrer策略实现外链访问控制

    - -
    允许的 Referrer,英文,分隔,例:baidu.com,noki.icu
    + +
    允许的 Referrer,英文,分隔,例:baidu.com,google.com,^[a-zA-Z0-9_]{1,10}\.xxxx\.com
    diff --git a/templates/pan/admin/view.html b/templates/pan/admin/view.html index d1bbcdec..ba487ba7 100644 --- a/templates/pan/admin/view.html +++ b/templates/pan/admin/view.html @@ -1,5 +1,5 @@ -{{define "pan/admin/view.html"}} - {{template "pan/admin/base.html" .}} +{{define "templates/pan/admin/view.html"}} + {{template "templates/pan/admin/base.html" .}} {{end}} {{define "admin-view"}}
    @@ -10,33 +10,33 @@

    文件预览 多个后缀名,半角英文逗号分隔

    - +
    - +
    - +
    - +
    - +
    - +
    这部分文件不支持预览, 但是也可以跳转到预览页
    diff --git a/templates/pan/admin/webdav.html b/templates/pan/admin/webdav.html new file mode 100644 index 00000000..9a9b23c6 --- /dev/null +++ b/templates/pan/admin/webdav.html @@ -0,0 +1,78 @@ +{{define "templates/pan/admin/webdav.html"}} + {{template "templates/pan/admin/base.html" .}} +{{end}} +{{define "admin-webdav"}} +
    +
    +

    WebDav 可通过RaiDrive等工具挂载成本地磁盘

    +
    + +
    + + +
    +
    + link + + +
    请求路径,开启后密码文件将无需授权,重启生效
    +
    +
    + chrome_reader_mode + +
    + + +
    +
    +
    + cloud_download + +
    + + +
    +
    +
    + account_circle + + +
    +
    + lock + + +
    默认密码:1234
    +
    +
    +
    + +
    +
    + +
    +{{end}} \ No newline at end of file diff --git a/templates/pan/bootstrap/index.html b/templates/pan/bootstrap/index.html index 352d7cc6..860737d1 100644 --- a/templates/pan/bootstrap/index.html +++ b/templates/pan/bootstrap/index.html @@ -2,29 +2,22 @@ - {{if eq $.Config.SiteName ""}} - {{.Title}} - {{else}} - {{$.Config.SiteName}} - {{end}} {{ .Path }} + {{$.title}} {{ $.path }} - {{if eq .Mode "aliyundrive"}} + {{- if eq $.account.Mode "aliyundrive"}} - {{end}} - {{if ne .FaviconUrl ""}} - - - {{else}} - - - {{end}} - - - - - - - + + + + + + + + + + + + + + + - {{ $SurportFolderDown := .SurportFolderDown }} - {{if .HasPwd}} - - {{else}} + {{- if $.has_pwd}} + + + + {{- else}}
    - +
    @@ -135,71 +132,52 @@ - {{if .HasParent}} + {{- if .has_parent}} - {{else}} {{end}} - {{range .List}} + {{range $.fns}} - {{if .IsFolder}} - - {{else}} - - {{end}} + {{- if .IsFolder}} + + {{- else}} + + {{- end}} - {{if .IsFolder}} - {{if and (ne .FileId "0") (ne .FileId "-12") (ne .FileId "-14") (ne .FileId "-13") (ne .FileId "-15") (ne .FileId "-11") (ne .FileId "-16") ($SurportFolderDown)}} - - {{else}} - - {{end}} - {{else}} - - {{end}} + - {{end}} + {{- end}}
    Name
    -   .. +   ..
    -   {{.FileName}} - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    - {{if eq .MediaType 1}} - - {{else if eq .MediaType 2}} - - {{else if eq .MediaType 3}} - - {{else if eq .MediaType 4}} - {{if or (eq .FileType "sh") (eq .FileType "go") (eq .FileType "java") (eq .FileType "py")}} - - {{else}} - - {{end}} - {{else}} - {{if eq .FileType "apk"}} - - {{else if eq .FileType "exe"}} - - {{else if or (eq .FileType "zip") (eq .FileType "gz") (eq .FileType "7z")}} - - {{else}} - - {{end}} - {{end}} -   {{.FileName}} - - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    + +   {{.FileName}} + + {{- if $.search_key}} +

    {{.Path}}

    + {{- end}} +
    + + +   {{.FileName}} + + {{- if $.search_key}} +

    {{.Path}}

    + {{- end}} +
    {{.SizeFmt}} {{.LastOpTime}}- + + + + {{- if not .IsFolder}} + + + + {{- end}} +
    @@ -211,7 +189,7 @@
    - +

    - - - - \ No newline at end of file diff --git a/templates/pan/cdn/admin/appearance.html b/templates/pan/cdn/admin/appearance.html deleted file mode 100644 index e3a00df3..00000000 --- a/templates/pan/cdn/admin/appearance.html +++ /dev/null @@ -1,46 +0,0 @@ -{{define "pan/admin/appearance.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-appearance"}} -
    -
    -

    外观

    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    - -
    -
    -
    -
    -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/admin/base.html b/templates/pan/cdn/admin/base.html deleted file mode 100644 index 20e797a4..00000000 --- a/templates/pan/cdn/admin/base.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - 系统配置 - PanIndex - {{- if ne .FaviconUrl ""}} - - - {{- else}} - - - {{- end}} - - - - - - - - -
    - -
    -{{- if ne .RedirectUrl "login"}} -
    -
    -
    -
    - settings -
    通用
    keyboard_arrow_down -
    - -
    -
    -
    - security -
    安全
    keyboard_arrow_down -
    - -
    - - storage -
    网盘挂载
    -
    -
    - -
    -{{- end}} -
    - {{- if eq .RedirectUrl "common"}} - {{block "admin-common" .}}{{end}} - {{- else if eq .RedirectUrl "appearance"}} - {{block "admin-appearance" .}}{{end}} - {{- else if eq .RedirectUrl "security"}} - {{block "admin-security" .}}{{end}} - {{- else if eq .RedirectUrl "view"}} - {{block "admin-view" .}}{{end}} - {{- else if eq .RedirectUrl "login"}} - {{block "admin-login" .}}{{end}} - {{- else if eq .RedirectUrl "pwd"}} - {{block "admin-pwd" .}}{{end}} - {{- else if eq .RedirectUrl "hide"}} - {{block "admin-hide" .}}{{end}} - {{- else if eq .RedirectUrl "safety"}} - {{block "admin-safety" .}}{{end}} - {{- else if eq .RedirectUrl "disk"}} - {{block "admin-disk" .}}{{end}} - {{- else}} - {{- end}} -
    - - - - - diff --git a/templates/pan/cdn/admin/common.html b/templates/pan/cdn/admin/common.html deleted file mode 100644 index 9e9912ea..00000000 --- a/templates/pan/cdn/admin/common.html +++ /dev/null @@ -1,71 +0,0 @@ -{{define "pan/admin/common.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-common"}} -
    -
    -

    基础配置

    -
    -
    -
    - - -
    重启生效
    -
    -
    - - -
    重启生效
    -
    -
    - - -
    显示优先于网盘名称
    -
    -
    - -
    - - -
    -
    -
    - - -
    如果是第一次运行,请务必修改默认密码!
    -
    -
    - - -
    -
    - - - -
    -
    -
    - -
    -
    -
    -
    -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/admin/disk.html b/templates/pan/cdn/admin/disk.html deleted file mode 100644 index 73e55092..00000000 --- a/templates/pan/cdn/admin/disk.html +++ /dev/null @@ -1,291 +0,0 @@ -{{define "pan/admin/disk.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-disk"}} -
    -
    -

    网盘挂载 拖动头像修改显示顺序

    -
    -
    - - - - - - - - - - - - - - - {{- if gt (len .Config.Accounts) 0 }} - {{- range .Config.Accounts}} - - - - - - - - - - {{- end}} - {{- end}} - -
    网盘名称网盘类型登录状态缓存状态文件总数上一次缓存耗时
    -
    - {{- if eq .Mode "cloud189"}} - face - {{- else if eq .Mode "teambition-us"}} - face - {{- else if eq .Mode "teambition"}} - face - {{- else if eq .Mode "onedrive"}} - face - {{- else if eq .Mode "onedrive-cn"}} - face - {{- else if eq .Mode "native"}} - face - {{- else if eq .Mode "aliyundrive"}} - face - {{- else if eq .Mode "ftp"}} - face - {{- else if eq .Mode "webdav"}} - face - {{- else if eq .Mode "yun139"}} - face - {{- else if eq .Mode "googledrive"}} - face - {{- else}} - {{- end}} - {{.Name}} -
    -
    - {{- if eq .Mode "native"}} - 本地磁盘 - {{- else if eq .Mode "cloud189"}} - 天翼云盘 - {{- else if eq .Mode "aliyundrive"}} - 阿里云盘 - {{- else if eq .Mode "onedrive"}} - 微软云盘 - {{- else if eq .Mode "onedrive-cn"}} - 世纪互联 - {{- else if eq .Mode "teambition"}} - Teambition项目盘 - {{- else if eq .Mode "teambition-us"}} - Teambition国际服 - {{- else if eq .Mode "ftp"}} - FTP - {{- else if eq .Mode "webdav"}} - WebDav - {{- else if eq .Mode "yun139"}} - 和彩云 - {{- else if eq .Mode "googledrive"}} - 谷歌云盘 - {{- else}} - {{- end}} - - {{- if eq .Mode "native"}} - - - {{- else}} - {{- if eq .CookieStatus 1}} - 未刷新 - {{- else if eq .CookieStatus 2}} - 正常 - {{- else if eq .CookieStatus 3}} - 失效 - {{- else if eq .CookieStatus 4}} - 登录失败 - {{- else if eq .CookieStatus -1}} - 刷新中 - {{- else}} - 未知 - {{- end}} - {{- end}} - - {{- if eq .Mode "native"}} - - - {{- else}} - {{- if eq .Status 1}} - 未缓存 - {{- else if eq .Status 2}} - 缓存成功 - {{- else if eq .Status 3}} - 缓存失败 - {{- else if eq .Status -1}} - 缓存中 - {{- else}} - 未知 - {{- end}} - {{- end}} - - {{- if eq .Mode "native"}} - - - {{- else}} - {{.FilesCount}} - {{- end}} - - {{- if eq .Mode "native"}} - - - {{- else}} - {{.LastOpTime}} - {{- end}} - - {{- if eq .Mode "native"}} - - - {{- else}} - {{.TimeSpan}} - {{- end}} -
    -
    -
    -
    -
    -
    添加
    -
    -
    - message - - - - -
    -
    - - -
    -
    - account_circle - - -
    -
    - lock - - -
    -
    - insert_link - - -
    -
    - refresh - - -
    -
    - insert_link - - -
    -
    - folder_open - - - -
    -
    - schedule - - -
    为空将关闭定时缓存,cron表达式在线生成
    -
    -
    - folder_open - - -
    定时任务只更新某个目录的缓存, 默认缓存全部
    -
    -
    - -
    -
    -
    -
    - - -
    -
    -
    -
    -
    刷新缓存
    -
    -
    - folder_open - - - -
    这里是PanIndex的虚拟路径,不需要带盘符/d_0
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    文件上传
    -
    -
    - - -
    -
    - folder_open - - - -
    这里是PanIndex的虚拟路径,不需要带盘符/d_0
    -
    -
    -
    -
    - - - -
    -
    -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/admin/hide.html b/templates/pan/cdn/admin/hide.html deleted file mode 100644 index 00b75381..00000000 --- a/templates/pan/cdn/admin/hide.html +++ /dev/null @@ -1,53 +0,0 @@ -{{define "pan/admin/hide.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-hide"}} -
    -
    -

    隐藏文件(夹) 隐藏部分文件或文件夹

    -
    -
    - - - - - - - - - {{- if gt (len .HideFiles) 0 }} - {{- range .HideFiles}} - - - - {{- end}} - {{- end}} - -
    文件(夹)ID
    {{.}}
    -
    -
    -
    -
    -
    -
    添加
    - -
    - folder_open - - -
    网盘中的原始文件ID,不同的网盘类型格式可能不同,获取方式
    -
    -
    -
    - -
    -
    -
    -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/admin/login.html b/templates/pan/cdn/admin/login.html deleted file mode 100644 index fd574caf..00000000 --- a/templates/pan/cdn/admin/login.html +++ /dev/null @@ -1,30 +0,0 @@ -{{define "pan/admin/login.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-login"}} -
    -
    -
    -

    登录

    -
    - https - - -
    -
    - -
    -
    -
    - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/admin/pwd.html b/templates/pan/cdn/admin/pwd.html deleted file mode 100644 index dbe7681f..00000000 --- a/templates/pan/cdn/admin/pwd.html +++ /dev/null @@ -1,64 +0,0 @@ -{{define "pan/admin/pwd.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-pwd"}} -
    -
    -

    密码文件(夹) 文件夹设置密码访问,设置后的文件将无法被搜索到

    -
    -
    - - - - - - - - - - {{- if gt (len .PwdDirs) 0 }} - {{- range .PwdDirs}} - - - - - {{- end}} - {{- end}} - -
    文件(夹)ID访问密码
    {{.FileId}}{{.Password}}
    -
    -
    -
    -
    -
    -
    添加
    - -
    - folder_open - - -
    网盘中的原始文件ID,不同的网盘类型格式可能不同,获取方式
    -
    -
    - lock_outline - - -
    - -
    -
    - -
    -
    -
    -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/admin/safety.html b/templates/pan/cdn/admin/safety.html deleted file mode 100644 index fcc66fb5..00000000 --- a/templates/pan/cdn/admin/safety.html +++ /dev/null @@ -1,41 +0,0 @@ -{{define "pan/admin/safety.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-safety"}} -
    -
    -

    防盗链 通过Referrer策略实现外链访问控制

    -
    -
    -
    - - -
    允许的 Referrer,英文,分隔,例:baidu.com,noki.icu
    -
    -
    - -
    - - -
    -
    -
    -
    - -
    -
    -
    -
    -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/admin/view.html b/templates/pan/cdn/admin/view.html deleted file mode 100644 index d1bbcdec..00000000 --- a/templates/pan/cdn/admin/view.html +++ /dev/null @@ -1,54 +0,0 @@ -{{define "pan/admin/view.html"}} - {{template "pan/admin/base.html" .}} -{{end}} -{{define "admin-view"}} -
    -
    -

    文件预览 多个后缀名,半角英文逗号分隔

    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    这部分文件不支持预览, 但是也可以跳转到预览页
    -
    -
    -
    - - -
    -
    -
    -
    -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/bootstrap/index.html b/templates/pan/cdn/bootstrap/index.html deleted file mode 100644 index 352d7cc6..00000000 --- a/templates/pan/cdn/bootstrap/index.html +++ /dev/null @@ -1,274 +0,0 @@ - - - - - {{if eq $.Config.SiteName ""}} - {{.Title}} - {{else}} - {{$.Config.SiteName}} - {{end}} {{ .Path }} - - - - {{if eq .Mode "aliyundrive"}} - - {{end}} - {{if ne .FaviconUrl ""}} - - - {{else}} - - - {{end}} - - - - - - - - - - {{ $SurportFolderDown := .SurportFolderDown }} - {{if .HasPwd}} - - {{else}} - -
    -
    -
    - - - - - - - - - - - {{if .HasParent}} - - - - - - - {{else}} - {{end}} - {{range .List}} - - {{if .IsFolder}} - - {{else}} - - {{end}} - - - {{if .IsFolder}} - {{if and (ne .FileId "0") (ne .FileId "-12") (ne .FileId "-14") (ne .FileId "-13") (ne .FileId "-15") (ne .FileId "-11") (ne .FileId "-16") ($SurportFolderDown)}} - - {{else}} - - {{end}} - {{else}} - - {{end}} - - {{end}} - -
    NameSizeDate ModifiedDownload
    -   .. -
    -   {{.FileName}} - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    - {{if eq .MediaType 1}} - - {{else if eq .MediaType 2}} - - {{else if eq .MediaType 3}} - - {{else if eq .MediaType 4}} - {{if or (eq .FileType "sh") (eq .FileType "go") (eq .FileType "java") (eq .FileType "py")}} - - {{else}} - - {{end}} - {{else}} - {{if eq .FileType "apk"}} - - {{else if eq .FileType "exe"}} - - {{else if or (eq .FileType "zip") (eq .FileType "gz") (eq .FileType "7z")}} - - {{else}} - - {{end}} - {{end}} -   {{.FileName}} - - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    {{.SizeFmt}}{{.LastOpTime}}-
    -
    - {{if .HasReadme}} -
    -
    -
    - README.md -
    -
    - - -

    -

    - -
    -
    -
    - {{else}} - {{end}} -
    -
    -
    - {{if eq $.Footer ""}} - ©2021 PanIndex. All rights reserved. - {{else}} - {{.Footer | unescaped}} - {{end}} -
    -
    -
    -
    - {{end}} -
    -
    - -
    - - - - - - - \ No newline at end of file diff --git a/templates/pan/cdn/classic/index.html b/templates/pan/cdn/classic/index.html deleted file mode 100644 index 02fb6019..00000000 --- a/templates/pan/cdn/classic/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - {{.Title}} {{ .Path }} - -{{if eq .Mode "aliyundrive"}} - -{{end}} - -{{if ne .FaviconUrl ""}} - - -{{else}} - - -{{end}} - - - - - - -{{ $SurportFolderDown := .SurportFolderDown }} -

    {{.Title}} {{ .Path }}

    - -{{if .HasPwd}} - - -{{else}} - - - - - - - - - - - {{if .HasParent}} - - - - - - {{else}} - {{end}} - {{range .List}} - - {{if .IsFolder}} - - {{else}} - - {{end}} - - - {{if .IsFolder}} - {{if and (ne .FileId "0") (ne .FileId "-12") (ne .FileId "-14") (ne .FileId "-13") (ne .FileId "-15") (ne .FileId "-11") (ne .FileId "-16") ($SurportFolderDown)}} - - {{else}} - - {{end}} - {{else}} - - {{end}} - - {{end}} - -
    NameSizeDate ModifiedDownload
    - .. -
    {{.FileName}}{{.FileName}}{{.SizeFmt}}{{.LastOpTime}}-
    - -
    -{{end}} -
    - - - - - - - \ No newline at end of file diff --git a/templates/pan/cdn/materialdesign/index.html b/templates/pan/cdn/materialdesign/index.html deleted file mode 100644 index e0b8421f..00000000 --- a/templates/pan/cdn/materialdesign/index.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - {{if eq $.Config.SiteName ""}} - {{.Title}} - {{else}} - {{$.Config.SiteName}} - {{end}} {{ .Path }} - - - - {{if eq .Mode "aliyundrive"}} - - {{end}} - {{if ne .FaviconUrl ""}} - - - {{else}} - - - {{end}} - - - - - - - - - - - {{ $SurportFolderDown := .SurportFolderDown }} - {{if .HasPwd}} - - {{else}} -
    -
    - {{/*
    -

    {{.Title}} {{ .Path }}

    -
    */}} - - -
    -
    -
    - - - - - - - - - - - {{if .HasParent}} - - - - - - - {{else}} - {{end}} - {{range .List}} - - {{if .IsFolder}} - - {{else}} - - {{end}} - - - {{if .IsFolder}} - {{if and (ne .FileId "0") (ne .FileId "-12") (ne .FileId "-14") (ne .FileId "-13") (ne .FileId "-15") (ne .FileId "-11") (ne .FileId "-16") ($SurportFolderDown)}} - - {{else}} - - {{end}} - {{else}} - - {{end}} - - {{end}} - -
    NameSizeDate ModifiedDownload
    -   .. -
    -   {{.FileName}} - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    - {{if eq .MediaType 1}} - - {{else if eq .MediaType 2}} - - {{else if eq .MediaType 3}} - - {{else if eq .MediaType 4}} - {{if or (eq .FileType "sh") (eq .FileType "go") (eq .FileType "java") (eq .FileType "py")}} - - {{else}} - - {{end}} - {{else}} - {{if eq .FileType "apk"}} - - {{else if eq .FileType "exe"}} - - {{else if or (eq .FileType "zip") (eq .FileType "gz") (eq .FileType "7z")}} - - {{else}} - - {{end}} - {{end}} -   {{.FileName}} - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    {{.SizeFmt}}{{.LastOpTime}}-
    -
    - {{if .HasReadme}} -
    -
    -
    - - -
    - -
    -
    -
    - {{end}} -
    - -
    -
    - {{end}} -
    - - - - - - - - \ No newline at end of file diff --git a/templates/pan/cdn/mdui/index.html b/templates/pan/cdn/mdui/index.html deleted file mode 100644 index 23d1e035..00000000 --- a/templates/pan/cdn/mdui/index.html +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - -{{- if or (eq .Mode "aliyundrive") (.SearchKey)}} - -{{- end}} - - -{{- if ne .FaviconUrl ""}} - - -{{- else}} - - -{{- end}} - - - - - - - - - -{{- if ne .Config.Css ""}} - {{.Config.Css | unescaped}} -{{- end}} - {{- if eq $.Config.SiteName ""}} - {{.Title}} - {{- else}} - {{$.Config.SiteName}} - {{- end}} {{ .Path }} - - {{ $SurportFolderDown := .SurportFolderDown }} - - -
    -
    -
    -
    -
    - home - {{- if gt (len .Accounts) 1 }} -
      - {{range $i, $a := .Accounts}} -
    • - face{{.Name}} -
    • - {{- end}} -
    - {{- end}} - - {{- if eq $.Config.SiteName ""}} - {{.Title}} - {{- else}} - {{$.Config.SiteName}} - {{- end}} - -
    - {{- if and (eq $.Config.AccountChoose "display") (or (ne $.Path "/") (ne $.DIndex ""))}} - chevron_right -
    - {{.Title}} -
    - {{- end}} - {{- range .PrePaths}} - chevron_right -
    - {{.PathName}} -
    - {{- end}} -
    - {{- if and (.HasHead) (not .HasPwd)}} - - {{- end}} -
      -
    • -
      -
      -
      - - - -
      -
      - {{- if and (eq $.Config.AccountChoose "display") (and (eq $.Path "/") (ne $.DIndex ""))}} - - {{- end}} - {{- if .HasParent}} - - {{- end}} - - - - {{- if .HasParent}} - share -
        -
      • -
      • - -
      • -
      • -
      • - -
      • -
      - {{- end}} - - -
      -
      -
      -
    • - {{- if .HasPwd}} -
      -
      - lock - - - - fingerprint - - {{- if .PwdErrorMsg}} -
      {{.PwdErrorMsg}}
      - - {{- end}} -
      -
      - {{- else}} - {{- if not .List}} -
      -
      - -

      网盘空空如也

      -
      -
      - {{- end}} - {{- range .List}} -
    • -
      -
      - {{- if .IsFolder}} - folder_open {{.FileName}} - {{- if and (ne .FileId "0") (ne .FileId "-12") (ne .FileId "-14") (ne .FileId "-13") (ne .FileId "-15") (ne .FileId "-11") (ne .FileId "-16") ($SurportFolderDown)}} - file_download - {{- else}} - {{- end}} - {{- else}} - - {{- if eq .MediaType 1}} - image - {{- else if eq .MediaType 2}} - audiotrack - {{- else if eq .MediaType 3}} - ondemand_video - {{- else if eq .MediaType 4}} - {{- if or (eq .FileType "sh") (eq .FileType "go") (eq .FileType "java") (eq .FileType "py")}} - code - {{- else}} - description - {{- end}} - {{- else}} - {{- if eq .FileType "apk"}} - android - {{- else if eq .FileType "exe"}} - apps - {{- else if or (eq .FileType "zip") (eq .FileType "gz") (eq .FileType "7z")}} - archive - {{- else}} - insert_drive_file - {{- end}} - {{- end}} - {{.FileName}} content_copy - file_download - {{- end}} -
      - {{- if .IsFolder}} - {{- else}} -
      - {{.SizeFmt}} / {{.LastOpTime}} -
      - {{- end}} - {{- if $.SearchKey}} -
      - {{index $.AcountIndex .AccountId }}{{.Path}} -
      - {{- end}} -
      -
    • - {{- end}} - {{- end}} -
    -
    - {{- if and (.HasReadme) (not .HasPwd)}} - - {{- else}} - {{- end}} - -
    - {{- if not .HasPwd}} - vertical_align_top - {{- end}} -
    - {{- if eq $.Footer ""}} - ©2021 PanIndex. All rights reserved. - {{- else}} - {{.Footer | unescaped}} - {{- end}} -
    -
    - - - -{{- if ne .Config.Js ""}} -{{.Config.Js | unescaped}} -{{- end}} - - \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-audio.html b/templates/pan/cdn/mdui/view-audio.html deleted file mode 100644 index 56398843..00000000 --- a/templates/pan/cdn/mdui/view-audio.html +++ /dev/null @@ -1,78 +0,0 @@ -{{define "pan/mdui/view-audio.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-audio"}} - -
    -
    -
    - - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-base.html b/templates/pan/cdn/mdui/view-base.html deleted file mode 100644 index f91dfabc..00000000 --- a/templates/pan/cdn/mdui/view-base.html +++ /dev/null @@ -1,202 +0,0 @@ -{{define "pan/mdui/view-base.html"}} - - - - - - -{{- if eq .Mode "aliyundrive"}} - -{{- end}} - - -{{- if ne .FaviconUrl ""}} - - -{{- else}} - - -{{- end}} - - - - - - -{{- if ne .Config.Css ""}} - {{.Config.Css | unescaped}} -{{- end}} - {{- if eq $.Config.SiteName ""}} - {{.Title}} - {{- else}} - {{$.Config.SiteName}} - {{- end}} {{ .Path }} - - {{ $SurportFolderDown := .SurportFolderDown }} - - -
    -
    -
    -
    -
    - home - {{- if gt (len .Accounts) 1 }} -
      - {{- range $i, $a := .Accounts}} -
    • - face{{.Name}} -
    • - {{- end}} -
    - {{- end}} - - {{- if eq $.Config.SiteName ""}} - {{.Title}} - {{- else}} - {{$.Config.SiteName}} - {{- end}} - -
    - {{- if and (eq $.Config.AccountChoose "display") (or (ne $.Path "/") (ne $.DIndex ""))}} - chevron_right -
    - {{.Title}} -
    - {{- end}} - {{- range .PrePaths}} - chevron_right -
    - {{.PathName}} - {{.PathName}} -
    - {{- end}} -
    -
      -
    • -
      -
      - {{- if .HasParent}} - - {{- end}} - {{- if .HasPwd}}{{- else}}info{{- end}} - {{- if .HasPwd}}{{- else}}share{{- end}} - {{- if .HasPwd}}{{- else}}file_download{{- end}} - {{- if .LastFile }} - chevron_leftt - {{- end}} - {{- if .NextFile }} - chevron_right - {{- end}} - -
        -
      • -
      • - -
      • -
      • -
      • - -
      • -
      -
      -
      -
    • -
    -
    - {{- if .HasPwd}} -
    -
    - lock - - - - fingerprint - - {{- if .PwdErrorMsg}} -
    {{.PwdErrorMsg}}
    - - {{- end}} -
    -
    - {{- else}} -
    -
    -
    -
    名称:{{ (index .List 0).FileName }}
    -
    大小:{{ (index .List 0).SizeFmt }}
    -
    日期:{{ (index .List 0).LastOpTime }}
    -
    文件ID:{{ (index .List 0).FileId }} content_copy
    -
    目录ID:{{ (index .List 0).ParentId }} content_copy
    -
    链接:
    -
    -
    -
    -
    - {{- if (index .List 0).FileType}} - {{- if contains $.Config.Image (index .List 0).FileType}} - {{block "content-img" .}}{{end}} - {{- else if contains $.Config.Audio (index .List 0).FileType}} - {{block "content-audio" .}}{{end}} - {{- else if contains $.Config.Video (index .List 0).FileType}} - {{block "content-video" .}}{{end}} - {{- else if contains $.Config.Code (index .List 0).FileType}} - {{block "content-code" .}}{{end}} - {{- else if contains $.Config.Doc (index .List 0).FileType}} - {{block "content-office" .}}{{end}} - {{- else if eq "pdf" (index .List 0).FileType}} - {{block "content-pdf" .}}{{end}} - {{- else if eq "epub" (index .List 0).FileType}} - {{block "content-epub" .}}{{end}} - {{- else if eq "md" (index .List 0).FileType}} - {{block "content-md" .}}{{end}} - {{- else}} - {{block "content-ns" .}}{{end}} - {{- end}} - {{- else}} - {{block "content-ns" .}}{{end}} - {{- end}} -
    - {{- end}} - -
    -
    -
    -
    - {{- if eq $.Footer ""}} - ©2021 PanIndex. All rights reserved. - {{- else}} - {{.Footer | unescaped}} - {{- end}} -
    -
    - - -{{- if ne .Config.Js ""}} -{{.Config.Js | unescaped}} -{{- end}} - - -{{end}} diff --git a/templates/pan/cdn/mdui/view-code.html b/templates/pan/cdn/mdui/view-code.html deleted file mode 100644 index 4d362dd4..00000000 --- a/templates/pan/cdn/mdui/view-code.html +++ /dev/null @@ -1,44 +0,0 @@ -{{define "pan/mdui/view-code.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-code"}} - - - - -
    - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-epub.html b/templates/pan/cdn/mdui/view-epub.html deleted file mode 100644 index 98ae77f2..00000000 --- a/templates/pan/cdn/mdui/view-epub.html +++ /dev/null @@ -1,143 +0,0 @@ -{{define "pan/mdui/view-epub.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-epub"}} -
    - -
    - - -
    - - - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-img.html b/templates/pan/cdn/mdui/view-img.html deleted file mode 100644 index 2a86f8ac..00000000 --- a/templates/pan/cdn/mdui/view-img.html +++ /dev/null @@ -1,16 +0,0 @@ -{{define "pan/mdui/view-img.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-img"}} -
    - -
    - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-md.html b/templates/pan/cdn/mdui/view-md.html deleted file mode 100644 index fb76d8a8..00000000 --- a/templates/pan/cdn/mdui/view-md.html +++ /dev/null @@ -1,21 +0,0 @@ -{{define "pan/mdui/view-md.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-md"}} -
    - -
    - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-ns.html b/templates/pan/cdn/mdui/view-ns.html deleted file mode 100644 index 71cb842c..00000000 --- a/templates/pan/cdn/mdui/view-ns.html +++ /dev/null @@ -1,18 +0,0 @@ -{{define "pan/mdui/view-ns.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-ns"}} -
    -
    - 该文件格式不支持预览 - -
    -
    - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-office.html b/templates/pan/cdn/mdui/view-office.html deleted file mode 100644 index 10991810..00000000 --- a/templates/pan/cdn/mdui/view-office.html +++ /dev/null @@ -1,14 +0,0 @@ -{{define "pan/mdui/view-office.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-office"}} - - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-pdf.html b/templates/pan/cdn/mdui/view-pdf.html deleted file mode 100644 index 7b2c7b14..00000000 --- a/templates/pan/cdn/mdui/view-pdf.html +++ /dev/null @@ -1,22 +0,0 @@ -{{define "pan/mdui/view-pdf.html"}} - {{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-pdf"}} - -
    - - - - - -{{end}} \ No newline at end of file diff --git a/templates/pan/cdn/mdui/view-video.html b/templates/pan/cdn/mdui/view-video.html deleted file mode 100644 index 9df6defd..00000000 --- a/templates/pan/cdn/mdui/view-video.html +++ /dev/null @@ -1,116 +0,0 @@ -{{define "pan/mdui/view-video.html"}} -{{template "pan/mdui/view-base.html" .}} -{{end}} -{{define "content-video"}} -{{- if eq .Mode "aliyundrive"}} - -{{- end}} -
    - - - - -{{end}} \ No newline at end of file diff --git a/templates/pan/classic/index.html b/templates/pan/classic/index.html index 02fb6019..e536a5aa 100644 --- a/templates/pan/classic/index.html +++ b/templates/pan/classic/index.html @@ -1,11 +1,12 @@ - + - {{.Title}} {{ .Path }} -{{if eq .Mode "aliyundrive"}} + + {{$.title}} {{ $.path }} + {{- if eq $.account.Mode "aliyundrive"}} -{{end}} + {{- end}} -{{if ne .FaviconUrl ""}} - - -{{else}} - - -{{end}} - - - - + {{- if ne $.config.FaviconUrl ""}} + + + {{- else}} + + + {{- end}} + + + + + + + + + + + + + + -{{ $SurportFolderDown := .SurportFolderDown }} -

    {{.Title}} {{ .Path }}

    +

    {{$.title}} {{ $.path }}

    -{{if .HasPwd}} - +{{- if $.has_pwd}} + + -{{else}} +{{- else}} @@ -51,52 +58,58 @@

    {{.Title}} {{ .Path }}

    - {{if .HasParent}} - - - - - - {{else}} - {{end}} - {{range .List}} - - {{if .IsFolder}} - - {{else}} - - {{end}} - - - {{if .IsFolder}} - {{if and (ne .FileId "0") (ne .FileId "-12") (ne .FileId "-14") (ne .FileId "-13") (ne .FileId "-15") (ne .FileId "-11") (ne .FileId "-16") ($SurportFolderDown)}} - - {{else}} - - {{end}} - {{else}} - - {{end}} - - {{end}} + {{- if $.has_parent}} + + + + + + {{- end}} + {{- range $.fns}} + + {{- if .IsFolder}} + + {{- else}} + + {{- end}} + + + + + {{- end}}
    - .. -
    {{.FileName}}{{.FileName}}{{.SizeFmt}}{{.LastOpTime}}-
    + .. +
    + + {{.FileName}} + + + + {{.FileName}} + + {{.SizeFmt}}{{.LastOpTime}} + + + + {{- if not .IsFolder}} + + + + {{- end}} +
    +

    + {{- if eq $.config.Footer ""}} + ©2021 PanIndex. All rights reserved. + {{- else}} + {{$.config.Footer | unescaped}} + {{- end}} +

    + {{end}}
    - - - - - \ No newline at end of file diff --git a/templates/pan/materialdesign/index.html b/templates/pan/materialdesign/index.html deleted file mode 100644 index e0b8421f..00000000 --- a/templates/pan/materialdesign/index.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - {{if eq $.Config.SiteName ""}} - {{.Title}} - {{else}} - {{$.Config.SiteName}} - {{end}} {{ .Path }} - - - - {{if eq .Mode "aliyundrive"}} - - {{end}} - {{if ne .FaviconUrl ""}} - - - {{else}} - - - {{end}} - - - - - - - - - - - {{ $SurportFolderDown := .SurportFolderDown }} - {{if .HasPwd}} - - {{else}} -
    -
    - {{/*
    -

    {{.Title}} {{ .Path }}

    -
    */}} - - -
    -
    -
    - - - - - - - - - - - {{if .HasParent}} - - - - - - - {{else}} - {{end}} - {{range .List}} - - {{if .IsFolder}} - - {{else}} - - {{end}} - - - {{if .IsFolder}} - {{if and (ne .FileId "0") (ne .FileId "-12") (ne .FileId "-14") (ne .FileId "-13") (ne .FileId "-15") (ne .FileId "-11") (ne .FileId "-16") ($SurportFolderDown)}} - - {{else}} - - {{end}} - {{else}} - - {{end}} - - {{end}} - -
    NameSizeDate ModifiedDownload
    -   .. -
    -   {{.FileName}} - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    - {{if eq .MediaType 1}} - - {{else if eq .MediaType 2}} - - {{else if eq .MediaType 3}} - - {{else if eq .MediaType 4}} - {{if or (eq .FileType "sh") (eq .FileType "go") (eq .FileType "java") (eq .FileType "py")}} - - {{else}} - - {{end}} - {{else}} - {{if eq .FileType "apk"}} - - {{else if eq .FileType "exe"}} - - {{else if or (eq .FileType "zip") (eq .FileType "gz") (eq .FileType "7z")}} - - {{else}} - - {{end}} - {{end}} -   {{.FileName}} - {{if $.SearchKey}} -

    {{index $.AcountIndex .AccountId }}{{.Path}}

    - {{end}} -
    {{.SizeFmt}}{{.LastOpTime}}-
    -
    - {{if .HasReadme}} -
    -
    -
    - - -
    - -
    -
    -
    - {{end}} -
    - -
    -
    - {{end}} -
    - - - - - - - - \ No newline at end of file diff --git a/templates/pan/mdui/index.html b/templates/pan/mdui/index.html index 09b62134..cdbe1e5f 100644 --- a/templates/pan/mdui/index.html +++ b/templates/pan/mdui/index.html @@ -4,106 +4,93 @@ -{{- if or (eq .Mode "aliyundrive") (.SearchKey)}} +{{- if or (eq $.account.Mode "aliyundrive") ($.search_key)}} {{- end}} -{{- if ne .FaviconUrl ""}} - - +{{- if ne $.config.FaviconUrl ""}} + + {{- else}} - - + + {{- end}} - - - - - - - - - - - -{{- if ne .Config.Css ""}} - {{.Config.Css | unescaped}} + + + + + + + + + + + {{- if ne $.config.Js ""}} + {{$.config.Js | unescaped}} + {{- end}} + +{{- if ne $.config.Css ""}} + {{$.config.Css | unescaped}} {{- end}} - {{- if eq $.Config.SiteName ""}} - {{.Title}} + <title>{{- if eq $.config.SiteName ""}} + {{$.title}} {{- else}} - {{$.Config.SiteName}} + {{$.config.SiteName}} {{- end}} {{ .Path }} - {{ $SurportFolderDown := .SurportFolderDown }} - +
    -
    +
    - home - {{- if gt (len .Accounts) 1 }} + home + {{- if gt (len $.accounts) 1 }} {{- end}} - - {{- if eq $.Config.SiteName ""}} - {{.Title}} + + {{- if eq $.config.SiteName ""}} + {{$.title}} {{- else}} - {{$.Config.SiteName}} + {{$.config.SiteName}} {{- end}}
    - {{- if and (eq $.Config.AccountChoose "display") (or (ne $.Path "/") (ne $.DIndex ""))}} - chevron_right -
    - {{.Title}} -
    - {{- end}} - {{- range .PrePaths}} + {{- range $.pre_paths}} chevron_right -
    +
    {{.PathName}}
    {{- end}}
    - {{- if and (.HasHead) (not .HasPwd)}} - - {{- if and (.HasReadme) (not .HasPwd)}} - - {{- if not .HasPwd}} + {{- if not $.has_pwd}} vertical_align_top {{- end}}
    - {{- if eq $.Footer ""}} - ©2021 PanIndex. All rights reserved. + {{- if eq $.config.Footer ""}} + ©2021 PanIndex. All rights reserved. {{- else}} - {{.Footer | unescaped}} + {{$.config.Footer | unescaped}} {{- end}}
    - - - -{{- if ne .Config.Js ""}} -{{.Config.Js | unescaped}} -{{- end}} \ No newline at end of file diff --git a/templates/pan/mdui/view-audio.html b/templates/pan/mdui/view-audio.html index d32711d9..e69860b2 100644 --- a/templates/pan/mdui/view-audio.html +++ b/templates/pan/mdui/view-audio.html @@ -1,43 +1,37 @@ -{{define "pan/mdui/view-audio.html"}} - {{template "pan/mdui/view-base.html" .}} +{{define "templates/pan/mdui/view-audio.html"}} + {{template "templates/pan/mdui/view-base.html" .}} {{end}} {{define "content-audio"}} - +
    - + {{end}} \ No newline at end of file diff --git a/templates/pan/mdui/view-base.html b/templates/pan/mdui/view-base.html index 9c9426a7..a2f69355 100644 --- a/templates/pan/mdui/view-base.html +++ b/templates/pan/mdui/view-base.html @@ -1,100 +1,124 @@ -{{define "pan/mdui/view-base.html"}} +{{define "templates/pan/mdui/view-base.html"}} -{{- if eq .Mode "aliyundrive"}} + {{- if or (eq $.account.Mode "aliyundrive") (.SearchKey)}} -{{- end}} + {{- end}} -{{- if ne .FaviconUrl ""}} - - -{{- else}} - - -{{- end}} - - - - - - - -{{- if ne .Config.Css ""}} - {{.Config.Css | unescaped}} -{{- end}} - {{- if eq $.Config.SiteName ""}} - {{.Title}} + {{- if ne $.config.FaviconUrl ""}} + <link rel="icon" href="{{$.config.FaviconUrl}}" type="image/x-icon" /> + <link rel="shortcut icon" href="{{$.config.FaviconUrl}}" type="image/x-icon" /> + {{- else}} + <link rel="icon" href="/static/img/favicon-{{$.account.Mode}}.ico" type="image/x-icon" /> + <link rel="shortcut icon" href="/static/img/favicon-{{$.account.Mode}}.ico" type="image/x-icon" /> + {{- end}} + <link rel="stylesheet" href="{{index $.config.CdnFiles "mdui@css"}}"/> + <script src="{{index $.config.CdnFiles "mdui@js"}}"></script> + <script src="{{index $.config.CdnFiles "jquery@js"}}"></script> + <script src="{{index $.config.CdnFiles "cookie@js"}}"></script> + <script src="{{index $.config.CdnFiles "md5@js"}}"></script> + <script src="{{index $.config.CdnFiles "marked@js"}}"></script> + <script src="{{index $.config.CdnFiles "clipboard@js"}}"></script> + <script src="{{index $.config.CdnFiles "mdui@index@js"}}?v={{$.version}}"></script> + {{- if ne $.config.Js ""}} + {{$.config.Js | unescaped}} + {{- end}} + <link rel="stylesheet" href="{{index $.config.CdnFiles "mdui@index@css"}}?v={{$.version}}"> + {{- if ne $.config.Css ""}} + {{$.config.Css | unescaped}} + {{- end}} + <title>{{- if eq $.config.SiteName ""}} + {{$.title}} {{- else}} - {{$.Config.SiteName}} + {{$.config.SiteName}} {{- end}} {{ .Path }} - {{ $SurportFolderDown := .SurportFolderDown }} - +
    -
    +
    - home - {{- if gt (len .Accounts) 1 }} -
      - {{- range $i, $a := .Accounts}} -
    • - face{{.Name}} -
    • - {{- end}} -
    - {{- end}} - - {{- if eq $.Config.SiteName ""}} - {{.Title}} - {{- else}} - {{$.Config.SiteName}} + home + {{- if gt (len $.accounts) 1 }} +
      + {{range $i, $a := $.accounts}} +
    • + face{{.Name}} +
    • {{- end}} - +
    + {{- end}} + + {{- if eq $.config.SiteName ""}} + {{$.title}} + {{- else}} + {{$.config.SiteName}} + {{- end}} + +
    + {{$lenPaths := len $.pre_paths}} + {{- range $index, $item := $.pre_paths}} + chevron_right +
    + {{.PathName}}
    - {{- if and (eq $.Config.AccountChoose "display") (or (ne $.Path "/") (ne $.DIndex ""))}} - chevron_right -
    - {{.Title}} -
    - {{- end}} - {{- range .PrePaths}} - chevron_right -
    - {{.PathName}} - {{.PathName}} -
    {{- end}}
    + {{- if not $.has_pwd}} + + {{- end}}
    • - {{- if .HasParent}} - + {{- if $.has_parent}} + {{- end}} - {{- if .HasPwd}}{{- else}}info{{- end}} - {{- if .HasPwd}}{{- else}}share{{- end}} - {{- if .HasPwd}}{{- else}}file_download{{- end}} - {{- if .LastFile }} - chevron_leftt + {{- if not $.has_pwd}}info{{- end}} + share + {{- if not $.has_pwd}}file_download{{- end}} + {{- if $.last_file }} + chevron_leftt {{- end}} - {{- if .NextFile }} - chevron_right + {{- if $.next_file }} + chevron_right {{- end}} - -
        + + +
          +
          • @@ -109,39 +133,19 @@
          - {{- if .HasPwd}} + {{- if $.has_pwd}}
          -
          +
          lock - - + + fingerprint - {{- if .PwdErrorMsg}} -
          {{.PwdErrorMsg}}
          + {{- if $.pwd_err_msg}} +
          {{$.pwd_err_msg}}
          {{- end}}
          @@ -150,32 +154,32 @@
          -
          名称:{{ (index .List 0).FileName }}
          -
          大小:{{ (index .List 0).SizeFmt }}
          -
          日期:{{ (index .List 0).LastOpTime }}
          -
          文件ID:{{ (index .List 0).FileId }} content_copy
          -
          目录ID:{{ (index .List 0).ParentId }} content_copy
          -
          链接:
          +
          名称:{{ (index $.fns 0).FileName }}
          +
          大小:{{ (index $.fns 0).SizeFmt }}
          +
          日期:{{ (index $.fns 0).LastOpTime }}
          +
          文件ID:{{ (index $.fns 0).FileId }} content_copy
          +
          目录ID:{{ (index $.fns 0).ParentId }} content_copy
          +
          链接:
          - {{- if (index .List 0).FileType}} - {{- if contains $.Config.Image (index .List 0).FileType}} + {{- if (index $.fns 0).FileType}} + {{- if contains $.config.Image (index $.fns 0).FileType}} {{block "content-img" .}}{{end}} - {{- else if contains $.Config.Audio (index .List 0).FileType}} + {{- else if contains $.config.Audio (index $.fns 0).FileType}} {{block "content-audio" .}}{{end}} - {{- else if contains $.Config.Video (index .List 0).FileType}} + {{- else if contains $.config.Video (index $.fns 0).FileType}} {{block "content-video" .}}{{end}} - {{- else if contains $.Config.Code (index .List 0).FileType}} + {{- else if contains $.config.Code (index $.fns 0).FileType}} {{block "content-code" .}}{{end}} - {{- else if contains $.Config.Doc (index .List 0).FileType}} + {{- else if contains $.config.Doc (index $.fns 0).FileType}} {{block "content-office" .}}{{end}} - {{- else if eq "pdf" (index .List 0).FileType}} + {{- else if eq "pdf" (index $.fns 0).FileType}} {{block "content-pdf" .}}{{end}} - {{- else if eq "epub" (index .List 0).FileType}} + {{- else if eq "epub" (index $.fns 0).FileType}} {{block "content-epub" .}}{{end}} - {{- else if eq "md" (index .List 0).FileType}} + {{- else if eq "md" (index $.fns 0).FileType}} {{block "content-md" .}}{{end}} {{- else}} {{block "content-ns" .}}{{end}} @@ -185,23 +189,17 @@ {{- end}}
          {{- end}} -
          - {{- if eq $.Footer ""}} + {{- if eq $.config.Footer ""}} ©2021 PanIndex. All rights reserved. - {{- else}} - {{.Footer | unescaped}} - {{- end}} + {{- else}} + {{$.config.Footer | unescaped}} + {{- end}}
        - - -{{- if ne .Config.Js ""}} -{{.Config.Js | unescaped}} -{{- end}} {{end}} diff --git a/templates/pan/mdui/view-code.html b/templates/pan/mdui/view-code.html index c3efbf13..29c78ab2 100644 --- a/templates/pan/mdui/view-code.html +++ b/templates/pan/mdui/view-code.html @@ -1,5 +1,5 @@ -{{define "pan/mdui/view-code.html"}} - {{template "pan/mdui/view-base.html" .}} +{{define "templates/pan/mdui/view-code.html"}} + {{template "templates/pan/mdui/view-base.html" .}} {{end}} {{define "content-code"}} + href="{{index $.config.CdnFiles "highlightjs@atom@dark@css"}}"> - + href="{{index $.config.CdnFiles "highlightjs@atom@light@css"}}"> +
        - + + {{end}} \ No newline at end of file diff --git a/templates/pan/mdui/view-md.html b/templates/pan/mdui/view-md.html index 0f2dd300..d30571b8 100644 --- a/templates/pan/mdui/view-md.html +++ b/templates/pan/mdui/view-md.html @@ -1,15 +1,12 @@ -{{define "pan/mdui/view-md.html"}} - {{template "pan/mdui/view-base.html" .}} +{{define "templates/pan/mdui/view-md.html"}} + {{template "templates/pan/mdui/view-base.html" .}} {{end}} {{define "content-md"}} -
        - - +
        {{end}} \ No newline at end of file diff --git a/templates/pan/mdui/view-office.html b/templates/pan/mdui/view-office.html index 10991810..bd08d96f 100644 --- a/templates/pan/mdui/view-office.html +++ b/templates/pan/mdui/view-office.html @@ -1,13 +1,12 @@ -{{define "pan/mdui/view-office.html"}} - {{template "pan/mdui/view-base.html" .}} +{{define "templates/pan/mdui/view-office.html"}} + {{template "templates/pan/mdui/view-base.html" .}} {{end}} {{define "content-office"}} - diff --git a/templates/pan/mdui/view-pdf.html b/templates/pan/mdui/view-pdf.html index f01cd098..f18f6789 100644 --- a/templates/pan/mdui/view-pdf.html +++ b/templates/pan/mdui/view-pdf.html @@ -1,22 +1,21 @@ -{{define "pan/mdui/view-pdf.html"}} - {{template "pan/mdui/view-base.html" .}} +{{define "templates/pan/mdui/view-pdf.html"}} + {{template "templates/pan/mdui/view-base.html" .}} {{end}} {{define "content-pdf"}} -
        - - - - +
        + + + + {{end}} \ No newline at end of file diff --git a/templates/pan/mdui/view-video.html b/templates/pan/mdui/view-video.html index 2d8e8f11..3260b60b 100644 --- a/templates/pan/mdui/view-video.html +++ b/templates/pan/mdui/view-video.html @@ -1,116 +1,24 @@ -{{define "pan/mdui/view-video.html"}} -{{template "pan/mdui/view-base.html" .}} +{{define "templates/pan/mdui/view-video.html"}} +{{template "templates/pan/mdui/view-base.html" .}} {{end}} {{define "content-video"}} -{{- if eq .Mode "aliyundrive"}} - -{{- end}} -
        - - - - +
        + +
          +
          +
          + + + + + {{end}} \ No newline at end of file diff --git a/util/common.go b/util/common.go new file mode 100644 index 00000000..e82e3265 --- /dev/null +++ b/util/common.go @@ -0,0 +1,714 @@ +package util + +import ( + "bytes" + "crypto/md5" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "fmt" + "github.com/libsgh/PanIndex/module" + "github.com/qingstor/go-mime" + "github.com/robfig/cron/v3" + log "github.com/sirupsen/logrus" + math_rand "math/rand" + "net/http" + "net/url" + "path/filepath" + "sort" + "strconv" + "strings" + "time" +) + +type Timespan time.Duration + +var CacheCronMap = make(map[string]cron.EntryID) + +var Cron *cron.Cron + +func (t Timespan) Format(format string) string { + z := time.Unix(0, 0).UTC() + return z.Add(time.Duration(t)).Format(format) +} + +func ShortDur(d time.Duration) string { + z := time.Unix(0, 0).UTC() + return z.Add(d).Format("15:04:05") +} + +func FormatFileSize(fileSize int64) (size string) { + if fileSize == 0 { + return "-" + } else if fileSize < 1024 { + //return strconv.FormatInt(fileSize, 10) + "B" + return fmt.Sprintf("%.2f B", float64(fileSize)/float64(1)) + } else if fileSize < (1024 * 1024) { + return fmt.Sprintf("%.2f KB", float64(fileSize)/float64(1024)) + } else if fileSize < (1024 * 1024 * 1024) { + return fmt.Sprintf("%.2f MB", float64(fileSize)/float64(1024*1024)) + } else if fileSize < (1024 * 1024 * 1024 * 1024) { + return fmt.Sprintf("%.2f GB", float64(fileSize)/float64(1024*1024*1024)) + } else if fileSize < (1024 * 1024 * 1024 * 1024 * 1024) { + return fmt.Sprintf("%.2f TB", float64(fileSize)/float64(1024*1024*1024*1024)) + } else { //if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024) + return fmt.Sprintf("%.2f EB", float64(fileSize)/float64(1024*1024*1024*1024*1024)) + } +} + +func UTCTimeFormat(timeStr string) string { + t, _ := time.Parse(time.RFC3339, timeStr) + timeUint := t.In(time.Local).Unix() + return time.Unix(timeUint, 0).Format("2006-01-02 15:04:05") +} + +func FileNodeAuth(fn *module.FileNode, hide, hasPwd int) { + if hide == 1 { + fn.Hide = hide + } else { + _, ok := module.GloablConfig.HideFiles[fn.FileId] + if ok { + fn.Hide = 1 + } else { + fn.Hide = 0 + } + } + if hasPwd == 1 { + fn.HasPwd = hasPwd + } else { + _, ok := module.GloablConfig.PwdFiles[fn.FileId] + if ok { + fn.HasPwd = 1 + } else { + fn.HasPwd = 0 + } + } +} + +func GetViewType(fileType string) string { + config := module.GloablConfig + if fileType == "" { + return "" + } + if strings.Contains(config.Image, fileType) { + return "img" + } else if strings.Contains(config.Audio, fileType) { + return "audio" + } else if strings.Contains(config.Video, fileType) { + return "video" + } else if strings.Contains(config.Code, fileType) { + return "code" + } else if strings.Contains(config.Doc, fileType) { + return "office" + } else if fileType == "pdf" { + return "pdf" + } else if fileType == "md" { + return "md" + } else if fileType == "epub" { + return "epub" + } else { + return "ns" + } +} + +func GetExt(name string) string { + ext := strings.TrimLeft(filepath.Ext(name), ".") + return ext +} + +type KV map[string]interface{} + +func GetIcon(isFolder bool, fileType string) string { + iconMap := KV{ + "mdui": KV{ + "folder": "folder_open", //文件夹 + "image": "image", //图片 + "audio": "audio_file", //音频 + "video": "video_file", //视频 + "apk": "android", //安卓apk + "archive": "folder_zip", //压缩包 + "file": "insert_drive_file", //普通文件 + "exe": "apps", //windows可执行文件 + "code": "code", //代码 + "txt": "text_snippet", //文本 + "pdf": "picture_as_pdf", + "md": "text_snippet", + }, + "classic": KV{ + "folder": "icon icon-dir", //文件夹 + "image": "icon icon-file", //图片 + "audio": "icon icon-file", //音频 + "video": "icon icon-file", //视频 + "apk": "icon icon-file", //安卓apk + "archive": "icon icon-file", //压缩包 + "file": "icon icon-file", //普通文件 + "exe": "icon icon-file", //windows可执行文件 + "code": "icon icon-file", //代码 + "txt": "icon icon-file", //文本 + "pdf": "icon icon-file", + "md": "icon icon-file", + }, + "bootstrap": KV{ + "folder": "fas fa-folder", //文件夹 + "image": "far fa-file-image", //图片 + "audio": "fas fa-music", //音频 + "video": "fab fa-youtube", //视频 + "apk": "fab fa-android", //安卓apk + "archive": "fas fa-file-archive", //压缩包 + "file": "fas fa-file", //普通文件 + "exe": "fab fa-microsoft", //windows可执行文件 + "code": "fas fa-code", //代码 + "txt": "fas fa-file-alt", //文本 + "pdf": "fas fa-file-alt", + "md": "fas fa-file-alt", + }, + } + config := module.GloablConfig + fileKey := "file" + if isFolder { + fileKey = "folder" + } else { + if strings.Contains(config.Image, fileType) { + fileKey = "image" + } else if strings.Contains(config.Audio, fileType) { + fileKey = "audio" + } else if strings.Contains(config.Video, fileType) { + fileKey = "video" + } else if strings.Contains(config.Code, fileType) { + fileKey = "txt" + } else if strings.Contains(config.Doc, fileType) { + fileKey = "txt" + } else if strings.Contains("pdf", fileType) { + fileKey = "pdf" + } else if strings.Contains("md", fileType) { + fileKey = "md" + } else if strings.Contains("zip,gz,7z,rar", fileType) { + fileKey = "archive" + } else if fileType == "apk" { + fileKey = "apk" + } else if fileType == "exe" { + fileKey = "exe" + } + } + return iconMap[config.Theme].(KV)[fileKey].(string) +} +func GetBetweenStr(str, start, end string) string { + n := strings.Index(str, start) + if n == -1 { + n = 0 + } else { + n = n + len(start) + } + str = string([]byte(str)[n:]) + m := strings.Index(str, end) + if m == -1 { + m = len(str) + } + str = string([]byte(str)[:m]) + return str +} + +func GetPrePath(path string) []map[string]string { + //path := "/a/b/c/d" + prePaths := []map[string]string{} + paths := strings.Split(path, "/") + for i, n := range paths { + item := make(map[string]string) + var buffer bytes.Buffer + for j := 0; j <= i; j++ { + if paths[j] == "" { + buffer.WriteString(paths[j]) + } else { + buffer.WriteString("/") + buffer.WriteString(paths[j]) + } + } + if buffer.String() != "" { + item["PathName"] = n + item["PathUrl"] = buffer.String() + prePaths = append(prePaths, item) + } + } + return prePaths +} + +func GetParentPath(p string) string { + if p == "/" { + return "" + } else { + s := "" + ss := strings.Split(p, "/") + for i := 0; i < len(ss)-1; i++ { + if ss[i] != "" { + s += "/" + ss[i] + } + } + if s == "" { + s = "/" + } + return s + } +} + +func Md5(data string) string { + return fmt.Sprintf("%x", md5.Sum([]byte(data))) +} + +const ( + VAL = 0x3FFFFFFF + INDEX = 0x0000003D +) + +var ( + alphabet = []byte("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") +) + +/** implementation of short url algorithm **/ +func Transform(longURL string) ([4]string, error) { + md5Str := Md5(longURL) + //var hexVal int64 + var tempVal int64 + var result [4]string + var tempUri []byte + for i := 0; i < 4; i++ { + tempSubStr := md5Str[i*8 : (i+1)*8] + hexVal, err := strconv.ParseInt(tempSubStr, 16, 64) + if err != nil { + return result, nil + } + tempVal = int64(VAL) & hexVal + var index int64 + tempUri = []byte{} + for i := 0; i < 6; i++ { + index = INDEX & tempVal + tempUri = append(tempUri, alphabet[index]) + tempVal = tempVal >> 5 + } + result[i] = string(tempUri) + } + return result, nil +} + +func SortFileNodeNew(sortColumn, sortOrder string, list []module.FileNode) { + if sortColumn != "default" && sortOrder != "null" { + sort.SliceStable(list, func(i, j int) bool { + li, _ := time.Parse("2006-01-02 15:04:05", list[i].LastOpTime) + lj, _ := time.Parse("2006-01-02 15:04:05", list[j].LastOpTime) + d1 := 0 + if list[i].IsFolder { + d1 = 1 + } + d2 := 0 + if list[j].IsFolder { + d2 = 1 + } + if d1 > d2 { + return true + } else if d1 == d2 { + if sortColumn == "file_name" { + c := strings.Compare(list[i].FileName, list[j].FileName) + if sortOrder == "desc" { + return c >= 0 + } else { + return c <= 0 + } + } else if sortColumn == "file_size" { + if sortOrder == "desc" { + return list[i].FileSize >= list[j].FileSize + } else { + return list[i].FileSize <= list[j].FileSize + } + } else if sortColumn == "last_op_time" { + if sortOrder == "desc" { + return li.After(lj) + } else { + return li.Before(lj) + } + } else { + return lj.After(li) + } + } else { + return false + } + }) + } +} +func SortFileNode(sortColumn, sortOrder string, list []module.FileNode) { + if sortColumn == "default" { + sortColumn = "last_op_time" + } + if sortOrder == "null" { + sortColumn = "asc" + } + sort.SliceStable(list, func(i, j int) bool { + if list[i].IsFolder != list[j].IsFolder { + return list[i].IsFolder + } + if sortColumn == "file_name" { + c := strings.Compare(list[i].FileName, list[j].FileName) + if c != 0 { + if sortOrder == "desc" { + return c > 0 + } else { + return c < 0 + } + } + } else if sortColumn == "file_size" { + if list[i].FileSize != list[j].FileSize { + if sortOrder == "desc" { + return list[i].FileSize > list[j].FileSize + } else { + return list[i].FileSize < list[j].FileSize + } + } + } else if sortColumn == "last_op_time" { + li, _ := time.Parse("2006-01-02 15:04:05", list[i].LastOpTime) + lj, _ := time.Parse("2006-01-02 15:04:05", list[j].LastOpTime) + if sortOrder == "desc" { + return li.After(lj) + } else { + return li.Before(lj) + } + } + return false + }) +} + +func GetPwdFromPath(path string) (module.PwdFiles, bool) { + pwdDir := module.PwdFiles{} + pwdFile := module.PwdFiles{} + pwdMaps := module.GloablConfig.PwdFiles + for k, v := range pwdMaps { + if strings.HasPrefix(path, k) { + pwdDir.FilePath = k + pwdDir.Password = v + } + if k == path { + pwdFile.FilePath = k + pwdFile.Password = v + } + } + if pwdFile.FilePath != "" { + return pwdFile, true + } + if pwdDir.FilePath != "" { + return pwdDir, true + } + return pwdDir, false +} + +func GetCdnFilesMap(cdn, version string) map[string]string { + if version == "" { + version = "main" + } + jp := "https://cdn.jsdelivr.net/gh/libsgh/PanIndex@" + version + m := map[string]string{} + cdnMap := KV{ + "0": KV{ + "mdui@css": "/static/lib/mdui@1.0.2/css/mdui.min.css", + "mdui@js": "/static/lib/mdui@1.0.2/js/mdui.min.js", + "viewer@css": "/static/lib/viewerjs@1.10.1/dist/viewer.min.css", + "viewer@js": "/static/lib/viewerjs@1.10.1/dist/viewer.min.js", + "jquery@js": "/static/lib/jquery@3.5.1/jquery.min.js", + "cookie@js": "/static/lib/js-cookie@3.0.1/dist/js.cookie.min.js", + "md5@js": "/static/lib/md5/md5.min.js", + "marked@js": "/static/lib/marked/marked.min.js", + "clipboard@js": "/static/lib/clipboard@2.0.8/clipboard.min.js", + "mdui@index@js": "/static/js/mdui.index.js", + "mdui@index@css": "/static/css/index.css", + "sortablejs@js": "/static/lib/sortablejs@1.14.0/Sortable.min.js", + "admin@js": "/static/js/admin.js", + "fontawesome@css": "/static/lib/fontawesome@5.15.4/css/all.min.css", + "APlayer@css": "/static/lib/aplayer@1.10.1/dist/APlayer.min.css", + "APlayer@js": "/static/lib/aplayer@1.10.1/dist/APlayer.min.js", + "sweetalert2@css": "/static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.css", + "sweetalert2@js": "/static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.js", + "hls@js": "/static/lib/hls.js@1.1.2/dist/hls.min.js", + "flv@js": "/static/lib/flv.js@1.6.2/dist/flv.min.js", + "artplayer@js": "/static/lib/artplayer@4.3.1/artplayer.min.js", + "video@mdui@js": "/static/js/mdui.video.js", + "video@simple@js": "/static/js/simple.video.js", + "simple@index@js": "/static/js/simple.index.js", + "highlightjs@atom@dark@css": "/static/lib/highlightjs/cdn-release@11.4.0/build/styles/atom-one-dark.min.css", + "highlightjs@atom@light@css": "/static/lib/highlightjs/cdn-release@11.4.0/build/styles/atom-one-light.min.css", + "highlight@js": "/static/lib/highlightjs/cdn-release@11.4.0/build/highlight.min.js", + "jszip@js": "/static/lib/jszip@3.1.5/jszip.min.js", + "epub@js": "/static/lib/epubjs@0.3.88/epub.min.js", + "pdfh5@css": "/static/lib/pdfh5@1.4.0/css/pdfh5.css", + "pdf@js": "/static/lib/pdfh5@1.4.0/js/pdf.js", + "pdf@worker@js": "/static/lib/pdfh5@1.4.0/js/pdf.worker.js", + "pdfh5@js": "/static/lib/pdfh5@1.4.0/js/pdfh5.js", + "natural@compare@js": "/static/lib/natural-compare-lite@1.4.0/index.min.js", + "bootstrap@css": "/static/lib/bootstrap@4.6.1/css/bootstrap.min.css", + "bootstrap@js": "/static/lib/bootstrap@4.6.1/js/bootstrap.min.js", + }, + "1": KV{ + "mdui@css": "//cdn.staticfile.org/mdui/1.0.2/css/mdui.min.css", + "mdui@js": "//cdn.staticfile.org/mdui/1.0.2/js/mdui.min.js", + "viewer@css": "//cdn.staticfile.org/viewerjs/1.10.1/viewer.min.css", + "viewer@js": "//cdn.staticfile.org/viewerjs/1.10.1/viewer.min.js", + "jquery@js": "//cdn.staticfile.org/jquery/3.5.1/jquery.min.js", + "cookie@js": "//cdn.staticfile.org/js-cookie/latest/js.cookie.min.js", + "md5@js": "//cdn.staticfile.org/blueimp-md5/1.0.1/js/md5.min.js", + "marked@js": "//cdn.staticfile.org/marked/4.0.2/marked.min.js", + "clipboard@js": "//cdn.staticfile.org/clipboard.js/2.0.8/clipboard.min.js", + "mdui@index@js": "/static/js/mdui.index.js", + "mdui@index@css": "/static/css/index.css", + "sortablejs@js": "//cdn.staticfile.org/Sortable/1.14.0/Sortable.min.js", + "admin@js": "/static/js/admin.js", + "fontawesome@css": "//cdn.staticfile.org/font-awesome/5.15.4/css/all.min.css", + "APlayer@css": "//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.css", + "APlayer@js": "//lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js", + "sweetalert2@css": "/static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.css", + "sweetalert2@js": "/static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.js", + "hls@js": "//cdn.staticfile.org/hls.js/1.1.2/hls.min.js", + "flv@js": "//cdn.staticfile.org/flv.js/1.6.2/flv.min.js", + "artplayer@js": "//unpkg.com/artplayer@4.3.1/dist/artplayer.js", + "video@mdui@js": "/static/js/mdui.video.js", + "video@simple@js": "/static/js/simple.video.js", + "simple@index@js": "/static/js/simple.index.js", + "highlightjs@atom@dark@css": "//cdn.bootcdn.net/ajax/libs/highlight.js/11.4.0/styles/atom-one-dark.min.css", + "highlightjs@atom@light@css": "//cdn.bootcdn.net/ajax/libs/highlight.js/11.4.0/styles/atom-one-light.min.css", + "highlight@js": "//cdn.bootcdn.net/ajax/libs/highlight.js/11.4.0/highlight.min.js", + "jszip@js": "//lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jszip/3.1.5/jszip.js", + "epub@js": "//cdn.jsdelivr.net/npm/epubjs@0.3.88/dist/epub.js", + "pdfh5@css": "//cdn.jsdelivr.net/npm/pdfh5@1.4.2/css/pdfh5.css", + "pdf@js": "//cdn.jsdelivr.net/npm/pdfh5@1.4.2/js/pdf.js", + "pdf@worker@js": "//cdn.jsdelivr.net/npm/pdfh5@1.4.2/js/pdf.worker.js", + "pdfh5@js": "//cdn.jsdelivr.net/npm/pdfh5@1.4.2/js/pdfh5.js", + "natural@compare@js": "//cdn.jsdelivr.net/npm/natural-compare-lite@1.4.0/index.min.js", + "bootstrap@css": "//cdn.staticfile.org/bootstrap/4.6.1/css/bootstrap.min.css", + "bootstrap@js": "//cdn.staticfile.org/bootstrap/4.6.1/js/bootstrap.min.js", + }, + "2": KV{ + "mdui@css": jp + "/static/lib/mdui@1.0.2/css/mdui.min.css", + "mdui@js": jp + "/static/lib/mdui@1.0.2/js/mdui.min.js", + "viewer@css": jp + "/static/lib/viewerjs@1.10.1/dist/viewer.min.css", + "viewer@js": jp + "/static/lib/viewerjs@1.10.1/dist/viewer.min.js", + "jquery@js": jp + "/static/lib/jquery@3.5.1/jquery.min.js", + "cookie@js": jp + "/static/lib/js-cookie@3.0.1/dist/js.cookie.min.js", + "md5@js": jp + "/static/lib/md5/md5.min.js", + "marked@js": jp + "/static/lib/marked/marked.min.js", + "clipboard@js": jp + "/static/lib/clipboard@2.0.8/clipboard.min.js", + "mdui@index@js": jp + "/static/js/mdui.index.js", + "mdui@index@css": jp + "/static/css/index.css", + "sortablejs@js": jp + "/static/lib/sortablejs@1.14.0/Sortable.min.js", + "admin@js": jp + "/static/js/admin.js", + "fontawesome@css": jp + "/static/lib/fontawesome@5.15.4/css/all.min.css", + "APlayer@css": jp + "/static/lib/aplayer@1.10.1/dist/APlayer.min.css", + "APlayer@js": jp + "/static/lib/aplayer@1.10.1/dist/APlayer.min.js", + "sweetalert2@css": jp + "/static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.css", + "sweetalert2@js": jp + "/static/lib/sweetalert2@11.3.0/dist/sweetalert2.min.js", + "hls@js": jp + "/static/lib/hls.js@1.1.2/dist/hls.min.js", + "flv@js": jp + "/static/lib/flv.js@1.6.2/dist/flv.min.js", + "artplayer@js": jp + "/static/lib/artplayer@4.3.1/artplayer.min.js", + "video@mdui@js": jp + "/static/js/mdui.video.js", + "video@simple@js": jp + "/static/js/simple.video.js", + "simple@index@js": jp + "/static/js/simple.index.js", + "highlightjs@atom@dark@css": jp + "/static/lib/highlightjs/cdn-release@11.4.0/build/styles/atom-one-dark.min.css", + "highlightjs@atom@light@css": jp + "/static/lib/highlightjs/cdn-release@11.4.0/build/styles/atom-one-light.min.css", + "highlight@js": jp + "/static/lib/highlightjs/cdn-release@11.4.0/build/highlight.min.js", + "jszip@js": jp + "/static/lib/jszip@3.1.5/jszip.min.js", + "epub@js": jp + "/static/lib/epubjs@0.3.88/epub.min.js", + "pdfh5@css": jp + "/static/lib/pdfh5@1.4.0/css/pdfh5.css", + "pdf@js": jp + "/static/lib/pdfh5@1.4.0/js/pdf.js", + "pdf@worker@js": jp + "/static/lib/pdfh5@1.4.0/js/pdf.worker.js", + "pdfh5@js": jp + "/static/lib/pdfh5@1.4.0/js/pdfh5.js", + "natural@compare@js": jp + "/static/lib/natural-compare-lite@1.4.0/index.min.js", + "bootstrap@css": jp + "/static/lib/bootstrap@4.6.1/css/bootstrap.min.css", + "bootstrap@js": jp + "/static/lib/bootstrap@4.6.1/js/bootstrap.min.js", + }, + } + cdnKV := cdnMap["0"].(KV) + if cdn != "" { + cdnKV = cdnMap[cdn].(KV) + } + for k, v := range cdnKV { + m[k] = v.(string) + } + return m +} + +func Base64Decode(str string) (string, bool) { + data, err := base64.StdEncoding.DecodeString(str) + if err != nil { + return "", true + } + return string(data), false +} + +//return ParentPath, fileName +func ParsePath(path string) (string, string) { + filePath, fileName := filepath.Split(path) + if filePath != "/" && filePath[len(filePath)-1:] == "/" { + filePath = filePath[0 : len(filePath)-1] + } + return filePath, fileName +} + +//clear Suffix +func ClearSuffix(filePath string) string { + if filePath != "/" && filePath[len(filePath)-1:] == "/" { + filePath = filePath[0 : len(filePath)-1] + } + return filePath +} + +//return fileName +func GetFileName(path string) string { + paths := strings.Split(path, "/") + return paths[len(paths)-1] +} + +func GetTransferDomain(transferConfig, domain string) string { + domainGroups := strings.Split(transferConfig, ",") + for _, dg := range domainGroups { + domains := strings.Split(dg, "|") + if domains[0] == domain { + return domains[1] + } + } + return domain +} + +func ChunkBytes(buf []byte, lim int) [][]byte { + var chunk []byte + chunks := make([][]byte, 0, len(buf)/lim+1) + for len(buf) >= lim { + chunk, buf = buf[:lim], buf[lim:] + chunks = append(chunks, chunk) + } + if len(buf) > 0 { + chunks = append(chunks, buf[:len(buf)]) + } + return chunks +} + +func RsaEncode(origData []byte, j_rsakey string) string { + publicKey := []byte("-----BEGIN PUBLIC KEY-----\n" + j_rsakey + "\n-----END PUBLIC KEY-----") + block, _ := pem.Decode(publicKey) + pubInterface, _ := x509.ParsePKIXPublicKey(block.Bytes) + pub := pubInterface.(*rsa.PublicKey) + b, err := rsa.EncryptPKCS1v15(rand.Reader, pub, origData) + if err != nil { + log.Errorf("err: %s", err.Error()) + } + return b64tohex(base64.StdEncoding.EncodeToString(b)) +} + +var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + +var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz" + +func int2char(a int) string { + return strings.Split(BI_RM, "")[a] +} + +func b64tohex(a string) string { + d := "" + e := 0 + c := 0 + for i := 0; i < len(a); i++ { + m := strings.Split(a, "")[i] + if m != "=" { + v := strings.Index(b64map, m) + if 0 == e { + e = 1 + d += int2char(v >> 2) + c = 3 & v + } else if 1 == e { + e = 2 + d += int2char(c<<2 | v>>4) + c = 15 & v + } else if 2 == e { + e = 3 + d += int2char(c) + d += int2char(v >> 2) + c = 3 & v + } else { + e = 0 + d += int2char(c<<2 | v>>4) + d += int2char(15 & v) + } + } + } + if e == 1 { + d += int2char(c << 2) + } + return d +} + +//获取随机数 +func Random() string { + return fmt.Sprintf("0.%17v", math_rand.New(math_rand.NewSource(time.Now().UnixNano())).Int63n(100000000000000000)) +} + +func GetRandomStr(n int) string { + letters := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") + b := make([]rune, n) + for i := range b { + b[i] = letters[math_rand.Intn(len(letters))] + } + return string(b) +} + +func Yun139Sign(timestamp, key, json string) string { + //去除多余空格 + json = strings.TrimSpace(json) + json = EncodeURIComponent(json) + c := strings.Split(json, "") + sort.Strings(c) + json = strings.Join(c, "") + s1 := Md5(base64.StdEncoding.EncodeToString([]byte(json))) + s2 := Md5(timestamp + ":" + key) + return strings.ToUpper(Md5(s1 + s2)) +} + +func EncodeURIComponent(str string) string { + r := url.QueryEscape(str) + r = strings.Replace(r, "+", "%20", -1) + r = strings.Replace(r, "%21", "!", -1) + r = strings.Replace(r, "%27", "'", -1) + r = strings.Replace(r, "%28", "(", -1) + r = strings.Replace(r, "%29", ")", -1) + r = strings.Replace(r, "%2A", "*", -1) + return r +} + +func GetClient(timeout int) *http.Client { + if module.GloablConfig.Proxy != "" { + proxy, _ := url.Parse(module.GloablConfig.Proxy) + tr := &http.Transport{ + Proxy: http.ProxyURL(proxy), + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{ + Transport: tr, + Timeout: time.Second * time.Duration(timeout), + } + return client + } else { + return &http.Client{ + Timeout: time.Second * time.Duration(timeout), + } + } +} + +func GetOffsetByRange(rangeStr string) uint64 { + rangeStr = strings.Split(rangeStr, "=")[1] + rangeStr = strings.Split(rangeStr, ",")[0] + rangeStr = strings.Split(rangeStr, "-")[0] + offset, err := strconv.ParseInt(rangeStr, 10, 64) + if err != nil { + return uint64(offset) + } + return 0 +} + +func GetMimeTypeByExt(ext string) string { + mimeType := mime.DetectFileExt(ext) + return mimeType +} diff --git a/util/file.go b/util/file.go new file mode 100644 index 00000000..fe3643d4 --- /dev/null +++ b/util/file.go @@ -0,0 +1,11 @@ +package util + +import "os" + +func FileExist(path string) bool { + _, err := os.Stat(path) + if err != nil { + return os.IsExist(err) + } + return true +} From ae80eec7d9e63bd5e84d95f8ed943a8ec0ba1b0b Mon Sep 17 00:00:00 2001 From: libsgh Date: Fri, 4 Mar 2022 15:38:51 +0800 Subject: [PATCH 2/2] :art:change checkout ref --- .github/workflows/compile-to-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compile-to-release.yml b/.github/workflows/compile-to-release.yml index 71384cb2..1df6e74b 100644 --- a/.github/workflows/compile-to-release.yml +++ b/.github/workflows/compile-to-release.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@v2 with: persist-credentials: false - ref: master + ref: main - name: Build PanIndex uses: libsgh/PanIndex-build-action@main - name: Release