feat: server

This commit is contained in:
mozzie 2023-02-11 13:21:06 +08:00
parent 2ce2f1d3e2
commit 328fc9801d
129 changed files with 25557 additions and 1087 deletions

5
apps/server/.babelrc Normal file
View File

@ -0,0 +1,5 @@
{
"presets": [
"@babel/preset-env"
]
}

0
apps/server/.env Normal file
View File

5
apps/server/.env.dev Normal file
View File

@ -0,0 +1,5 @@
# 服务端口
PORT=4000
# 静态资源
ASSETS_URL=/

5
apps/server/.env.prod Normal file
View File

@ -0,0 +1,5 @@
# 服务端口
PORT=7001
# 静态资源
ASSETS_URL=https://cdn.com/backset/

View File

@ -7,23 +7,32 @@
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
"dev:be": "cross-env RUNNING_ENV=dev nest start --watch",
"prod:be": "cross-env RUNNING_ENV=prod node dist/main",
"dev:fe": "cross-env RUNNING_ENV=dev webpack -w",
"build:fe": "cross-env RUNNING_ENV=prod webpack build",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"new:page": "node ./script/new.page.js",
"new:mvc": "node ./script/new.mvc.js"
},
"dependencies": {
"@backset/util": "workspace:^1.0.0",
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/config": "2.3.1",
"@nestjs/platform-express": "^9.0.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0"
"rxjs": "^7.2.0",
"@nestjs/mongoose": "7.2.4",
"mongoose": "5.13.15",
"mysql2": "3.0.1",
"typeorm": "0.3.11",
"axios": "0.27.2"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@nestjs/typeorm": "9.0.1",
"@types/express": "^4.17.13",
"@types/node": "18.11.18",
"@typescript-eslint/eslint-plugin": "^5.0.0",
@ -33,26 +42,26 @@
"eslint-plugin-prettier": "^4.0.0",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.1.1",
"typescript": "^4.7.4"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
"typescript": "^4.7.4",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"ts-loader": "9.4.2",
"css-loader": "6.7.3",
"url-loader": "4.1.1",
"@babel/core": "7.20.12",
"@babel/preset-env": "7.20.2",
"babel-loader": "8.1.0",
"less": "3.8.0",
"less-loader": "4.1.0",
"cross-env": "7.0.3",
"ejs": "3.1.8",
"mini-css-extract-plugin": "2.7.2",
"@types/mongoose": "^5.11.97",
"inquirer": "8.0.0",
"chalk": "4.1.2",
"copy-webpack-plugin": "5.1.2",
"cash-dom": "8.1.3"
}
}

Binary file not shown.

View File

@ -0,0 +1 @@
<svg t="1667271285418" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34809" width="200" height="200"><path d="M158.165333 499.498667A42.496 42.496 0 0 0 170.666667 469.333333V256a42.666667 42.666667 0 0 1 42.666666-42.666667 42.666667 42.666667 0 0 0 0-85.333333C142.762667 128 85.333333 185.429333 85.333333 256v195.669333l-30.165333 30.165334a42.666667 42.666667 0 0 0 0 60.330666l30.165333 30.165334V768c0 70.570667 57.429333 128 128 128a42.666667 42.666667 0 0 0 0-85.333333 42.666667 42.666667 0 0 1-42.666666-42.666667v-213.333333a42.496 42.496 0 0 0-12.501334-30.165334L145.664 512l12.501333-12.501333zM978.090667 495.658667a42.709333 42.709333 0 0 0-9.258667-13.824L938.666667 451.669333V256c0-70.570667-57.429333-128-128-128a42.666667 42.666667 0 1 0 0 85.333333 42.666667 42.666667 0 0 1 42.666666 42.666667v213.333333a42.581333 42.581333 0 0 0 12.501334 30.165334l12.501333 12.501333-12.501333 12.501333A42.496 42.496 0 0 0 853.333333 554.666667v213.333333a42.666667 42.666667 0 0 1-42.666666 42.666667 42.666667 42.666667 0 1 0 0 85.333333c70.570667 0 128-57.429333 128-128v-195.669333l30.165333-30.165334a42.709333 42.709333 0 0 0 9.258667-46.506666zM669.738667 225.450667a42.752 42.752 0 0 0-69.546667 14.762666l-255.829333 512a42.624 42.624 0 0 0 23.893333 55.424 42.922667 42.922667 0 0 0 55.552-23.765333l255.786667-512a42.538667 42.538667 0 0 0-9.813334-46.421333z" p-id="34810" fill="#2c2c2c"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,235 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="865.76" height="682.89" viewBox="0 0 865.76 682.89">
<defs>
<style xmlns="http://www.w3.org/1999/xhtml">*, ::after, ::before { box-sizing: border-box; }
img, svg { vertical-align: middle; }
</style>
<style xmlns="http://www.w3.org/1999/xhtml">*, body, html { -webkit-font-smoothing: antialiased; }
img, svg { max-width: 100%; }
</style>
</defs>
<rect x="167.21" y="379.13" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M189,358.3l19.37-.42,9.83-.16c3.29-.07,6.6,0,9.89-.07h.65v.66l.09,16.52v.74h-.71l-19.55-.09c-6.51,0-13-.18-19.54-.25h-.42v-.4c0-2.8.12-5.59.2-8.34Zm0,0,.21,8.34c0,2.76.16,5.47.19,8.18l-.4-.4c6.51-.08,13-.24,19.54-.25l19.58-.09-.74.74V358.3l.74.72c-3.22,0-6.44,0-9.67-.09l-9.71-.16Z" fill="#ebebeb"/>
<path d="M145.48,358.3l19.37-.42,9.83-.16c3.29-.07,6.58,0,9.89-.07h.65v.66l.09,16.52v.74h-.74L165,375.48c-6.53,0-13-.18-19.55-.25h-.41v-.4c0-2.8.13-5.59.19-8.34Zm0,0,.21,8.34c0,2.76.16,5.47.19,8.18l-.4-.4c6.51-.08,13-.24,19.55-.25l19.54-.09-.74.74V358.3l.67.66c-3.24,0-6.44,0-9.67-.09l-9.72-.16Z" fill="#ebebeb"/>
<path d="M746.68,51.89l-19.36.41-9.83.16c-3.3.08-6.6,0-9.89.09H707v-.66l-.09-16.52v-.74h.74l19.54.1c6.52,0,13,.17,19.54.24h.42v.4c0,2.8-.13,5.59-.19,8.35Zm0,0-.2-8.34c0-2.75-.16-5.47-.19-8.18l.39.41c-6.51,0-13,.24-19.54.24l-19.54.09.73-.74-.07,16.52-.66-.65h9.66l9.72.17Z" fill="#ebebeb"/>
<rect x="729.4" y="56.2" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M184.51,52l-19.38.39-9.83.18H144.76V34.7h.72l19.55.09c6.51,0,13,.16,19.54.24h.4v.4c0,2.79-.13,5.58-.19,8.34Zm0,0-.22-8.36c0-2.75-.16-5.46-.19-8.16l.41.4c-6.52.07-13,.23-19.54.23l-19.49,0,.72-.74L146.07,52l-.59-.73c3.22,0,6.42,0,9.66.09l9.71.16Z" fill="#ebebeb"/>
<rect x="420.15" y="139.6" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M729.4,364.47l19.38-.42,9.83-.16c3.29-.07,6.59,0,9.88-.09h.66v.67l.08,16.52v.73h-.8l-19.55-.08c-6.51,0-13-.18-19.54-.26h-.4V381c0-2.81.13-5.6.19-8.34Zm0,0,.22,8.34c0,2.76.16,5.47.19,8.18l-.41-.4c6.52-.08,13-.24,19.54-.25l19.55-.09-.73.74.08-16.52.65.66c-3.22,0-6.42,0-9.66-.09l-9.71-.16Z" fill="#ebebeb"/>
<rect x="473.81" y="501.71" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M441.94,118.77l19.44-.37,9.83-.16h10.54v.67l.08,16.51v.74h-.74l-19.54-.09c-6.53,0-13-.16-19.55-.25h-.41v-.4c0-2.8.13-5.59.19-8.34Zm0,0,.22,8.36c0,2.74.17,5.46.2,8.16l-.4-.4c6.51,0,13-.23,19.54-.23l19.55-.11-.74.74.07-16.52.67.67c-3.24,0-6.44,0-9.67-.09l-9.72-.16Z" fill="#ebebeb"/>
<polygon points="246.63 502.21 197.09 502.21 168.75 360.87 214.09 340.02 246.63 502.21" fill="#dbdbdb"/>
<polygon points="388.43 502.21 246.63 502.21 214.09 340.02 355.9 340.02 388.43 502.21" fill="#ebebeb"/>
<rect x="145.27" y="426.38" width="75.92" height="155.78" fill="#dbdbdb"/>
<polygon points="424.86 582.16 404.12 582.16 373.21 426.38 424.86 426.38 424.86 582.16" fill="#dbdbdb"/>
<rect x="221.19" y="426.38" width="41.72" height="155.78" fill="#ebebeb"/>
<rect x="424.86" y="426.38" width="41.72" height="155.78" fill="#ebebeb"/>
<rect x="262.91" y="502.21" width="161.95" height="79.94" fill="#ebebeb"/>
<rect x="262.91" y="467.65" width="161.95" height="34.88" fill="#ebebeb"/>
<path d="M231.42,426.38l15.76-.28,15.73-.21h.47v.49l.2,18.26v18.23c0,12.15.08,24.3,0,36.46s0,24.3-.21,36.46-.27,24.3-.53,36.46q-.39-18.24-.52-36.46c-.16-12.16-.18-24.31-.22-36.46s0-24.31,0-36.46V444.64l.18-18.23.47.47L247,426.69Z" fill="#dbdbdb"/>
<path d="M424.86,426.38c.33,12.19.48,24.38.61,36.59l.18,36.6-.18,36.59-.22,18.31-.39,18.29-.38-18.29-.22-18.31-.18-36.59.18-36.6C424.39,450.76,424.48,438.57,424.86,426.38Z" fill="#dbdbdb"/>
<path d="M424.86,502.21c-13.49.32-27,.47-40.49.6l-40.48.18-40.46-.18-20.24-.22-20.28-.38,20.25-.38,20.24-.23,40.49-.17,40.48.17C397.91,501.74,411.37,501.88,424.86,502.21Z" fill="#dbdbdb"/>
<path d="M424.86,467.65c-13.49.33-27,.47-40.49.61l-40.48.17-40.46-.17L283.19,468l-20.25-.39,20.25-.38,20.24-.22,40.49-.18,40.48.18C397.91,467.18,411.37,467.33,424.86,467.65Z" fill="#dbdbdb"/>
<polygon points="174.13 582.14 173.1 594.77 170.71 623.93 159.71 623.93 157.32 594.77 156.29 582.14 174.13 582.14" fill="#c7c7c7"/>
<polygon points="156.29 582.14 174.13 582.14 173.1 594.77 157.32 594.77 156.29 582.14" fill="#a6a6a6"/>
<polygon points="250.98 582.14 249.95 594.77 247.56 623.93 236.56 623.93 234.17 594.77 233.14 582.14 250.98 582.14" fill="#c7c7c7"/>
<polygon points="233.14 582.14 250.98 582.14 249.95 594.77 234.17 594.77 233.14 582.14" fill="#a6a6a6"/>
<polygon points="378.44 582.14 377.42 594.77 375.03 623.93 364.03 623.93 361.64 594.77 360.61 582.14 378.44 582.14" fill="#c7c7c7"/>
<polygon points="360.61 582.14 378.44 582.14 377.42 594.77 361.64 594.77 360.61 582.14" fill="#a6a6a6"/>
<polygon points="455.32 582.14 454.28 594.77 451.89 623.93 440.89 623.93 438.5 594.77 437.47 582.14 455.32 582.14" fill="#c7c7c7"/>
<polygon points="455.32 582.14 454.28 594.77 438.5 594.77 437.47 582.14 455.32 582.14" fill="#a6a6a6"/>
<rect x="175.4" y="127.2" width="253.39" height="10.88" fill="#ebebeb"/>
<polygon points="212.25 180.91 202.37 180.91 198.42 138.08 212.25 138.08 212.25 180.91" fill="#ebebeb"/>
<polygon points="391.94 180.91 401.82 180.91 405.78 138.08 391.94 138.08 391.94 180.91" fill="#ebebeb"/>
<polygon points="198.42 138.08 212.23 138.08 212.23 152.83 199.78 152.83 198.42 138.08" fill="#dbdbdb"/>
<polygon points="405.78 138.08 404.42 152.83 391.94 152.83 391.94 138.08 405.78 138.08" fill="#dbdbdb"/>
<path d="M267.16,61.94c-11.25,15.22-23,32.84-25.82,52a.26.26,0,0,0,.25.26.25.25,0,0,0,.24-.17,114,114,0,0,1,5-15.28c7.38-2,14.64-3.7,18.52-11s3.46-17.37,2.7-25.59C268,61.66,267.38,61.64,267.16,61.94Z" fill="#ebebeb"/>
<path d="M246.92,98.59a125.92,125.92,0,0,1,19.77-32m.09.09a136.1,136.1,0,0,0-13.54,21.23C257,84.1,261,80.7,264.56,76.7c0,0,.18,0,.12.12-3.5,4.19-7.38,8.75-11.81,11.81-1.22,2.26-2.46,4.53-3.72,6.79.31-.18.64-.33.95-.49m0,.09-1,.52c-.59,1.06-1.18,2.14-1.79,3.2-.11.3-.45.09-.34-.15Z" fill="#a6a6a6"/>
<path d="M250.67,94.64a67.6,67.6,0,0,0,8.64-5.76s.18,0,.1.1a46.21,46.21,0,0,1-8.62,5.91.14.14,0,0,1-.18-.07.12.12,0,0,1,.06-.18Z" fill="#a6a6a6"/>
<path d="M240.1,113.75c0,.24.42.22.42,0,0-6.29,0-12.6.1-18.92,1.61-3.25,5.06-5,7.47-7.66a33.37,33.37,0,0,0,4.43-6.25,45,45,0,0,0,5.2-17.34c.66-6.73-1.89-28.92-4.73-28.15-1.47.4-6.23,11.39-7.48,15a103.3,103.3,0,0,0-4.43,18.43C238.79,83.67,239,98.86,240.1,113.75Z" fill="#ebebeb"/>
<path d="M240.06,86.62h0a141.83,141.83,0,0,1,3.82-23.71c1.8-8.32,3.92-16.15,8.2-23.62,0-.14.28,0,.2.12A87.62,87.62,0,0,0,245.7,57.5c.29-.45.63-.87.93-1.3.12-.17.4,0,.28.16a11.29,11.29,0,0,1-1.33,1.89h0c-1.48,5.9-2.54,12-3.44,18.08l.21-.23h.09l-.36.6c-.46,3.07-.88,6.14-1.31,9.18a43,43,0,0,0,12.8-17h0a35.28,35.28,0,0,1-12.95,17.61c-.1.82-.22,1.64-.34,2.46,0,.17-.29.12-.29,0V86.77A.15.15,0,0,1,240.06,86.62Z" fill="#a6a6a6"/>
<path d="M242.64,75.09A124.48,124.48,0,0,0,253.8,55.9H254a61.86,61.86,0,0,1-11,19.35.16.16,0,0,1-.22.06A.17.17,0,0,1,242.64,75.09Z" fill="#a6a6a6"/>
<path d="M248.21,54.32c1.74-3.07,3.56-6,5.19-9.18,0-.09.17,0,.14.07a47.39,47.39,0,0,1-5.07,9.27.16.16,0,0,1-.23,0A.16.16,0,0,1,248.21,54.32Z" fill="#a6a6a6"/>
<path d="M237,97.63a63,63,0,0,1-1.47,12.4,11.1,11.1,0,0,0,.19,1.36A59.87,59.87,0,0,0,238,97.57a.45.45,0,0,0,0-.42h0a91.63,91.63,0,0,0-1.39-18.71c-1.95-11.56-6.2-22.66-14.26-31.31a.59.59,0,0,0-.83.08.36.36,0,0,0-.07.1c-3.25,8.27-2.11,18.14.67,26.39a47.73,47.73,0,0,0,6.39,12.54C231.26,90.1,234.79,93.4,237,97.63Z" fill="#ebebeb"/>
<path d="M223.29,51c7.65,12.4,13,27.08,13.61,41.73,0,.26-.43.34-.47.07-.18-1.31-.37-2.63-.59-3.93h0a50.43,50.43,0,0,1-8.67-10s0-.15.12,0A108.77,108.77,0,0,0,235.71,88c-.56-3.23-1.21-6.42-2-9.57-.2-.22-.4-.47-.6-.71s.09-.38.22-.22l.19.21a108.42,108.42,0,0,0-4-12.68A38.88,38.88,0,0,1,224,57.88s0-.13.1,0a57.55,57.55,0,0,0,3.55,4.68c.5.59,1.07,1.15,1.6,1.73a98.15,98.15,0,0,0-6.25-13,.19.19,0,1,1,.29-.26Z" fill="#a6a6a6"/>
<path d="M224.84,66.28c2.47,3.32,5.29,6.49,7.57,9.92,0,.1,0,.21-.16.13a51.34,51.34,0,0,1-7.57-10C224.6,66.26,224.77,66.18,224.84,66.28Z" fill="#a6a6a6"/>
<path d="M232.77,77l.1.11s0,.18-.12.11l-.1-.12C232.58,77.07,232.69,76.91,232.77,77Z" fill="#a6a6a6"/>
<path d="M210.15,71.68a37.83,37.83,0,0,0,8.06,18.91,20.07,20.07,0,0,0,6.53,5.11c2.83,1.4,5.8,3,8.72,4.16a58.11,58.11,0,0,1,3.1,11c.09-.32.18-.65.28-1-1.89-16.15-12.32-30-25.7-38.81a.65.65,0,0,0-.89.2A.66.66,0,0,0,210.15,71.68Z" fill="#ebebeb"/>
<path d="M214.76,76.45c-.09,0,0-.25.15-.18a55,55,0,0,1,17,21c.1.23-.21.42-.33.2-.62-1.08-1.25-2.14-1.9-3.19h0a18.34,18.34,0,0,1-8.21-4.77m.09-.09a18.87,18.87,0,0,0,3.85,2.72,33.17,33.17,0,0,0,3.88,1.47c-1.13-1.8-2.3-3.52-3.54-5.19a35.38,35.38,0,0,1-9.17-5.15.1.1,0,0,1,0-.13.1.1,0,0,1,.09,0,91.92,91.92,0,0,0,8.5,4.63,78.41,78.41,0,0,0-6-7c-1-.55-2.1-1.11-3.1-1.68a.09.09,0,0,1-.05-.12.07.07,0,0,1,.05,0,11,11,0,0,1,2.36,1.16,46.83,46.83,0,0,0-3.69-3.6Z" fill="#a6a6a6"/>
<path d="M215.05,82a4.87,4.87,0,0,1,.52.37v.09a4.07,4.07,0,0,1-.53-.31.09.09,0,0,1,0-.13Z" fill="#a6a6a6"/>
<polygon points="253.27 127.2 225.74 127.2 227.1 109.16 227.62 103.27 251.15 103.27 251.68 109.16 253.27 127.2" fill="#dbdbdb"/>
<polygon points="251.68 109.16 227.1 109.16 227.62 103.27 251.15 103.27 251.68 109.16" fill="#c7c7c7"/>
<rect x="225.74" y="98.45" width="27.28" height="6.04" fill="#dbdbdb"/>
<rect x="303.64" y="61.66" width="16.5" height="65.51" fill="#c7c7c7"/>
<rect x="303.65" y="58.15" width="16.5" height="7.2" fill="#dbdbdb"/>
<rect x="303.64" y="74.56" width="16.5" height="2.67" fill="#dbdbdb"/>
<rect x="303.64" y="111.36" width="16.5" height="7.2" fill="#dbdbdb"/>
<rect x="320.14" y="50.75" width="11.53" height="76.42" fill="#dbdbdb"/>
<rect x="322.4" y="57.92" width="6.92" height="29.39" fill="#ebebeb"/>
<rect x="376.78" y="57.92" width="11.53" height="76.42" transform="translate(45.24 300.6) rotate(-45.33)" fill="#c7c7c7"/>
<rect x="383.09" y="85.34" width="6.92" height="29.39" transform="translate(43.66 304.61) rotate(-45.33)" fill="#dbdbdb"/>
<rect x="331.69" y="69.13" width="19.57" height="58.04" fill="#a6a6a6"/>
<rect x="331.67" y="115.61" width="19.57" height="5.4" fill="#c7c7c7"/>
<rect x="331.69" y="109.96" width="19.57" height="2.1" fill="#c7c7c7"/>
<rect x="260.27" y="93.54" width="54.5" height="13.51" transform="translate(82.96 325.87) rotate(-67.03)" fill="#a6a6a6"/>
<rect x="276.77" y="110.14" width="5.08" height="13.52" transform="translate(61.72 327.46) rotate(-66.77)" fill="#c7c7c7"/>
<rect x="289.57" y="80.33" width="5.08" height="13.52" transform="translate(96.86 321.17) rotate(-66.77)" fill="#c7c7c7"/>
<rect x="288.36" y="86.77" width="1.98" height="13.52" transform="translate(89.28 322.54) rotate(-66.77)" fill="#c7c7c7"/>
<rect x="569.6" y="445.51" width="144.36" height="178.43" fill="#ebebeb"/>
<rect x="562.61" y="438.1" width="158.33" height="7.41" fill="#dbdbdb"/>
<rect x="720.95" y="438.1" width="49.79" height="7.41" fill="#ebebeb"/>
<rect x="713.96" y="445.51" width="48.91" height="178.43" fill="#dbdbdb"/>
<path d="M698.41,528.35H585.15v-64H698.41ZM585.52,528H698V464.69H585.52Z" fill="#c7c7c7"/>
<rect x="625.98" y="483.03" width="22.05" height="12.68" fill="#c7c7c7"/>
<path d="M654.76,494.93H632.31V483.8h22.45Zm-22.14-.37h21.69V484.23H632.62Z" fill="#c7c7c7"/>
<path d="M698.41,608.78H585.15v-64H698.41Zm-112.89-.37H698v-63.3H585.52Z" fill="#c7c7c7"/>
<rect x="625.98" y="563.46" width="22.05" height="12.68" fill="#c7c7c7"/>
<path d="M654.76,575.35H632.31V564.21h22.45ZM632.62,575h21.69V564.65H632.62Z" fill="#c7c7c7"/>
<polygon points="724.13 624.56 731.53 624.56 679.67 350.48 661.22 350.48 724.13 624.56" fill="#2f2e41" data-secondary="true"/>
<polygon points="661.22 350.48 670.53 391.01 687.33 391.01 679.68 350.52 679.67 350.48 661.22 350.48" opacity="0.2"/>
<polygon points="648.47 624.56 655.87 624.56 654.22 350.48 635.79 350.48 648.47 624.56" fill="#2f2e41" data-secondary="true"/>
<polygon points="635.79 350.48 637.66 391.01 654.47 391.01 654.22 350.52 654.22 350.48 635.79 350.48" opacity="0.2"/>
<polygon points="580.21 624.56 572.82 624.56 613.65 350.48 632.09 350.48 580.21 624.56" fill="#2f2e41" data-secondary="true"/>
<polygon points="607.61 391.01 624.41 391.01 632.09 350.48 613.65 350.48 613.64 350.52 607.61 391.01" opacity="0.2"/>
<rect x="595.4" y="507.14" width="107.62" height="5.35" fill="#2f2e41" data-secondary="true"/>
<ellipse cx="657.73" cy="244.11" rx="138.63" ry="98.46" transform="translate(381.44 888.99) rotate(-87.17)" fill="#0071f2" data-primary="true"/>
<polygon points="643.09 104.28 666.2 105.71 648.6 382.44 625.48 381.01 643.09 104.28" fill="#0071f2" data-primary="true"/>
<g opacity="0.1">
<polygon points="643.09 104.28 666.2 105.71 648.6 382.44 625.48 381.01 643.09 104.28"/>
</g>
<ellipse cx="636.45" cy="242.79" rx="138.63" ry="98.46" transform="translate(362.53 866.48) rotate(-87.17)" fill="#0071f2" data-primary="true"/>
<ellipse cx="636.45" cy="242.79" rx="108.14" ry="76.81" transform="translate(362.53 866.48) rotate(-87.17)" fill="#fff"/>
<ellipse cx="636.45" cy="242.79" rx="77.97" ry="55.37" transform="translate(362.53 866.48) rotate(-87.17)" fill="#0071f2" data-primary="true"/>
<ellipse cx="636.45" cy="242.79" rx="47.47" ry="33.71" transform="translate(362.53 866.48) rotate(-87.17)" fill="#fff"/>
<path d="M651.4,240.11c.8,11.63-5.25,22.16-13.52,23.67s-15.6-6.61-16.39-18.18,5.25-22.17,13.51-23.69S650.6,228.47,651.4,240.11Z" fill="#0071f2" data-primary="true"/>
<ellipse cx="636.45" cy="242.79" rx="138.63" ry="98.46" transform="translate(362.53 866.48) rotate(-87.17)" fill="#fff" opacity="0.4" style="isolation:isolate"/>
<path d="M528.17,536.16a361.87,361.87,0,0,0-.54-38.69,491.73,491.73,0,0,0-12.12-78.83c-3.38-14.58-7.54-28.93-11.88-43.25-.13-.44-.81-.31-.69.13,13.4,50.5,24.41,102.63,23.62,155.12-.21,14.76-1.91,29.13-3.31,43.73,0,.39.61.54.69.14C526.75,562.08,527.65,549,528.17,536.16Z" fill="#0071f2" data-primary="true"/>
<path d="M502.94,375.58s-20.33,51.58-15.78,63.7S501.09,454,501.09,454s-12.43,17.72-3.75,34.4,28.05,15.87,29.28,34.73C526.62,523.11,527.69,444.2,502.94,375.58Z" fill="#0071f2" data-primary="true"/>
<path d="M524.42,490.53a.66.66,0,0,0,0-.28,473.14,473.14,0,0,0-19.71-103.74c0-.09-.19,0-.16,0q6,22.62,10.67,45.49a22.46,22.46,0,0,0-9.7-5.4c-.07,0-.1.07,0,.1a25.64,25.64,0,0,1,10,6.69c.61,2.95,1.18,5.9,1.73,9-4.53-5.08-10.84-7.59-17.14-10-.09,0-.13.1,0,.13,6.57,2.67,13.09,6.11,17.55,11.81q2.33,12.84,4.07,25.76a24.51,24.51,0,0,0-12.11-6.94c-.14,0-.23.18-.08.22a25.59,25.59,0,0,1,12.28,7.87h.09c.4,3,.78,6.07,1.14,9.09a31.67,31.67,0,0,0-8.49-5.12c-.07,0-.12.1,0,.13a29.24,29.24,0,0,1,8.5,5.64.13.13,0,0,0,.12,0c.33,2.95.67,5.79,1,8.68a41.34,41.34,0,0,0-17.23-12.31.11.11,0,1,0-.07.21,45,45,0,0,1,17,13.08.4.4,0,0,0,.42.13c.45,4.43.85,8.86,1.17,13.28,0,0,.1.08.1,0C525.1,499.64,524.86,495.08,524.42,490.53Z" fill="#3f4347"/>
<path d="M508.09,421.52a25.43,25.43,0,0,0-12.21-3.81.08.08,0,0,0-.07.08.07.07,0,0,0,.07.07A49.39,49.39,0,0,1,508,421.8C508.1,421.88,508.24,421.63,508.09,421.52Z" fill="#3f4347"/>
<path d="M510.56,476.13a25.58,25.58,0,0,0-9.17-3.15c-.12,0-.12.16,0,.18a34.73,34.73,0,0,1,9.06,3.17C510.57,476.39,510.67,476.18,510.56,476.13Z" fill="#3f4347"/>
<path d="M581.57,440.12a139,139,0,0,0-23.51,20.55,84.62,84.62,0,0,0-16.49,28,208.9,208.9,0,0,0-12.28,66.9,161.76,161.76,0,0,0,3.61,37.62.37.37,0,0,0,.43.28.35.35,0,0,0,.28-.42,210.38,210.38,0,0,1,.37-65.74c3.49-21.35,9-44.56,22.53-61.9,7.38-9.43,16.59-16.86,25.7-24.54C582.68,440.43,582.08,439.77,581.57,440.12Z" fill="#0071f2" data-primary="true"/>
<path d="M532.24,540.18a126.61,126.61,0,0,1,17.15-21.91c10.16-10.17,18.72-17.39,20.05-24.11s-10.19-11.67-10.19-11.67,14.07,2.52,17.91-3.38,5.71-40.1,5.71-40.1-25.53,18.28-37.48,43.89S532.24,540.18,532.24,540.18Z" fill="#0071f2" data-primary="true"/>
<path d="M574.05,447.78c-10.77,10.59-21.6,21.85-27.95,35.74a139.33,139.33,0,0,0-5.65,14.76h0c-.33,1-.67,2-1,3a.49.49,0,0,0,0,.17,289,289,0,0,0-7.27,31.59s.1.1.11,0c1.1-5.33,2.32-10.72,3.68-16.09h.15a22.26,22.26,0,0,1,6.71-1.72c.15,0,.14-.28,0-.26a24.61,24.61,0,0,0-6.64,1.21c1.24-4.84,2.58-9.67,4.1-14.44a72,72,0,0,1,15.18-2v-.09A57.89,57.89,0,0,0,540.58,501c.25-.81.53-1.62.81-2.43a75.27,75.27,0,0,1,10.1-1.71m0-.12a49.17,49.17,0,0,0-9.89,1.21c1.4-4.12,2.95-8.18,4.58-12.14a70.35,70.35,0,0,1,4.82-9.38,61.53,61.53,0,0,1,8.2-1.48c.07,0,.07-.13,0-.13a22.17,22.17,0,0,0-7.77.84q2-3.25,4.27-6.36h0c5.74-1.27,11.56-2.45,17.43-1.35.09,0,.13-.16,0-.17-5.58-1.48-11.13-.62-16.7.47.6-.81,1.22-1.61,1.86-2.39A37.56,37.56,0,0,1,569,464.15a.06.06,0,1,0,0-.11,27.6,27.6,0,0,0-10,.88c4.74-5.9,10-11.44,15.16-16.92.31-.32.13-.41-.13-.22Z" fill="#3f4347"/>
<path d="M573.77,471.09a24.17,24.17,0,0,0-5.1-.18.2.2,0,0,0-.13.24.17.17,0,0,0,.13.13c1.69,0,3.38-.08,5.07,0a.1.1,0,0,0,.08-.12A.18.18,0,0,0,573.77,471.09Z" fill="#3f4347"/>
<path d="M555.34,504.26a23.38,23.38,0,0,0-7.88,1.58V506c2.61-.62,5.24-.87,7.88-1.31a.2.2,0,0,0,.19-.2A.19.19,0,0,0,555.34,504.26Z" fill="#3f4347"/>
<path d="M549.82,492.81a16.37,16.37,0,0,0-3.35.29c-.1,0-.1.21,0,.21a17.07,17.07,0,0,0,3.35-.16C550,493.12,550,492.81,549.82,492.81Z" fill="#3f4347"/>
<path d="M457.26,476.41a116.15,116.15,0,0,1,23.79,11.2,71,71,0,0,1,19.81,18.82,176.35,176.35,0,0,1,25.48,51.3A138,138,0,0,1,532.11,589a.31.31,0,0,1-.37.23.3.3,0,0,1-.24-.23A177.66,177.66,0,0,0,516,535.87c-7.76-16.46-17.55-34-32.47-44.88-8.17-5.9-17.33-9.82-26.47-13.92C456.44,476.91,456.78,476.24,457.26,476.41Z" fill="#0071f2" data-primary="true"/>
<path d="M520.3,546a106.15,106.15,0,0,0-18.94-13.76c-10.59-5.9-19.19-9.74-21.8-14.88s5.55-11.81,5.55-11.81-10.81,5.29-15.28,1.4-13.89-31.13-13.89-31.13,24.93,8.86,40.5,26.85S520.3,546,520.3,546Z" fill="#0071f2" data-primary="true"/>
<path d="M519,540.37C506.48,517,489.84,495.79,467,481.81h0a115,115,0,0,1,16.68,13.06,26.52,26.52,0,0,0-13.41,2.82.09.09,0,0,0,0,.13l.07,0a36.42,36.42,0,0,1,13.79-2.33h.14c.82.77,1.61,1.55,2.41,2.33a41.08,41.08,0,0,0-7.16,1m0,.09a36.82,36.82,0,0,1,7.56-.62,154.46,154.46,0,0,1,11.81,13.36,12,12,0,0,0-5,.35.1.1,0,0,0-.05.14l.05,0a25.86,25.86,0,0,1,5.35-.07c.69.87,1.37,1.73,2.05,2.61a48.21,48.21,0,0,0-15.13,1.48v.12a60,60,0,0,1,15.54-1c.64.84,1.24,1.71,1.86,2.57a32.54,32.54,0,0,0-9,1c-.12,0-.09.21,0,.18a34.79,34.79,0,0,1,9.33-.73c2.68,3.69,5.25,7.47,7.72,11.3a8.56,8.56,0,0,0-4,.23m0,.11a18,18,0,0,1,4.27.2c2.23,3.46,4.43,7,6.43,10.47.28.25.77,0,.56-.28Z" fill="#3f4347"/>
<path d="M499.6,521a19,19,0,0,0-7.25.88m0,.11a56.28,56.28,0,0,1,7.21-.74c.2,0,.2-.24,0-.25Z" fill="#3f4347"/>
<path d="M477.84,492.42a13.78,13.78,0,0,0-3.33.19.11.11,0,0,0-.11.11.11.11,0,0,0,.11.1c1.09-.12,2.17-.07,3.27-.1a.16.16,0,0,0,.18-.12A.16.16,0,0,0,477.84,492.42Z" fill="#3f4347"/>
<polygon points="552.45 623.37 496.18 623.37 504.19 564.59 506.25 549.54 542.37 549.54 544.42 564.59 552.45 623.37" fill="#3f4347"/>
<polygon points="544.42 564.59 504.19 564.59 506.25 549.54 542.37 549.54 544.42 564.59" fill="#2e3135"/>
<rect x="501.08" y="544.3" width="46.46" height="12.77" fill="#3f4347"/>
<path d="M223.65,476.08l3.1,18.14s1.31,8.66-4.74,13.88c0,0-16.17,14.38-15.35,35.13l-.49,58.48,14.37,2,34.64-91.48a32.86,32.86,0,0,0,5.71-17.65c0-.81-2.77-24.83-2.77-24.83Z" fill="#f9b499"/>
<path d="M230.51,646.31s11.92,1.3,7.68-12.91L222.5,602.2s-6.37-10.13-12.25-1.47c0,0-4.48,2.45-3.55-5,0,0-3-9.29-9.72-1.57a18.42,18.42,0,0,0-3.73,17.09l4.81,17a21.93,21.93,0,0,0,16.06,15.35A106.41,106.41,0,0,0,230.51,646.31Z" fill="#0071f2" data-primary="true"/>
<path d="M230.51,646.31s11.92,1.3,7.68-12.91L222.5,602.2s-6.37-10.13-12.25-1.47c0,0-4.48,2.45-3.55-5,0,0-3-9.29-9.72-1.57a18.42,18.42,0,0,0-3.73,17.09l4.81,17a21.93,21.93,0,0,0,16.06,15.35A106.41,106.41,0,0,0,230.51,646.31Z" opacity="0.2"/>
<path d="M173.33,613.47s-1-19.93-3.1-30.55c0,0-10-34.79,1-62.4,0,0,3.59-4.41,3.43-16.5l-2.78-23.2,41.33.49s-2.94,19.77-8.33,29.73c0,0-2.12,3.43-2,10.62,0,0-3.76,20.91-5.72,31.53,0,0-5.39,40.51-3.43,51.46L188.53,623l-9.81,1.63Z" fill="#f9b499"/>
<path d="M342.58,250.81l-1.8,12.74c0,.07,0,.13,0,.2.41,6-2.63,6.5-2.63,6.5l-8.65,2.12c-24.51,8.26-38.08,6.21-42.49,5.08a19,19,0,0,0-8.28-.33A37.65,37.65,0,0,0,266.61,282a17.51,17.51,0,0,1-4.51,2.82,23,23,0,0,1-9.24,2c-4.49.05-5.52,1.08-5.52,1.08-9.15,4.57-1.31,21.73-1.31,21.73,5.88,13.07,6.7,40.35,6.7,40.35a40.38,40.38,0,0,0,1.14,11.11c2.12,12.25.82,16.17.33,26.63,0,.26,0,.51,0,.76-.37,9.72,1.34,10.34,1.34,10.34,4.09,11.11,1.31,12.26,1.31,12.26-1.65,1.25-4,1.6-6.49,1.47a40.68,40.68,0,0,1-11.81-2.94c-7.18-3.11-7.35-1.47-7.35-1.47-1,4.34-9.46,1.59-14.1-.29A53.12,53.12,0,0,0,208,405c-21.3-4.53-34.34,0-34.34,0-6.15,2.22-10.09,2-11.42,1.88a5.08,5.08,0,0,1-.51-.08c-4.43-1-3.85-7-3.29-9.89a11,11,0,0,1,.6-2.1,9.23,9.23,0,0,0,.65-2.7,10.8,10.8,0,0,0-.72-4.8c-2-5.34,1.13-13.67,1.13-13.67,1.32-6.39,1.16-10.1.91-11.84a7.29,7.29,0,0,0-.46-1.72,6.69,6.69,0,0,1,.21-6.18,7.53,7.53,0,0,0,1.11-4.39c0-.34-.06-.66-.11-.95a7.11,7.11,0,0,0-.78-2.27,8.33,8.33,0,0,1-1-3.53l-.66-6.86c-.81-8.5-2.94-9.48-2.94-9.48,0,9-18.13,26.47-18.13,26.47-3.27,4.41-12.74,1.47-12.74,1.47a8.75,8.75,0,0,1-7.19-3.76c-3.76-4.08-2.78-16.82-2.78-16.82C115.67,321.87,118,322,118,322l10.78-37.57c12.58-18.3,23.86-16.66,23.86-16.66.65-2.45,4.24-2.78,4.24-2.78,2.78.49,3.6-1.14,3.6-1.14,4.08-8.33,13.48-10.9,13.48-10.9l49.61-8.28a8.41,8.41,0,0,1,8.79-1.24l9.47,2.28c35.94,3.6,91.16.49,91.16.49,5.79-1,8.12.52,9.05,2.07A4.28,4.28,0,0,1,342.58,250.81Z" fill="#0071f2" data-primary="true"/>
<g opacity="0.2">
<path d="M180.51,289.43h0a3.67,3.67,0,0,1-2.54-1.44l0,0c-2.07-4-6.59-6.77-6.63-6.8a30.14,30.14,0,0,1-10.21-10.29,15.63,15.63,0,0,1-2-5,.16.16,0,0,1,.14-.18.15.15,0,0,1,.18.13c0,.09,1.27,8.18,12,15.08,0,0,4.62,2.84,6.75,6.91a3.44,3.44,0,0,0,2.28,1.31h0a2.65,2.65,0,0,0,2-1.19,6.11,6.11,0,0,0,1.23-2.87c.39-2.49,1.33-6.7,3.26-7a.18.18,0,0,1,.19.14.16.16,0,0,1-.14.18c-1.24.17-2.36,2.67-3,6.69a6.4,6.4,0,0,1-1.3,3A3,3,0,0,1,180.51,289.43Z"/>
</g>
<g opacity="0.2">
<path d="M202.09,280.38c-3.25,0-6.85-6-7-6.29a.18.18,0,0,1,.06-.23.16.16,0,0,1,.22.06c0,.07,3.83,6.41,6.93,6.13,1.13-.11,2.06-1.12,2.74-3l5.4-12.1a.16.16,0,0,1,.22-.08.17.17,0,0,1,.08.22l-5.39,12.09c-.73,2-1.75,3.07-3,3.19Z"/>
</g>
<g opacity="0.2">
<path d="M234.43,279.23a.16.16,0,0,1-.14-.07l-4.73-7.51c-3.27-4.1-2-11.88-2-12.21a.18.18,0,0,1,.19-.14.16.16,0,0,1,.13.19c0,.08-1.25,8,1.93,12v0l4.74,7.51a.17.17,0,0,1,0,.23Z"/>
</g>
<g opacity="0.2">
<path d="M240.31,258.16a.16.16,0,0,1-.12-.06.17.17,0,0,1,0-.23c.16-.14,4-3.45,14.38-3.35a28,28,0,0,0,4.58-.3c3.19-.49,8.92-1.74,11.41-4.66a.16.16,0,1,1,.25.21c-2.56,3-8.37,4.28-11.61,4.77a28.69,28.69,0,0,1-4.64.31c-10.2-.1-14.11,3.23-14.15,3.27A.15.15,0,0,1,240.31,258.16Z"/>
</g>
<g opacity="0.2">
<path d="M246.85,261.75a.2.2,0,0,1-.14-.06.17.17,0,0,1,0-.23s4.38-3.14,12-2.81a.15.15,0,0,1,.15.17.17.17,0,0,1-.17.16c-7.53-.33-11.78,2.71-11.82,2.74Z"/>
</g>
<g opacity="0.2">
<path d="M157.32,273.51a.15.15,0,0,1-.16-.13c-.47-3.15-4.61-5.42-4.65-5.44a.16.16,0,0,1,.15-.29c.18.1,4.33,2.37,4.82,5.68a.15.15,0,0,1-.13.18Z"/>
</g>
<g opacity="0.2">
<path d="M228.39,409.11a.18.18,0,0,1-.17-.14c-3.2-17.47-10.6-41.87-10.77-42.45-3.88-9.06-4.41-14-4.42-14.08-1.45-16.61-11.16-37.48-11.26-37.69-6.15-13.76-6.22-24.47-6.22-24.57a.17.17,0,0,1,.16-.17.18.18,0,0,1,.17.17c0,.1.07,10.75,6.19,24.44.1.2,9.83,21.12,11.29,37.78,0,.05.53,5,4.39,14v0c.07.25,7.55,24.88,10.79,42.49a.17.17,0,0,1-.14.19Z"/>
</g>
<g opacity="0.2">
<path d="M239.82,383.78h0a.16.16,0,0,1-.14-.18c0-.12,1.68-11.34,6.05-16.71.21-1,3-13.8,5.29-15.26a.16.16,0,0,1,.23.05.15.15,0,0,1,0,.22c-2.2,1.42-5.13,15-5.16,15.09a.09.09,0,0,1,0,.07c-4.33,5.3-6,16.47-6,16.58A.15.15,0,0,1,239.82,383.78Z"/>
</g>
<g opacity="0.2">
<path d="M228.22,317a.17.17,0,0,1-.14-.08.18.18,0,0,1,.06-.23s4-2.33,2.86-9.47c0-.06-.95-6.35,3.52-8.66a.16.16,0,1,1,.15.29c-4.26,2.2-3.36,8.26-3.35,8.32,1.15,7.38-3,9.79-3,9.81Z"/>
</g>
<g opacity="0.2">
<path d="M235.25,292a.16.16,0,0,1-.15-.09.16.16,0,0,1,.08-.22l4.93-2.35a14.32,14.32,0,0,1,3.88-1.22A15.81,15.81,0,0,0,249.7,286a.18.18,0,0,1,.23.06.16.16,0,0,1-.06.22,16.27,16.27,0,0,1-5.83,2.19,14,14,0,0,0-3.79,1.18L235.32,292Z"/>
</g>
<g opacity="0.2">
<path d="M156.5,318.77l-.09,0c-.13-.1-1.18-1.06,1.92-6.1v0a5.74,5.74,0,0,0,.79-4.92.15.15,0,0,1,0-.13.19.19,0,0,1,.11-.07s1.52-.68,1.83-10.63a.17.17,0,0,1,.17-.16.17.17,0,0,1,.16.17c-.28,8.81-1.48,10.53-1.94,10.86a6,6,0,0,1-.87,5.08c-2.92,4.76-2,5.65-2,5.65a.18.18,0,0,1,0,.23A.17.17,0,0,1,156.5,318.77Z"/>
</g>
<g opacity="0.2">
<path d="M202.41,358.14h0c-10.25-2.62-20.43-11.43-27.17-18.36a136.18,136.18,0,0,1-12.29-14.54.16.16,0,0,1,0-.23.16.16,0,0,1,.22,0,135.68,135.68,0,0,0,12.26,14.51c6.71,6.89,16.85,15.66,27,18.26a.17.17,0,0,1,.12.2A.17.17,0,0,1,202.41,358.14Z"/>
</g>
<g opacity="0.2">
<path d="M192.12,360.26h0c-6.12-.43-9.16-2.07-10.64-3.37a5.06,5.06,0,0,1-1.75-2.72c-6.62-2.77-7.8-6.61-7.85-6.77a.16.16,0,1,1,.31-.09s1.21,3.88,7.75,6.59a.17.17,0,0,1,.1.14,4.54,4.54,0,0,0,1.69,2.63c1.43,1.26,4.41,2.85,10.41,3.26a.17.17,0,0,1,.15.18A.16.16,0,0,1,192.12,360.26Z"/>
</g>
<g opacity="0.2">
<path d="M124.94,348.39a40.06,40.06,0,0,1-5.54-.38.17.17,0,1,1,0-.33c.1,0,10,1.59,16.23-1.78a.2.2,0,0,1,.15,0,5.35,5.35,0,0,0,4.18-.09c2.57-1.12,4.6-4.08,6.05-8.8a.16.16,0,0,1,.2-.1.15.15,0,0,1,.11.2c-1.48,4.82-3.57,7.85-6.24,9a5.59,5.59,0,0,1-4.36.12C132.49,348,128.27,348.39,124.94,348.39Z"/>
</g>
<g opacity="0.2">
<path d="M145.72,332a.16.16,0,0,1-.16-.15c-.32-3.33-5.28-7.69-5.33-7.73a.16.16,0,1,1,.21-.25c.21.18,5.12,4.49,5.45,7.95a.17.17,0,0,1-.15.18Z"/>
</g>
<g opacity="0.2">
<path d="M145.23,319.58a.15.15,0,0,1-.11,0,14.67,14.67,0,0,0-6-3.06.17.17,0,0,1-.12-.2.16.16,0,0,1,.2-.12,15.14,15.14,0,0,1,6.12,3.14.16.16,0,0,1,0,.23A.13.13,0,0,1,145.23,319.58Z"/>
</g>
<path d="M139.52,258.32l-30.91,11.36a2.36,2.36,0,0,1-.78.16,2.52,2.52,0,0,1-2.46-1.72.14.14,0,0,0,0-.06,2.64,2.64,0,0,1-.11-.73,2.61,2.61,0,0,1,.05-.48,2.53,2.53,0,0,1,1.74-1.92l1.2-.36,30.14-9Z" fill="#0071f2" data-primary="true"/>
<polygon points="138.37 255.54 148.66 253.75 139.52 258.32 138.37 255.54" fill="#2f2e41" data-secondary="true"/>
<path d="M108.23,264.57l-1.2.36a2.53,2.53,0,0,0-1.74,1.92h0l-8.39-6.09s-2-1.33-1.85-3a1.86,1.86,0,0,1,1.64-1.59C98.69,255.91,103.64,256.31,108.23,264.57Z" fill="#2f2e41" data-secondary="true"/>
<path d="M107.83,269.84c-2.78,5.76-5.49,7.23-7,7.56A1.48,1.48,0,0,1,99,276c-.15-2.94,4.43-6.58,6.36-8a.14.14,0,0,1,0,.06A2.52,2.52,0,0,0,107.83,269.84Z" fill="#2f2e41" data-secondary="true"/>
<path d="M393,257.65l-4,1.65s6.19,2,5.07,5a.47.47,0,0,1-.53.3c-1.83-.37-10.21-1.94-14.31-.87a16.05,16.05,0,0,1-3.22.54,42,42,0,0,1-13.54-1.54,14.08,14.08,0,0,0-4.92-.44l-16.73,1.44c0-.07,0-.13,0-.2l1.8-12.74a4.28,4.28,0,0,0-.59-2.51c.74-.13,4.56-.63,13,.38,0,0,6.05,1.15,10.78-2l7.52-5.55s7-4.57,11.92.16c0,0,5.88-2.61,6.86,3.76,0,0,6.7-1.63,5.56,6,0,0,9.31-2.45,10,.82,0,0,2.65,2.5-10,4.43A19.42,19.42,0,0,0,393,257.65Z" fill="#f9b499"/>
<line x1="385.21" y1="241.33" x2="379.66" y2="242.48" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="392.07" y1="245.09" x2="387.5" y2="246.4" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="397.63" y1="251.13" x2="389.95" y2="252.28" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path d="M382.76,258.65a14,14,0,0,1,6.21.65" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path d="M262.53,468.9c-1,6.2-14.21,8.82-14.21,8.82-15.2,3.43-24.84.32-24.84.32-2.61,0-3.43-5.06-3.43-5.06-2.45-.49-2,5.55-2,5.55,0,7-6.2,5.72-6.2,5.72-20.56,4.9-36.69.57-40.91-.77A1.92,1.92,0,0,1,169.7,482l-3.07-16.39c-2.28-8.17-1.47-12.25-1.47-12.25A104.37,104.37,0,0,0,163,424.79c-1.21-9.94-1.14-15.17-.8-17.89,1.33.16,5.27.34,11.42-1.88,0,0,13-4.53,34.34,0a53.12,53.12,0,0,1,9.06,2.82c4.64,1.88,13.05,4.63,14.1.29,0,0,.17-1.64,7.35,1.47a40.68,40.68,0,0,0,11.81,2.94c1.21,10.47,7,25.81,7,25.81,2.61,8.33,1.63,10.13,1.63,10.13-.49,7.51,1,11.92,1,11.92A16.29,16.29,0,0,1,262.53,468.9Z" fill="#2f2e41" data-secondary="true"/>
<g opacity="0.2">
<path d="M177.74,477.72a.16.16,0,0,1-.15-.12c-3.56-11.65-2.8-25.4-2.79-25.54.64-9.77-2.38-13.74-2.41-13.77a.09.09,0,0,1,0-.06c-4.05-15.07.28-31,.32-31.13a.17.17,0,0,1,.32.09c0,.16-4.35,16-.34,30.92.3.39,3.1,4.38,2.47,14,0,.14-.77,13.83,2.77,25.43a.16.16,0,0,1-.11.2Z"/>
</g>
<g opacity="0.2">
<path d="M171.13,420.41a.17.17,0,0,1-.17-.16.18.18,0,0,1,.17-.17,24.58,24.58,0,0,0,9-2.15A21.86,21.86,0,0,0,192.46,403a.16.16,0,0,1,.2-.11.16.16,0,0,1,.12.2,22.16,22.16,0,0,1-12.55,15.13,25.13,25.13,0,0,1-9.1,2.18Z"/>
</g>
<g opacity="0.2">
<path d="M220.05,473.14a.16.16,0,0,1-.16-.16l-.54-36.35a15.5,15.5,0,0,1,5.48-12.1L227,422.7a.16.16,0,0,1,.21.25L225,424.78a15.2,15.2,0,0,0-5.37,11.85l.55,36.35a.16.16,0,0,1-.16.16Z"/>
</g>
<g opacity="0.2">
<path d="M245.37,472.65l-.09,0a.16.16,0,0,1,0-.22l5.53-7.8c0-1.23.06-5,.74-5.33.4-.22,2.19-4.32,3.68-8.08a.17.17,0,0,1,.21-.09.16.16,0,0,1,.09.21c-.52,1.32-3.16,7.92-3.83,8.26-.35.17-.57,2.77-.57,5.08a.14.14,0,0,1,0,.09l-5.55,7.84A.15.15,0,0,1,245.37,472.65Z"/>
</g>
<g opacity="0.2">
<path d="M249.62,473.14l-.09,0a.16.16,0,0,1,0-.22l5.39-7.84a.16.16,0,0,1,.23-.05.17.17,0,0,1,0,.23l-5.39,7.84A.16.16,0,0,1,249.62,473.14Z"/>
</g>
<path d="M180.85,617.88s2.77,1.31.49-5.39c0,0-4.58-8.82,4.9-11.27,0,0,6.86-2.29,10,3.76,0,0,36.27,34.79,26,41.33,0,0-2.45,2.61-17.81,1.79,0,0-14.05-2.12-21.73-1.3,0,0-14.21,2.61-14.21-5.39l.49-21.57s-1-10.45,5.07-8.66C174,611.18,178.4,612.33,180.85,617.88Z" fill="#0071f2" data-primary="true"/>
<path d="M175.46,235.45s2.94,13.56-3.11,19.61l-4.9,6.53s2.13,4.74,10.78,8.82c0,0,13.24,4.25,15.2,17.15,0,0,2,.82-.66-8.82,0,0-2.28-6,3.76-7.68,0,0,9.26-4.9,4.3-12.41L195.71,249l-11.6-18.3-7-.07Z" fill="#f9b499"/>
<path d="M199.32,255.72l2.33,4.57a6.84,6.84,0,0,1-1,7.29s-12.27-.88-15.13-18.46Z" fill="#f7a48b"/>
<rect x="181.83" y="193.47" width="43.13" height="65.02" rx="21.56" fill="#f9b499"/>
<path d="M196.53,218.79s-2.91,12.52-8.8,6l-9.23,9.69s-.92,6.35-6.15,3.41c0,0-14.54-19.11-10.62-32.67,0,0,.49-1.31-1-3.1,0,0-2.94-3.27.17-5.89a6,6,0,0,0,.81-4.24s-1.63-7.68,6.21-13.4c0,0,5.72-6.37,13.56-2,0,0,2.29-5.39,7.84-.33,0,0,4.41-5.88,10.62-2.45,0,0,3.43.33,3.43,5.56,0,0,6.05-.66,6.7,3.1,0,0,2.94-2.12,8.49.82,0,0,2.62.49,3.43,6.37,0,0-.65,2.78,3.27,3.27,0,0,6.05,1,4.9,7.84,0,0-1.47,8.66-11.11,3.76,0,0-12.25-1.31-15,6.37,0,0,.33,5.55-6.37,6C197.67,217,196.37,216.5,196.53,218.79Z" fill="#2f2e41" data-secondary="true"/>
<g opacity="0.2">
<path d="M204.38,205.74a4,4,0,0,1-2.95-1.48,2.41,2.41,0,0,0-.4-.35c-.24-.13-.49-.24-.72-.34a5,5,0,0,0-4.25.12c-4.1,2.05-6.79.89-8.34-.45-1.22-1.07-1.91-2.47-1.8-2.8a.16.16,0,0,1,.21-.1.15.15,0,0,1,.1.19,5.64,5.64,0,0,0,2.29,2.91c1.41,1,3.84,1.74,7.4,0a5.34,5.34,0,0,1,4.52-.13c.24.1.49.22.74.34a2.28,2.28,0,0,1,.48.42c.88.9,2.52,2.57,6.05.09a.16.16,0,0,1,.23,0,.16.16,0,0,1,0,.22A6.24,6.24,0,0,1,204.38,205.74Zm-18.15-5.2Z"/>
</g>
<g opacity="0.2">
<path d="M170.72,186.77h-.05a.17.17,0,0,1-.11-.2,9.24,9.24,0,0,1,4.38-5.16,8.74,8.74,0,0,1,7.11.15.17.17,0,0,1,.09.22.17.17,0,0,1-.21.09,8.37,8.37,0,0,0-6.85-.16,9.12,9.12,0,0,0-4.21,5A.16.16,0,0,1,170.72,186.77Z"/>
</g>
<g opacity="0.2">
<path d="M164.47,203a6.23,6.23,0,0,1-2.48-.52.17.17,0,1,1,.14-.3,5.71,5.71,0,0,0,4.07.19,5.94,5.94,0,0,0,3.22-3.53.16.16,0,0,1,.22-.09.17.17,0,0,1,.09.21,6.26,6.26,0,0,1-3.42,3.71A5.23,5.23,0,0,1,164.47,203Z"/>
</g>
<g opacity="0.2">
<path d="M212.54,187.75a.15.15,0,0,1-.15-.1c-.41-1-.93-1.61-1.56-1.76a2,2,0,0,0-1.61.51.17.17,0,0,1-.12,0,.14.14,0,0,1-.12-.06c-.83-1-1.63-1.47-2.39-1.37-1.29.19-2.06,2-2.07,2a.15.15,0,0,1-.18.09.15.15,0,0,1-.13-.16c0-3.2-3.75-5-4-5.07-6.3-1.73-8.59,4.41-8.61,4.47a.16.16,0,0,1-.21.1.17.17,0,0,1-.1-.21c0-.06,2.42-6.49,9-4.67h0c.16.07,3.73,1.67,4.15,4.78a3.15,3.15,0,0,1,2-1.65,3,3,0,0,1,2.59,1.36,2.28,2.28,0,0,1,1.77-.48c.74.17,1.34.83,1.79,2a.17.17,0,0,1-.09.21Z"/>
</g>
<g opacity="0.2">
<path d="M217.44,201.64l-.06,0c-2.08-.83-3.34-1.93-3.75-3.27a3.51,3.51,0,0,1,.41-2.85.15.15,0,0,1,.22,0,.15.15,0,0,1,.05.22,3.28,3.28,0,0,0-.37,2.58c.38,1.24,1.58,2.27,3.56,3.06a.17.17,0,0,1-.06.32Z"/>
</g>
<g opacity="0.2">
<path d="M223.65,202.06a4.13,4.13,0,0,1-2.56-.89,6.45,6.45,0,0,1-2.34-4.76.17.17,0,0,1,.16-.17h0a.17.17,0,0,1,.16.17,6.28,6.28,0,0,0,2.22,4.51,3.84,3.84,0,0,0,3.07.75,3.66,3.66,0,0,0,2.48-1.74l.09-.17a.18.18,0,0,1,.23-.07.17.17,0,0,1,.06.23l-.1.18a4,4,0,0,1-2.7,1.89A4.08,4.08,0,0,1,223.65,202.06Z"/>
</g>
<g opacity="0.2">
<path d="M192.47,216.58a7.25,7.25,0,0,1-4.68-1.63,8.32,8.32,0,0,1-2.36-3.13.16.16,0,0,1,.1-.21.17.17,0,0,1,.21.1,8,8,0,0,0,2.27,3c2.14,1.74,4.88,2,8.14.82a.16.16,0,0,1,.21.1.17.17,0,0,1-.1.21A11.13,11.13,0,0,1,192.47,216.58Z"/>
</g>
<ellipse cx="181.83" cy="227.04" rx="5.88" ry="8.74" fill="#f9b499"/>
<path d="M120.4,289.36l-2.94,41s2.62,7.36,12.58,6.05c0,0,11.76-1.14,8.82-13.07s-7-32.67-7-32.67,3.1-5.72,1.31-14.54a8.58,8.58,0,0,1,0-3.43s.16-2.13-1.64-2.62c0,0,8.17-9,1.31-8.16,0,0,3.43-4.58-2.45-4.09,0,0-.66-4.9-8-2,0,0-15.22,6.53-12.64,20.33a3.31,3.31,0,0,0,1,1.77C112.85,280.09,119.32,286.52,120.4,289.36Z" fill="#f9b499"/>
<path d="M115.34,267.47l-.08,0a.15.15,0,0,1-.06-.22,20.65,20.65,0,0,1,15.15-9.56.16.16,0,1,1,0,.32,20.36,20.36,0,0,0-14.91,9.4A.16.16,0,0,1,115.34,267.47Z" fill="#f7a48b"/>
<path d="M119.75,274.82a.18.18,0,0,1-.13-.06.17.17,0,0,1,0-.23s4.77-3.95,8.16-7c0,0,2.95-3.12,4.88-5.69a.16.16,0,0,1,.23,0,.16.16,0,0,1,0,.22c-1.94,2.6-4.88,5.71-4.91,5.74-3.41,3.08-8.14,7-8.19,7A.13.13,0,0,1,119.75,274.82Z" fill="#f7a48b"/>
<path d="M120.89,270.9a.19.19,0,0,1-.1,0,.16.16,0,0,1,0-.23c0-.06,4.75-5.93,11.14-7.73a.16.16,0,0,1,.2.11.15.15,0,0,1-.11.2c-6.29,1.77-10.93,7.56-11,7.62A.16.16,0,0,1,120.89,270.9Z" fill="#f7a48b"/>
<path d="M129.71,285.6a.16.16,0,0,1-.16-.16c0-3.19-2.57-8.37-2.6-8.42-1.51-3.7,4.24-6.94,4.48-7.08a.17.17,0,0,1,.22.06.17.17,0,0,1-.06.23c-.06,0-5.74,3.24-4.34,6.65.1.21,2.63,5.29,2.63,8.56A.17.17,0,0,1,129.71,285.6Z" fill="#f7a48b"/>
</svg>

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

View File

@ -0,0 +1,4 @@
/*!**************************************************************************************************************************************************************************************************************************************************!*\
!*** css ../../node_modules/.pnpm/css-loader@6.7.3_webpack@5.75.0/node_modules/css-loader/dist/cjs.js!../../node_modules/.pnpm/less-loader@4.1.0_less@3.8.0+webpack@5.75.0/node_modules/less-loader/dist/cjs.js!./src/view/page/home/index.less ***!
\**************************************************************************************************************************************************************************************************************************************************/

View File

@ -0,0 +1,79 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/view/page/home/index.less":
/*!***************************************!*\
!*** ./src/view/page/home/index.less ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n\n\n//# sourceURL=webpack://@backset/server/./src/view/page/home/index.less?");
/***/ }),
/***/ "./src/view/page/home/index.ts":
/*!*************************************!*\
!*** ./src/view/page/home/index.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n__webpack_require__(/*! ./index.less */ \"./src/view/page/home/index.less\");\nconsole.log('use ts wepack');\n\n\n//# sourceURL=webpack://@backset/server/./src/view/page/home/index.ts?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./src/view/page/home/index.ts");
/******/
/******/ })()
;

4319
apps/server/public/login.css Normal file

File diff suppressed because it is too large Load Diff

526
apps/server/public/login.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/view/page/notFound/index.less":
/*!*******************************************!*\
!*** ./src/view/page/notFound/index.less ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n\n\n//# sourceURL=webpack://@backset/server/./src/view/page/notFound/index.less?");
/***/ }),
/***/ "./src/view/page/notFound/index.ts":
/*!*****************************************!*\
!*** ./src/view/page/notFound/index.ts ***!
\*****************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n__webpack_require__(/*! ./index.less */ \"./src/view/page/notFound/index.less\");\n\n\n//# sourceURL=webpack://@backset/server/./src/view/page/notFound/index.ts?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./src/view/page/notFound/index.ts");
/******/
/******/ })()
;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,63 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { writeFile } = require('fs/promises');
const inquirer = require('inquirer');
const { join } = require('path');
const chalk = require('chalk');
const upper1st = (word) => word.charAt(0).toUpperCase() + word.slice(1);
const controller = (name) => `import { Controller } from '@nestjs/common';
import { ${upper1st(name)}Service } from 'src/service/${name}.service';
@Controller()
export class ${upper1st(name)}Controller {
constructor(private readonly ${name}Service: ${upper1st(name)}Service) {}
}
`;
const mod = (name) => `import { Module } from '@nestjs/common';
import { ${upper1st(name)}Controller } from 'src/controller/${name}.controller';
import { ${upper1st(name)}Service } from 'src/service/${name}.service';
@Module({
controllers: [${upper1st(name)}Controller],
providers: [${upper1st(name)}Service],
})
export class ${upper1st(name)}Module {}
`;
const impl = (name) => `export interface ${upper1st(name)}ServiceImpl {}`;
const service = (name) => `import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { ${upper1st(name)}ServiceImpl } from './impl/${name}.interface';
@Injectable()
export class ${upper1st(name)}Service implements ${upper1st(name)}ServiceImpl {
constructor(@InjectDataSource() private db: DataSource) {}
}
`;
inquirer
.prompt([
{
type: 'input',
name: 'name',
message: '输入模块名称',
},
])
.then(async (res) => {
const { name } = res;
const controllerDir = join(process.cwd(), 'src/controller');
const moduleDir = join(process.cwd(), 'src/module');
const implDir = join(process.cwd(), 'src/service/impl');
const serviceDir = join(process.cwd(), 'src/service');
await writeFile(`${controllerDir}/${name}.controller.ts`, controller(name));
await writeFile(`${moduleDir}/${name}.module.ts`, mod(name));
await writeFile(`${implDir}/${name}.interface.ts`, impl(name));
await writeFile(`${serviceDir}/${name}.service.ts`, service(name));
console.log(
chalk.blue(`! 请在 app.module.ts 中imports: [${upper1st(name)}Module]`),
);
});

View File

@ -0,0 +1,42 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { mkdir, writeFile } = require('fs/promises');
const inquirer = require('inquirer');
const { join } = require('path');
const less = () => `@import '../../less/common.less';
@import '../../less/var.less';
`;
const ts = (name) => `import './index.less';
console.log('${name}');
`;
const ejs = (name) => `<!DOCTYPE html>
<html lang="en">
<head>
<%- include('../_layout/base') -%>
<title>new page: <%= name %></title>
</head>
<body>
<p>${name}</p>
</body>
</html>
`;
inquirer
.prompt([
{
type: 'input',
name: 'name',
message: '输入页面文件夹名称',
},
])
.then(async (res) => {
const { name } = res;
const targetDir = join(process.cwd(), 'src/view/pages', name);
await mkdir(targetDir);
await writeFile(`${targetDir}/index.ts`, ts(name));
await writeFile(`${targetDir}/index.ejs`, ejs(name));
await writeFile(`${targetDir}/index.less`, less());
});

View File

@ -1,13 +0,0 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { EncryptUtil } from '@backset/util';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return EncryptUtil.md5('原文字符');
}
}

View File

@ -1,10 +1,22 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './module/user.module';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { mongo, mysql } from './config/db';
import { MongooseModule } from '@nestjs/mongoose';
import { BaseModule } from './module/base.module';
import { SmsModule } from './module/sms.module';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: ['.env.dev', '.env', '.env.prod'],
}),
TypeOrmModule.forRoot(mysql),
MongooseModule.forRoot(mongo),
UserModule,
BaseModule,
SmsModule,
],
})
export class AppModule {}

View File

@ -1,8 +0,0 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}

View File

@ -0,0 +1,4 @@
export enum BizStatus {
OK = 1,
FAIL = -99,
}

View File

@ -0,0 +1,21 @@
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
/**
* typeorm Mysql,
*/
export const mysql: TypeOrmModuleOptions = {
type: 'mysql',
host: 'mozzie.cn',
port: 6033,
username: 'root',
password: 'cr654654.',
database: 'backset',
entities: [],
synchronize: true,
autoLoadEntities: true,
};
/**
* mongodb
*/
export const mongo = 'mongodb://backset:cr654654.@mozzie.cn:37017/backset';

View File

@ -0,0 +1,4 @@
/**
* axios baseURL
*/
export const PREFIX = '';

View File

@ -0,0 +1,23 @@
import { NestExpressApplication } from '@nestjs/platform-express';
const { ASSETS_URL } = process.env;
// 全局变量
const TEMPLATE_GLOBAL_VARS = {
/**
* home.js?v={version}
*/
version: Date.now(),
/**
*! nestjs public , ASSETS_URL /, cdn , cdn url
*/
assets: ASSETS_URL,
};
/**
*
*/
export const injectTemplateVars = (app: NestExpressApplication) => {
for (const [k, v] of Object.entries(TEMPLATE_GLOBAL_VARS)) {
app.setLocal(k, v);
}
};

View File

@ -0,0 +1,27 @@
import { Controller, Get, Render } from '@nestjs/common';
/**
* @Render {name: xxx} ,
* webpack构建单页面输出的 js / css资源的打包到public下的静态资源名称
*/
@Controller()
export class BaseController {
@Get('/')
@Render('page/home/index')
async homeViewModel() {
return { name: 'home' };
}
@Get('/signup')
@Render('page/signup/index')
async signupViewModel() {
return { name: 'signup' };
}
@Get('/login')
@Render('page/login/index')
async loginViewModel() {
return { name: 'login' };
}
}

View File

@ -0,0 +1,16 @@
import { Body, Controller, Post } from '@nestjs/common';
import { BizStatus } from 'src/config/biz.code';
import { IVerifyCodeRequest } from 'src/dto/sms.dto';
import { SmsService } from 'src/service/sms.service';
@Controller('/sms')
export class SmsController {
constructor(private readonly smsService: SmsService) {}
@Post('/verifycode')
async verifycode(@Body() params: IVerifyCodeRequest) {
const { phone } = params;
const verifycode = this.smsService.getVerifyCode({ phone });
return { code: BizStatus.OK, data: verifycode };
}
}

View File

@ -0,0 +1,31 @@
import { Body, Controller, Get, Post, Render } from '@nestjs/common';
import { BizStatus } from 'src/config/biz.code';
import { IUserRequest } from 'src/dto/user.dto';
import { UserService } from 'src/service/user.service';
@Controller('/user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get('/topic')
@Render('pages/topic/index')
async topic() {
return { name: 'topic' };
}
@Get('/course')
@Render('pages/course/index')
async course() {
return { name: 'course' };
}
@Post('/create')
async create(@Body() params: IUserRequest) {
try {
await this.userService.createUser(params);
return { code: BizStatus.OK, data: params };
} catch (error) {
console.log(error);
}
}
}

View File

@ -0,0 +1,3 @@
export interface IVerifyCodeRequest {
phone: string;
}

View File

@ -0,0 +1,12 @@
export interface IUserRequest {
user_login: string;
user_pass: string;
user_phone: number | string;
}
export interface IUserLoginRequest {
login_type: 'password' | 'verifycode';
user_login: string | number;
user_pass?: string;
verify_code?: string | number;
}

View File

@ -0,0 +1,30 @@
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { execPath } from 'process';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
const message = exception.message;
switch (status) {
case 404:
response.render('page/notFound/index', { name: 'notFound' });
break;
default:
response.status(status).json({
code: status,
message,
});
break;
}
}
}

View File

@ -1,8 +1,26 @@
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';
import { PREFIX } from './config/router';
import { injectTemplateVars } from './config/template.var';
const { PORT = 4000 } = process.env;
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const logger: Logger = new Logger('main.ts');
app
.useStaticAssets(join(process.cwd(), 'public'), { prefix: '/' })
.setViewEngine('ejs')
.setBaseViewsDir(join(process.cwd(), 'src/view'))
.setGlobalPrefix(PREFIX);
injectTemplateVars(app);
await app.listen(PORT, () => {
logger.log(`服务已启动,访问:http://localhost:${PORT}/${PREFIX}`);
});
}
bootstrap();

View File

@ -0,0 +1,7 @@
import { Module } from '@nestjs/common';
import { BaseController } from 'src/controller/base.controller';
@Module({
controllers: [BaseController],
})
export class BaseModule {}

View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { SmsController } from 'src/controller/sms.controller';
import { SmsService } from 'src/service/sms.service';
@Module({
controllers: [SmsController],
providers: [SmsService],
})
export class SmsModule {}

View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { UserController } from 'src/controller/user.controller';
import { UserService } from 'src/service/user.service';
@Module({
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}

View File

@ -0,0 +1,11 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
export type SubscribeDocument = Subscribe & Document;
@Schema({ collection: 'subscribe_plan' })
export class Subscribe extends Document {
@Prop({ required: true })
title: string;
}
export const SubscribeSchema = SchemaFactory.createForClass(Subscribe);

View File

@ -0,0 +1,8 @@
import { IVerifyCodeRequest } from 'src/dto/sms.dto';
export interface SmsServiceImpl {
/**
*
*/
getVerifyCode(p: IVerifyCodeRequest): number;
}

View File

@ -0,0 +1,5 @@
import { IUserRequest } from 'src/dto/user.dto';
export interface UserServiceImpl {
createUser(p: IUserRequest): Promise<boolean>;
}

View File

@ -0,0 +1,14 @@
import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { IVerifyCodeRequest } from 'src/dto/sms.dto';
import { DataSource } from 'typeorm';
import { SmsServiceImpl } from './impl/sms.interface';
@Injectable()
export class SmsService implements SmsServiceImpl {
constructor(@InjectDataSource() private db: DataSource) {}
getVerifyCode(p: IVerifyCodeRequest): number {
return 303404;
}
}

View File

@ -0,0 +1,26 @@
import { EncryptUtil } from '@backset/util';
import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { IUserRequest } from 'src/dto/user.dto';
import { DataSource } from 'typeorm';
import { UserServiceImpl } from './impl/user.interface';
@Injectable()
export class UserService implements UserServiceImpl {
constructor(@InjectDataSource() private db: DataSource) {}
async createUser(p: IUserRequest): Promise<boolean> {
const create_sql = `INSERT INTO backset.user(user_login,user_pass,user_phone,user_create_time) VALUES(?,?,?,?)`;
const { affectedRows } = await this.db.query(create_sql, [
p.user_login,
EncryptUtil.md5(p.user_pass),
p.user_phone,
Date.now(),
]);
return affectedRows === 1;
}
async getUser() {
return await this.db.query(`select * from user`);
}
}

View File

@ -0,0 +1,20 @@
import { IVerifyCodeRequest } from 'src/dto/sms.dto';
import { IUserLoginRequest, IUserRequest } from '../../dto/user.dto';
import { axiosCommon as Request } from '../lib/request';
/**
*
*/
export const userLogin = (p: IUserLoginRequest) =>
Request.post('/user/login', p);
/**
*
*/
export const getVerifyCode = (p: IVerifyCodeRequest) =>
Request.post('/sms/verifycode', p);
/**
*
*/
export const createUser = (p: IUserRequest) => Request.post('/user/create', p);

Binary file not shown.

View File

@ -0,0 +1 @@
<svg t="1667271285418" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34809" width="200" height="200"><path d="M158.165333 499.498667A42.496 42.496 0 0 0 170.666667 469.333333V256a42.666667 42.666667 0 0 1 42.666666-42.666667 42.666667 42.666667 0 0 0 0-85.333333C142.762667 128 85.333333 185.429333 85.333333 256v195.669333l-30.165333 30.165334a42.666667 42.666667 0 0 0 0 60.330666l30.165333 30.165334V768c0 70.570667 57.429333 128 128 128a42.666667 42.666667 0 0 0 0-85.333333 42.666667 42.666667 0 0 1-42.666666-42.666667v-213.333333a42.496 42.496 0 0 0-12.501334-30.165334L145.664 512l12.501333-12.501333zM978.090667 495.658667a42.709333 42.709333 0 0 0-9.258667-13.824L938.666667 451.669333V256c0-70.570667-57.429333-128-128-128a42.666667 42.666667 0 1 0 0 85.333333 42.666667 42.666667 0 0 1 42.666666 42.666667v213.333333a42.581333 42.581333 0 0 0 12.501334 30.165334l12.501333 12.501333-12.501333 12.501333A42.496 42.496 0 0 0 853.333333 554.666667v213.333333a42.666667 42.666667 0 0 1-42.666666 42.666667 42.666667 42.666667 0 1 0 0 85.333333c70.570667 0 128-57.429333 128-128v-195.669333l30.165333-30.165334a42.709333 42.709333 0 0 0 9.258667-46.506666zM669.738667 225.450667a42.752 42.752 0 0 0-69.546667 14.762666l-255.829333 512a42.624 42.624 0 0 0 23.893333 55.424 42.922667 42.922667 0 0 0 55.552-23.765333l255.786667-512a42.538667 42.538667 0 0 0-9.813334-46.421333z" p-id="34810" fill="#2c2c2c"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,235 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="865.76" height="682.89" viewBox="0 0 865.76 682.89">
<defs>
<style xmlns="http://www.w3.org/1999/xhtml">*, ::after, ::before { box-sizing: border-box; }
img, svg { vertical-align: middle; }
</style>
<style xmlns="http://www.w3.org/1999/xhtml">*, body, html { -webkit-font-smoothing: antialiased; }
img, svg { max-width: 100%; }
</style>
</defs>
<rect x="167.21" y="379.13" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M189,358.3l19.37-.42,9.83-.16c3.29-.07,6.6,0,9.89-.07h.65v.66l.09,16.52v.74h-.71l-19.55-.09c-6.51,0-13-.18-19.54-.25h-.42v-.4c0-2.8.12-5.59.2-8.34Zm0,0,.21,8.34c0,2.76.16,5.47.19,8.18l-.4-.4c6.51-.08,13-.24,19.54-.25l19.58-.09-.74.74V358.3l.74.72c-3.22,0-6.44,0-9.67-.09l-9.71-.16Z" fill="#ebebeb"/>
<path d="M145.48,358.3l19.37-.42,9.83-.16c3.29-.07,6.58,0,9.89-.07h.65v.66l.09,16.52v.74h-.74L165,375.48c-6.53,0-13-.18-19.55-.25h-.41v-.4c0-2.8.13-5.59.19-8.34Zm0,0,.21,8.34c0,2.76.16,5.47.19,8.18l-.4-.4c6.51-.08,13-.24,19.55-.25l19.54-.09-.74.74V358.3l.67.66c-3.24,0-6.44,0-9.67-.09l-9.72-.16Z" fill="#ebebeb"/>
<path d="M746.68,51.89l-19.36.41-9.83.16c-3.3.08-6.6,0-9.89.09H707v-.66l-.09-16.52v-.74h.74l19.54.1c6.52,0,13,.17,19.54.24h.42v.4c0,2.8-.13,5.59-.19,8.35Zm0,0-.2-8.34c0-2.75-.16-5.47-.19-8.18l.39.41c-6.51,0-13,.24-19.54.24l-19.54.09.73-.74-.07,16.52-.66-.65h9.66l9.72.17Z" fill="#ebebeb"/>
<rect x="729.4" y="56.2" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M184.51,52l-19.38.39-9.83.18H144.76V34.7h.72l19.55.09c6.51,0,13,.16,19.54.24h.4v.4c0,2.79-.13,5.58-.19,8.34Zm0,0-.22-8.36c0-2.75-.16-5.46-.19-8.16l.41.4c-6.52.07-13,.23-19.54.23l-19.49,0,.72-.74L146.07,52l-.59-.73c3.22,0,6.42,0,9.66.09l9.71.16Z" fill="#ebebeb"/>
<rect x="420.15" y="139.6" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M729.4,364.47l19.38-.42,9.83-.16c3.29-.07,6.59,0,9.88-.09h.66v.67l.08,16.52v.73h-.8l-19.55-.08c-6.51,0-13-.18-19.54-.26h-.4V381c0-2.81.13-5.6.19-8.34Zm0,0,.22,8.34c0,2.76.16,5.47.19,8.18l-.41-.4c6.52-.08,13-.24,19.54-.25l19.55-.09-.73.74.08-16.52.65.66c-3.22,0-6.42,0-9.66-.09l-9.71-.16Z" fill="#ebebeb"/>
<rect x="473.81" y="501.71" width="39.09" height="16.52" fill="#ebebeb"/>
<path d="M441.94,118.77l19.44-.37,9.83-.16h10.54v.67l.08,16.51v.74h-.74l-19.54-.09c-6.53,0-13-.16-19.55-.25h-.41v-.4c0-2.8.13-5.59.19-8.34Zm0,0,.22,8.36c0,2.74.17,5.46.2,8.16l-.4-.4c6.51,0,13-.23,19.54-.23l19.55-.11-.74.74.07-16.52.67.67c-3.24,0-6.44,0-9.67-.09l-9.72-.16Z" fill="#ebebeb"/>
<polygon points="246.63 502.21 197.09 502.21 168.75 360.87 214.09 340.02 246.63 502.21" fill="#dbdbdb"/>
<polygon points="388.43 502.21 246.63 502.21 214.09 340.02 355.9 340.02 388.43 502.21" fill="#ebebeb"/>
<rect x="145.27" y="426.38" width="75.92" height="155.78" fill="#dbdbdb"/>
<polygon points="424.86 582.16 404.12 582.16 373.21 426.38 424.86 426.38 424.86 582.16" fill="#dbdbdb"/>
<rect x="221.19" y="426.38" width="41.72" height="155.78" fill="#ebebeb"/>
<rect x="424.86" y="426.38" width="41.72" height="155.78" fill="#ebebeb"/>
<rect x="262.91" y="502.21" width="161.95" height="79.94" fill="#ebebeb"/>
<rect x="262.91" y="467.65" width="161.95" height="34.88" fill="#ebebeb"/>
<path d="M231.42,426.38l15.76-.28,15.73-.21h.47v.49l.2,18.26v18.23c0,12.15.08,24.3,0,36.46s0,24.3-.21,36.46-.27,24.3-.53,36.46q-.39-18.24-.52-36.46c-.16-12.16-.18-24.31-.22-36.46s0-24.31,0-36.46V444.64l.18-18.23.47.47L247,426.69Z" fill="#dbdbdb"/>
<path d="M424.86,426.38c.33,12.19.48,24.38.61,36.59l.18,36.6-.18,36.59-.22,18.31-.39,18.29-.38-18.29-.22-18.31-.18-36.59.18-36.6C424.39,450.76,424.48,438.57,424.86,426.38Z" fill="#dbdbdb"/>
<path d="M424.86,502.21c-13.49.32-27,.47-40.49.6l-40.48.18-40.46-.18-20.24-.22-20.28-.38,20.25-.38,20.24-.23,40.49-.17,40.48.17C397.91,501.74,411.37,501.88,424.86,502.21Z" fill="#dbdbdb"/>
<path d="M424.86,467.65c-13.49.33-27,.47-40.49.61l-40.48.17-40.46-.17L283.19,468l-20.25-.39,20.25-.38,20.24-.22,40.49-.18,40.48.18C397.91,467.18,411.37,467.33,424.86,467.65Z" fill="#dbdbdb"/>
<polygon points="174.13 582.14 173.1 594.77 170.71 623.93 159.71 623.93 157.32 594.77 156.29 582.14 174.13 582.14" fill="#c7c7c7"/>
<polygon points="156.29 582.14 174.13 582.14 173.1 594.77 157.32 594.77 156.29 582.14" fill="#a6a6a6"/>
<polygon points="250.98 582.14 249.95 594.77 247.56 623.93 236.56 623.93 234.17 594.77 233.14 582.14 250.98 582.14" fill="#c7c7c7"/>
<polygon points="233.14 582.14 250.98 582.14 249.95 594.77 234.17 594.77 233.14 582.14" fill="#a6a6a6"/>
<polygon points="378.44 582.14 377.42 594.77 375.03 623.93 364.03 623.93 361.64 594.77 360.61 582.14 378.44 582.14" fill="#c7c7c7"/>
<polygon points="360.61 582.14 378.44 582.14 377.42 594.77 361.64 594.77 360.61 582.14" fill="#a6a6a6"/>
<polygon points="455.32 582.14 454.28 594.77 451.89 623.93 440.89 623.93 438.5 594.77 437.47 582.14 455.32 582.14" fill="#c7c7c7"/>
<polygon points="455.32 582.14 454.28 594.77 438.5 594.77 437.47 582.14 455.32 582.14" fill="#a6a6a6"/>
<rect x="175.4" y="127.2" width="253.39" height="10.88" fill="#ebebeb"/>
<polygon points="212.25 180.91 202.37 180.91 198.42 138.08 212.25 138.08 212.25 180.91" fill="#ebebeb"/>
<polygon points="391.94 180.91 401.82 180.91 405.78 138.08 391.94 138.08 391.94 180.91" fill="#ebebeb"/>
<polygon points="198.42 138.08 212.23 138.08 212.23 152.83 199.78 152.83 198.42 138.08" fill="#dbdbdb"/>
<polygon points="405.78 138.08 404.42 152.83 391.94 152.83 391.94 138.08 405.78 138.08" fill="#dbdbdb"/>
<path d="M267.16,61.94c-11.25,15.22-23,32.84-25.82,52a.26.26,0,0,0,.25.26.25.25,0,0,0,.24-.17,114,114,0,0,1,5-15.28c7.38-2,14.64-3.7,18.52-11s3.46-17.37,2.7-25.59C268,61.66,267.38,61.64,267.16,61.94Z" fill="#ebebeb"/>
<path d="M246.92,98.59a125.92,125.92,0,0,1,19.77-32m.09.09a136.1,136.1,0,0,0-13.54,21.23C257,84.1,261,80.7,264.56,76.7c0,0,.18,0,.12.12-3.5,4.19-7.38,8.75-11.81,11.81-1.22,2.26-2.46,4.53-3.72,6.79.31-.18.64-.33.95-.49m0,.09-1,.52c-.59,1.06-1.18,2.14-1.79,3.2-.11.3-.45.09-.34-.15Z" fill="#a6a6a6"/>
<path d="M250.67,94.64a67.6,67.6,0,0,0,8.64-5.76s.18,0,.1.1a46.21,46.21,0,0,1-8.62,5.91.14.14,0,0,1-.18-.07.12.12,0,0,1,.06-.18Z" fill="#a6a6a6"/>
<path d="M240.1,113.75c0,.24.42.22.42,0,0-6.29,0-12.6.1-18.92,1.61-3.25,5.06-5,7.47-7.66a33.37,33.37,0,0,0,4.43-6.25,45,45,0,0,0,5.2-17.34c.66-6.73-1.89-28.92-4.73-28.15-1.47.4-6.23,11.39-7.48,15a103.3,103.3,0,0,0-4.43,18.43C238.79,83.67,239,98.86,240.1,113.75Z" fill="#ebebeb"/>
<path d="M240.06,86.62h0a141.83,141.83,0,0,1,3.82-23.71c1.8-8.32,3.92-16.15,8.2-23.62,0-.14.28,0,.2.12A87.62,87.62,0,0,0,245.7,57.5c.29-.45.63-.87.93-1.3.12-.17.4,0,.28.16a11.29,11.29,0,0,1-1.33,1.89h0c-1.48,5.9-2.54,12-3.44,18.08l.21-.23h.09l-.36.6c-.46,3.07-.88,6.14-1.31,9.18a43,43,0,0,0,12.8-17h0a35.28,35.28,0,0,1-12.95,17.61c-.1.82-.22,1.64-.34,2.46,0,.17-.29.12-.29,0V86.77A.15.15,0,0,1,240.06,86.62Z" fill="#a6a6a6"/>
<path d="M242.64,75.09A124.48,124.48,0,0,0,253.8,55.9H254a61.86,61.86,0,0,1-11,19.35.16.16,0,0,1-.22.06A.17.17,0,0,1,242.64,75.09Z" fill="#a6a6a6"/>
<path d="M248.21,54.32c1.74-3.07,3.56-6,5.19-9.18,0-.09.17,0,.14.07a47.39,47.39,0,0,1-5.07,9.27.16.16,0,0,1-.23,0A.16.16,0,0,1,248.21,54.32Z" fill="#a6a6a6"/>
<path d="M237,97.63a63,63,0,0,1-1.47,12.4,11.1,11.1,0,0,0,.19,1.36A59.87,59.87,0,0,0,238,97.57a.45.45,0,0,0,0-.42h0a91.63,91.63,0,0,0-1.39-18.71c-1.95-11.56-6.2-22.66-14.26-31.31a.59.59,0,0,0-.83.08.36.36,0,0,0-.07.1c-3.25,8.27-2.11,18.14.67,26.39a47.73,47.73,0,0,0,6.39,12.54C231.26,90.1,234.79,93.4,237,97.63Z" fill="#ebebeb"/>
<path d="M223.29,51c7.65,12.4,13,27.08,13.61,41.73,0,.26-.43.34-.47.07-.18-1.31-.37-2.63-.59-3.93h0a50.43,50.43,0,0,1-8.67-10s0-.15.12,0A108.77,108.77,0,0,0,235.71,88c-.56-3.23-1.21-6.42-2-9.57-.2-.22-.4-.47-.6-.71s.09-.38.22-.22l.19.21a108.42,108.42,0,0,0-4-12.68A38.88,38.88,0,0,1,224,57.88s0-.13.1,0a57.55,57.55,0,0,0,3.55,4.68c.5.59,1.07,1.15,1.6,1.73a98.15,98.15,0,0,0-6.25-13,.19.19,0,1,1,.29-.26Z" fill="#a6a6a6"/>
<path d="M224.84,66.28c2.47,3.32,5.29,6.49,7.57,9.92,0,.1,0,.21-.16.13a51.34,51.34,0,0,1-7.57-10C224.6,66.26,224.77,66.18,224.84,66.28Z" fill="#a6a6a6"/>
<path d="M232.77,77l.1.11s0,.18-.12.11l-.1-.12C232.58,77.07,232.69,76.91,232.77,77Z" fill="#a6a6a6"/>
<path d="M210.15,71.68a37.83,37.83,0,0,0,8.06,18.91,20.07,20.07,0,0,0,6.53,5.11c2.83,1.4,5.8,3,8.72,4.16a58.11,58.11,0,0,1,3.1,11c.09-.32.18-.65.28-1-1.89-16.15-12.32-30-25.7-38.81a.65.65,0,0,0-.89.2A.66.66,0,0,0,210.15,71.68Z" fill="#ebebeb"/>
<path d="M214.76,76.45c-.09,0,0-.25.15-.18a55,55,0,0,1,17,21c.1.23-.21.42-.33.2-.62-1.08-1.25-2.14-1.9-3.19h0a18.34,18.34,0,0,1-8.21-4.77m.09-.09a18.87,18.87,0,0,0,3.85,2.72,33.17,33.17,0,0,0,3.88,1.47c-1.13-1.8-2.3-3.52-3.54-5.19a35.38,35.38,0,0,1-9.17-5.15.1.1,0,0,1,0-.13.1.1,0,0,1,.09,0,91.92,91.92,0,0,0,8.5,4.63,78.41,78.41,0,0,0-6-7c-1-.55-2.1-1.11-3.1-1.68a.09.09,0,0,1-.05-.12.07.07,0,0,1,.05,0,11,11,0,0,1,2.36,1.16,46.83,46.83,0,0,0-3.69-3.6Z" fill="#a6a6a6"/>
<path d="M215.05,82a4.87,4.87,0,0,1,.52.37v.09a4.07,4.07,0,0,1-.53-.31.09.09,0,0,1,0-.13Z" fill="#a6a6a6"/>
<polygon points="253.27 127.2 225.74 127.2 227.1 109.16 227.62 103.27 251.15 103.27 251.68 109.16 253.27 127.2" fill="#dbdbdb"/>
<polygon points="251.68 109.16 227.1 109.16 227.62 103.27 251.15 103.27 251.68 109.16" fill="#c7c7c7"/>
<rect x="225.74" y="98.45" width="27.28" height="6.04" fill="#dbdbdb"/>
<rect x="303.64" y="61.66" width="16.5" height="65.51" fill="#c7c7c7"/>
<rect x="303.65" y="58.15" width="16.5" height="7.2" fill="#dbdbdb"/>
<rect x="303.64" y="74.56" width="16.5" height="2.67" fill="#dbdbdb"/>
<rect x="303.64" y="111.36" width="16.5" height="7.2" fill="#dbdbdb"/>
<rect x="320.14" y="50.75" width="11.53" height="76.42" fill="#dbdbdb"/>
<rect x="322.4" y="57.92" width="6.92" height="29.39" fill="#ebebeb"/>
<rect x="376.78" y="57.92" width="11.53" height="76.42" transform="translate(45.24 300.6) rotate(-45.33)" fill="#c7c7c7"/>
<rect x="383.09" y="85.34" width="6.92" height="29.39" transform="translate(43.66 304.61) rotate(-45.33)" fill="#dbdbdb"/>
<rect x="331.69" y="69.13" width="19.57" height="58.04" fill="#a6a6a6"/>
<rect x="331.67" y="115.61" width="19.57" height="5.4" fill="#c7c7c7"/>
<rect x="331.69" y="109.96" width="19.57" height="2.1" fill="#c7c7c7"/>
<rect x="260.27" y="93.54" width="54.5" height="13.51" transform="translate(82.96 325.87) rotate(-67.03)" fill="#a6a6a6"/>
<rect x="276.77" y="110.14" width="5.08" height="13.52" transform="translate(61.72 327.46) rotate(-66.77)" fill="#c7c7c7"/>
<rect x="289.57" y="80.33" width="5.08" height="13.52" transform="translate(96.86 321.17) rotate(-66.77)" fill="#c7c7c7"/>
<rect x="288.36" y="86.77" width="1.98" height="13.52" transform="translate(89.28 322.54) rotate(-66.77)" fill="#c7c7c7"/>
<rect x="569.6" y="445.51" width="144.36" height="178.43" fill="#ebebeb"/>
<rect x="562.61" y="438.1" width="158.33" height="7.41" fill="#dbdbdb"/>
<rect x="720.95" y="438.1" width="49.79" height="7.41" fill="#ebebeb"/>
<rect x="713.96" y="445.51" width="48.91" height="178.43" fill="#dbdbdb"/>
<path d="M698.41,528.35H585.15v-64H698.41ZM585.52,528H698V464.69H585.52Z" fill="#c7c7c7"/>
<rect x="625.98" y="483.03" width="22.05" height="12.68" fill="#c7c7c7"/>
<path d="M654.76,494.93H632.31V483.8h22.45Zm-22.14-.37h21.69V484.23H632.62Z" fill="#c7c7c7"/>
<path d="M698.41,608.78H585.15v-64H698.41Zm-112.89-.37H698v-63.3H585.52Z" fill="#c7c7c7"/>
<rect x="625.98" y="563.46" width="22.05" height="12.68" fill="#c7c7c7"/>
<path d="M654.76,575.35H632.31V564.21h22.45ZM632.62,575h21.69V564.65H632.62Z" fill="#c7c7c7"/>
<polygon points="724.13 624.56 731.53 624.56 679.67 350.48 661.22 350.48 724.13 624.56" fill="#2f2e41" data-secondary="true"/>
<polygon points="661.22 350.48 670.53 391.01 687.33 391.01 679.68 350.52 679.67 350.48 661.22 350.48" opacity="0.2"/>
<polygon points="648.47 624.56 655.87 624.56 654.22 350.48 635.79 350.48 648.47 624.56" fill="#2f2e41" data-secondary="true"/>
<polygon points="635.79 350.48 637.66 391.01 654.47 391.01 654.22 350.52 654.22 350.48 635.79 350.48" opacity="0.2"/>
<polygon points="580.21 624.56 572.82 624.56 613.65 350.48 632.09 350.48 580.21 624.56" fill="#2f2e41" data-secondary="true"/>
<polygon points="607.61 391.01 624.41 391.01 632.09 350.48 613.65 350.48 613.64 350.52 607.61 391.01" opacity="0.2"/>
<rect x="595.4" y="507.14" width="107.62" height="5.35" fill="#2f2e41" data-secondary="true"/>
<ellipse cx="657.73" cy="244.11" rx="138.63" ry="98.46" transform="translate(381.44 888.99) rotate(-87.17)" fill="#0071f2" data-primary="true"/>
<polygon points="643.09 104.28 666.2 105.71 648.6 382.44 625.48 381.01 643.09 104.28" fill="#0071f2" data-primary="true"/>
<g opacity="0.1">
<polygon points="643.09 104.28 666.2 105.71 648.6 382.44 625.48 381.01 643.09 104.28"/>
</g>
<ellipse cx="636.45" cy="242.79" rx="138.63" ry="98.46" transform="translate(362.53 866.48) rotate(-87.17)" fill="#0071f2" data-primary="true"/>
<ellipse cx="636.45" cy="242.79" rx="108.14" ry="76.81" transform="translate(362.53 866.48) rotate(-87.17)" fill="#fff"/>
<ellipse cx="636.45" cy="242.79" rx="77.97" ry="55.37" transform="translate(362.53 866.48) rotate(-87.17)" fill="#0071f2" data-primary="true"/>
<ellipse cx="636.45" cy="242.79" rx="47.47" ry="33.71" transform="translate(362.53 866.48) rotate(-87.17)" fill="#fff"/>
<path d="M651.4,240.11c.8,11.63-5.25,22.16-13.52,23.67s-15.6-6.61-16.39-18.18,5.25-22.17,13.51-23.69S650.6,228.47,651.4,240.11Z" fill="#0071f2" data-primary="true"/>
<ellipse cx="636.45" cy="242.79" rx="138.63" ry="98.46" transform="translate(362.53 866.48) rotate(-87.17)" fill="#fff" opacity="0.4" style="isolation:isolate"/>
<path d="M528.17,536.16a361.87,361.87,0,0,0-.54-38.69,491.73,491.73,0,0,0-12.12-78.83c-3.38-14.58-7.54-28.93-11.88-43.25-.13-.44-.81-.31-.69.13,13.4,50.5,24.41,102.63,23.62,155.12-.21,14.76-1.91,29.13-3.31,43.73,0,.39.61.54.69.14C526.75,562.08,527.65,549,528.17,536.16Z" fill="#0071f2" data-primary="true"/>
<path d="M502.94,375.58s-20.33,51.58-15.78,63.7S501.09,454,501.09,454s-12.43,17.72-3.75,34.4,28.05,15.87,29.28,34.73C526.62,523.11,527.69,444.2,502.94,375.58Z" fill="#0071f2" data-primary="true"/>
<path d="M524.42,490.53a.66.66,0,0,0,0-.28,473.14,473.14,0,0,0-19.71-103.74c0-.09-.19,0-.16,0q6,22.62,10.67,45.49a22.46,22.46,0,0,0-9.7-5.4c-.07,0-.1.07,0,.1a25.64,25.64,0,0,1,10,6.69c.61,2.95,1.18,5.9,1.73,9-4.53-5.08-10.84-7.59-17.14-10-.09,0-.13.1,0,.13,6.57,2.67,13.09,6.11,17.55,11.81q2.33,12.84,4.07,25.76a24.51,24.51,0,0,0-12.11-6.94c-.14,0-.23.18-.08.22a25.59,25.59,0,0,1,12.28,7.87h.09c.4,3,.78,6.07,1.14,9.09a31.67,31.67,0,0,0-8.49-5.12c-.07,0-.12.1,0,.13a29.24,29.24,0,0,1,8.5,5.64.13.13,0,0,0,.12,0c.33,2.95.67,5.79,1,8.68a41.34,41.34,0,0,0-17.23-12.31.11.11,0,1,0-.07.21,45,45,0,0,1,17,13.08.4.4,0,0,0,.42.13c.45,4.43.85,8.86,1.17,13.28,0,0,.1.08.1,0C525.1,499.64,524.86,495.08,524.42,490.53Z" fill="#3f4347"/>
<path d="M508.09,421.52a25.43,25.43,0,0,0-12.21-3.81.08.08,0,0,0-.07.08.07.07,0,0,0,.07.07A49.39,49.39,0,0,1,508,421.8C508.1,421.88,508.24,421.63,508.09,421.52Z" fill="#3f4347"/>
<path d="M510.56,476.13a25.58,25.58,0,0,0-9.17-3.15c-.12,0-.12.16,0,.18a34.73,34.73,0,0,1,9.06,3.17C510.57,476.39,510.67,476.18,510.56,476.13Z" fill="#3f4347"/>
<path d="M581.57,440.12a139,139,0,0,0-23.51,20.55,84.62,84.62,0,0,0-16.49,28,208.9,208.9,0,0,0-12.28,66.9,161.76,161.76,0,0,0,3.61,37.62.37.37,0,0,0,.43.28.35.35,0,0,0,.28-.42,210.38,210.38,0,0,1,.37-65.74c3.49-21.35,9-44.56,22.53-61.9,7.38-9.43,16.59-16.86,25.7-24.54C582.68,440.43,582.08,439.77,581.57,440.12Z" fill="#0071f2" data-primary="true"/>
<path d="M532.24,540.18a126.61,126.61,0,0,1,17.15-21.91c10.16-10.17,18.72-17.39,20.05-24.11s-10.19-11.67-10.19-11.67,14.07,2.52,17.91-3.38,5.71-40.1,5.71-40.1-25.53,18.28-37.48,43.89S532.24,540.18,532.24,540.18Z" fill="#0071f2" data-primary="true"/>
<path d="M574.05,447.78c-10.77,10.59-21.6,21.85-27.95,35.74a139.33,139.33,0,0,0-5.65,14.76h0c-.33,1-.67,2-1,3a.49.49,0,0,0,0,.17,289,289,0,0,0-7.27,31.59s.1.1.11,0c1.1-5.33,2.32-10.72,3.68-16.09h.15a22.26,22.26,0,0,1,6.71-1.72c.15,0,.14-.28,0-.26a24.61,24.61,0,0,0-6.64,1.21c1.24-4.84,2.58-9.67,4.1-14.44a72,72,0,0,1,15.18-2v-.09A57.89,57.89,0,0,0,540.58,501c.25-.81.53-1.62.81-2.43a75.27,75.27,0,0,1,10.1-1.71m0-.12a49.17,49.17,0,0,0-9.89,1.21c1.4-4.12,2.95-8.18,4.58-12.14a70.35,70.35,0,0,1,4.82-9.38,61.53,61.53,0,0,1,8.2-1.48c.07,0,.07-.13,0-.13a22.17,22.17,0,0,0-7.77.84q2-3.25,4.27-6.36h0c5.74-1.27,11.56-2.45,17.43-1.35.09,0,.13-.16,0-.17-5.58-1.48-11.13-.62-16.7.47.6-.81,1.22-1.61,1.86-2.39A37.56,37.56,0,0,1,569,464.15a.06.06,0,1,0,0-.11,27.6,27.6,0,0,0-10,.88c4.74-5.9,10-11.44,15.16-16.92.31-.32.13-.41-.13-.22Z" fill="#3f4347"/>
<path d="M573.77,471.09a24.17,24.17,0,0,0-5.1-.18.2.2,0,0,0-.13.24.17.17,0,0,0,.13.13c1.69,0,3.38-.08,5.07,0a.1.1,0,0,0,.08-.12A.18.18,0,0,0,573.77,471.09Z" fill="#3f4347"/>
<path d="M555.34,504.26a23.38,23.38,0,0,0-7.88,1.58V506c2.61-.62,5.24-.87,7.88-1.31a.2.2,0,0,0,.19-.2A.19.19,0,0,0,555.34,504.26Z" fill="#3f4347"/>
<path d="M549.82,492.81a16.37,16.37,0,0,0-3.35.29c-.1,0-.1.21,0,.21a17.07,17.07,0,0,0,3.35-.16C550,493.12,550,492.81,549.82,492.81Z" fill="#3f4347"/>
<path d="M457.26,476.41a116.15,116.15,0,0,1,23.79,11.2,71,71,0,0,1,19.81,18.82,176.35,176.35,0,0,1,25.48,51.3A138,138,0,0,1,532.11,589a.31.31,0,0,1-.37.23.3.3,0,0,1-.24-.23A177.66,177.66,0,0,0,516,535.87c-7.76-16.46-17.55-34-32.47-44.88-8.17-5.9-17.33-9.82-26.47-13.92C456.44,476.91,456.78,476.24,457.26,476.41Z" fill="#0071f2" data-primary="true"/>
<path d="M520.3,546a106.15,106.15,0,0,0-18.94-13.76c-10.59-5.9-19.19-9.74-21.8-14.88s5.55-11.81,5.55-11.81-10.81,5.29-15.28,1.4-13.89-31.13-13.89-31.13,24.93,8.86,40.5,26.85S520.3,546,520.3,546Z" fill="#0071f2" data-primary="true"/>
<path d="M519,540.37C506.48,517,489.84,495.79,467,481.81h0a115,115,0,0,1,16.68,13.06,26.52,26.52,0,0,0-13.41,2.82.09.09,0,0,0,0,.13l.07,0a36.42,36.42,0,0,1,13.79-2.33h.14c.82.77,1.61,1.55,2.41,2.33a41.08,41.08,0,0,0-7.16,1m0,.09a36.82,36.82,0,0,1,7.56-.62,154.46,154.46,0,0,1,11.81,13.36,12,12,0,0,0-5,.35.1.1,0,0,0-.05.14l.05,0a25.86,25.86,0,0,1,5.35-.07c.69.87,1.37,1.73,2.05,2.61a48.21,48.21,0,0,0-15.13,1.48v.12a60,60,0,0,1,15.54-1c.64.84,1.24,1.71,1.86,2.57a32.54,32.54,0,0,0-9,1c-.12,0-.09.21,0,.18a34.79,34.79,0,0,1,9.33-.73c2.68,3.69,5.25,7.47,7.72,11.3a8.56,8.56,0,0,0-4,.23m0,.11a18,18,0,0,1,4.27.2c2.23,3.46,4.43,7,6.43,10.47.28.25.77,0,.56-.28Z" fill="#3f4347"/>
<path d="M499.6,521a19,19,0,0,0-7.25.88m0,.11a56.28,56.28,0,0,1,7.21-.74c.2,0,.2-.24,0-.25Z" fill="#3f4347"/>
<path d="M477.84,492.42a13.78,13.78,0,0,0-3.33.19.11.11,0,0,0-.11.11.11.11,0,0,0,.11.1c1.09-.12,2.17-.07,3.27-.1a.16.16,0,0,0,.18-.12A.16.16,0,0,0,477.84,492.42Z" fill="#3f4347"/>
<polygon points="552.45 623.37 496.18 623.37 504.19 564.59 506.25 549.54 542.37 549.54 544.42 564.59 552.45 623.37" fill="#3f4347"/>
<polygon points="544.42 564.59 504.19 564.59 506.25 549.54 542.37 549.54 544.42 564.59" fill="#2e3135"/>
<rect x="501.08" y="544.3" width="46.46" height="12.77" fill="#3f4347"/>
<path d="M223.65,476.08l3.1,18.14s1.31,8.66-4.74,13.88c0,0-16.17,14.38-15.35,35.13l-.49,58.48,14.37,2,34.64-91.48a32.86,32.86,0,0,0,5.71-17.65c0-.81-2.77-24.83-2.77-24.83Z" fill="#f9b499"/>
<path d="M230.51,646.31s11.92,1.3,7.68-12.91L222.5,602.2s-6.37-10.13-12.25-1.47c0,0-4.48,2.45-3.55-5,0,0-3-9.29-9.72-1.57a18.42,18.42,0,0,0-3.73,17.09l4.81,17a21.93,21.93,0,0,0,16.06,15.35A106.41,106.41,0,0,0,230.51,646.31Z" fill="#0071f2" data-primary="true"/>
<path d="M230.51,646.31s11.92,1.3,7.68-12.91L222.5,602.2s-6.37-10.13-12.25-1.47c0,0-4.48,2.45-3.55-5,0,0-3-9.29-9.72-1.57a18.42,18.42,0,0,0-3.73,17.09l4.81,17a21.93,21.93,0,0,0,16.06,15.35A106.41,106.41,0,0,0,230.51,646.31Z" opacity="0.2"/>
<path d="M173.33,613.47s-1-19.93-3.1-30.55c0,0-10-34.79,1-62.4,0,0,3.59-4.41,3.43-16.5l-2.78-23.2,41.33.49s-2.94,19.77-8.33,29.73c0,0-2.12,3.43-2,10.62,0,0-3.76,20.91-5.72,31.53,0,0-5.39,40.51-3.43,51.46L188.53,623l-9.81,1.63Z" fill="#f9b499"/>
<path d="M342.58,250.81l-1.8,12.74c0,.07,0,.13,0,.2.41,6-2.63,6.5-2.63,6.5l-8.65,2.12c-24.51,8.26-38.08,6.21-42.49,5.08a19,19,0,0,0-8.28-.33A37.65,37.65,0,0,0,266.61,282a17.51,17.51,0,0,1-4.51,2.82,23,23,0,0,1-9.24,2c-4.49.05-5.52,1.08-5.52,1.08-9.15,4.57-1.31,21.73-1.31,21.73,5.88,13.07,6.7,40.35,6.7,40.35a40.38,40.38,0,0,0,1.14,11.11c2.12,12.25.82,16.17.33,26.63,0,.26,0,.51,0,.76-.37,9.72,1.34,10.34,1.34,10.34,4.09,11.11,1.31,12.26,1.31,12.26-1.65,1.25-4,1.6-6.49,1.47a40.68,40.68,0,0,1-11.81-2.94c-7.18-3.11-7.35-1.47-7.35-1.47-1,4.34-9.46,1.59-14.1-.29A53.12,53.12,0,0,0,208,405c-21.3-4.53-34.34,0-34.34,0-6.15,2.22-10.09,2-11.42,1.88a5.08,5.08,0,0,1-.51-.08c-4.43-1-3.85-7-3.29-9.89a11,11,0,0,1,.6-2.1,9.23,9.23,0,0,0,.65-2.7,10.8,10.8,0,0,0-.72-4.8c-2-5.34,1.13-13.67,1.13-13.67,1.32-6.39,1.16-10.1.91-11.84a7.29,7.29,0,0,0-.46-1.72,6.69,6.69,0,0,1,.21-6.18,7.53,7.53,0,0,0,1.11-4.39c0-.34-.06-.66-.11-.95a7.11,7.11,0,0,0-.78-2.27,8.33,8.33,0,0,1-1-3.53l-.66-6.86c-.81-8.5-2.94-9.48-2.94-9.48,0,9-18.13,26.47-18.13,26.47-3.27,4.41-12.74,1.47-12.74,1.47a8.75,8.75,0,0,1-7.19-3.76c-3.76-4.08-2.78-16.82-2.78-16.82C115.67,321.87,118,322,118,322l10.78-37.57c12.58-18.3,23.86-16.66,23.86-16.66.65-2.45,4.24-2.78,4.24-2.78,2.78.49,3.6-1.14,3.6-1.14,4.08-8.33,13.48-10.9,13.48-10.9l49.61-8.28a8.41,8.41,0,0,1,8.79-1.24l9.47,2.28c35.94,3.6,91.16.49,91.16.49,5.79-1,8.12.52,9.05,2.07A4.28,4.28,0,0,1,342.58,250.81Z" fill="#0071f2" data-primary="true"/>
<g opacity="0.2">
<path d="M180.51,289.43h0a3.67,3.67,0,0,1-2.54-1.44l0,0c-2.07-4-6.59-6.77-6.63-6.8a30.14,30.14,0,0,1-10.21-10.29,15.63,15.63,0,0,1-2-5,.16.16,0,0,1,.14-.18.15.15,0,0,1,.18.13c0,.09,1.27,8.18,12,15.08,0,0,4.62,2.84,6.75,6.91a3.44,3.44,0,0,0,2.28,1.31h0a2.65,2.65,0,0,0,2-1.19,6.11,6.11,0,0,0,1.23-2.87c.39-2.49,1.33-6.7,3.26-7a.18.18,0,0,1,.19.14.16.16,0,0,1-.14.18c-1.24.17-2.36,2.67-3,6.69a6.4,6.4,0,0,1-1.3,3A3,3,0,0,1,180.51,289.43Z"/>
</g>
<g opacity="0.2">
<path d="M202.09,280.38c-3.25,0-6.85-6-7-6.29a.18.18,0,0,1,.06-.23.16.16,0,0,1,.22.06c0,.07,3.83,6.41,6.93,6.13,1.13-.11,2.06-1.12,2.74-3l5.4-12.1a.16.16,0,0,1,.22-.08.17.17,0,0,1,.08.22l-5.39,12.09c-.73,2-1.75,3.07-3,3.19Z"/>
</g>
<g opacity="0.2">
<path d="M234.43,279.23a.16.16,0,0,1-.14-.07l-4.73-7.51c-3.27-4.1-2-11.88-2-12.21a.18.18,0,0,1,.19-.14.16.16,0,0,1,.13.19c0,.08-1.25,8,1.93,12v0l4.74,7.51a.17.17,0,0,1,0,.23Z"/>
</g>
<g opacity="0.2">
<path d="M240.31,258.16a.16.16,0,0,1-.12-.06.17.17,0,0,1,0-.23c.16-.14,4-3.45,14.38-3.35a28,28,0,0,0,4.58-.3c3.19-.49,8.92-1.74,11.41-4.66a.16.16,0,1,1,.25.21c-2.56,3-8.37,4.28-11.61,4.77a28.69,28.69,0,0,1-4.64.31c-10.2-.1-14.11,3.23-14.15,3.27A.15.15,0,0,1,240.31,258.16Z"/>
</g>
<g opacity="0.2">
<path d="M246.85,261.75a.2.2,0,0,1-.14-.06.17.17,0,0,1,0-.23s4.38-3.14,12-2.81a.15.15,0,0,1,.15.17.17.17,0,0,1-.17.16c-7.53-.33-11.78,2.71-11.82,2.74Z"/>
</g>
<g opacity="0.2">
<path d="M157.32,273.51a.15.15,0,0,1-.16-.13c-.47-3.15-4.61-5.42-4.65-5.44a.16.16,0,0,1,.15-.29c.18.1,4.33,2.37,4.82,5.68a.15.15,0,0,1-.13.18Z"/>
</g>
<g opacity="0.2">
<path d="M228.39,409.11a.18.18,0,0,1-.17-.14c-3.2-17.47-10.6-41.87-10.77-42.45-3.88-9.06-4.41-14-4.42-14.08-1.45-16.61-11.16-37.48-11.26-37.69-6.15-13.76-6.22-24.47-6.22-24.57a.17.17,0,0,1,.16-.17.18.18,0,0,1,.17.17c0,.1.07,10.75,6.19,24.44.1.2,9.83,21.12,11.29,37.78,0,.05.53,5,4.39,14v0c.07.25,7.55,24.88,10.79,42.49a.17.17,0,0,1-.14.19Z"/>
</g>
<g opacity="0.2">
<path d="M239.82,383.78h0a.16.16,0,0,1-.14-.18c0-.12,1.68-11.34,6.05-16.71.21-1,3-13.8,5.29-15.26a.16.16,0,0,1,.23.05.15.15,0,0,1,0,.22c-2.2,1.42-5.13,15-5.16,15.09a.09.09,0,0,1,0,.07c-4.33,5.3-6,16.47-6,16.58A.15.15,0,0,1,239.82,383.78Z"/>
</g>
<g opacity="0.2">
<path d="M228.22,317a.17.17,0,0,1-.14-.08.18.18,0,0,1,.06-.23s4-2.33,2.86-9.47c0-.06-.95-6.35,3.52-8.66a.16.16,0,1,1,.15.29c-4.26,2.2-3.36,8.26-3.35,8.32,1.15,7.38-3,9.79-3,9.81Z"/>
</g>
<g opacity="0.2">
<path d="M235.25,292a.16.16,0,0,1-.15-.09.16.16,0,0,1,.08-.22l4.93-2.35a14.32,14.32,0,0,1,3.88-1.22A15.81,15.81,0,0,0,249.7,286a.18.18,0,0,1,.23.06.16.16,0,0,1-.06.22,16.27,16.27,0,0,1-5.83,2.19,14,14,0,0,0-3.79,1.18L235.32,292Z"/>
</g>
<g opacity="0.2">
<path d="M156.5,318.77l-.09,0c-.13-.1-1.18-1.06,1.92-6.1v0a5.74,5.74,0,0,0,.79-4.92.15.15,0,0,1,0-.13.19.19,0,0,1,.11-.07s1.52-.68,1.83-10.63a.17.17,0,0,1,.17-.16.17.17,0,0,1,.16.17c-.28,8.81-1.48,10.53-1.94,10.86a6,6,0,0,1-.87,5.08c-2.92,4.76-2,5.65-2,5.65a.18.18,0,0,1,0,.23A.17.17,0,0,1,156.5,318.77Z"/>
</g>
<g opacity="0.2">
<path d="M202.41,358.14h0c-10.25-2.62-20.43-11.43-27.17-18.36a136.18,136.18,0,0,1-12.29-14.54.16.16,0,0,1,0-.23.16.16,0,0,1,.22,0,135.68,135.68,0,0,0,12.26,14.51c6.71,6.89,16.85,15.66,27,18.26a.17.17,0,0,1,.12.2A.17.17,0,0,1,202.41,358.14Z"/>
</g>
<g opacity="0.2">
<path d="M192.12,360.26h0c-6.12-.43-9.16-2.07-10.64-3.37a5.06,5.06,0,0,1-1.75-2.72c-6.62-2.77-7.8-6.61-7.85-6.77a.16.16,0,1,1,.31-.09s1.21,3.88,7.75,6.59a.17.17,0,0,1,.1.14,4.54,4.54,0,0,0,1.69,2.63c1.43,1.26,4.41,2.85,10.41,3.26a.17.17,0,0,1,.15.18A.16.16,0,0,1,192.12,360.26Z"/>
</g>
<g opacity="0.2">
<path d="M124.94,348.39a40.06,40.06,0,0,1-5.54-.38.17.17,0,1,1,0-.33c.1,0,10,1.59,16.23-1.78a.2.2,0,0,1,.15,0,5.35,5.35,0,0,0,4.18-.09c2.57-1.12,4.6-4.08,6.05-8.8a.16.16,0,0,1,.2-.1.15.15,0,0,1,.11.2c-1.48,4.82-3.57,7.85-6.24,9a5.59,5.59,0,0,1-4.36.12C132.49,348,128.27,348.39,124.94,348.39Z"/>
</g>
<g opacity="0.2">
<path d="M145.72,332a.16.16,0,0,1-.16-.15c-.32-3.33-5.28-7.69-5.33-7.73a.16.16,0,1,1,.21-.25c.21.18,5.12,4.49,5.45,7.95a.17.17,0,0,1-.15.18Z"/>
</g>
<g opacity="0.2">
<path d="M145.23,319.58a.15.15,0,0,1-.11,0,14.67,14.67,0,0,0-6-3.06.17.17,0,0,1-.12-.2.16.16,0,0,1,.2-.12,15.14,15.14,0,0,1,6.12,3.14.16.16,0,0,1,0,.23A.13.13,0,0,1,145.23,319.58Z"/>
</g>
<path d="M139.52,258.32l-30.91,11.36a2.36,2.36,0,0,1-.78.16,2.52,2.52,0,0,1-2.46-1.72.14.14,0,0,0,0-.06,2.64,2.64,0,0,1-.11-.73,2.61,2.61,0,0,1,.05-.48,2.53,2.53,0,0,1,1.74-1.92l1.2-.36,30.14-9Z" fill="#0071f2" data-primary="true"/>
<polygon points="138.37 255.54 148.66 253.75 139.52 258.32 138.37 255.54" fill="#2f2e41" data-secondary="true"/>
<path d="M108.23,264.57l-1.2.36a2.53,2.53,0,0,0-1.74,1.92h0l-8.39-6.09s-2-1.33-1.85-3a1.86,1.86,0,0,1,1.64-1.59C98.69,255.91,103.64,256.31,108.23,264.57Z" fill="#2f2e41" data-secondary="true"/>
<path d="M107.83,269.84c-2.78,5.76-5.49,7.23-7,7.56A1.48,1.48,0,0,1,99,276c-.15-2.94,4.43-6.58,6.36-8a.14.14,0,0,1,0,.06A2.52,2.52,0,0,0,107.83,269.84Z" fill="#2f2e41" data-secondary="true"/>
<path d="M393,257.65l-4,1.65s6.19,2,5.07,5a.47.47,0,0,1-.53.3c-1.83-.37-10.21-1.94-14.31-.87a16.05,16.05,0,0,1-3.22.54,42,42,0,0,1-13.54-1.54,14.08,14.08,0,0,0-4.92-.44l-16.73,1.44c0-.07,0-.13,0-.2l1.8-12.74a4.28,4.28,0,0,0-.59-2.51c.74-.13,4.56-.63,13,.38,0,0,6.05,1.15,10.78-2l7.52-5.55s7-4.57,11.92.16c0,0,5.88-2.61,6.86,3.76,0,0,6.7-1.63,5.56,6,0,0,9.31-2.45,10,.82,0,0,2.65,2.5-10,4.43A19.42,19.42,0,0,0,393,257.65Z" fill="#f9b499"/>
<line x1="385.21" y1="241.33" x2="379.66" y2="242.48" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="392.07" y1="245.09" x2="387.5" y2="246.4" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="397.63" y1="251.13" x2="389.95" y2="252.28" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path d="M382.76,258.65a14,14,0,0,1,6.21.65" fill="none" stroke="#f7a48b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path d="M262.53,468.9c-1,6.2-14.21,8.82-14.21,8.82-15.2,3.43-24.84.32-24.84.32-2.61,0-3.43-5.06-3.43-5.06-2.45-.49-2,5.55-2,5.55,0,7-6.2,5.72-6.2,5.72-20.56,4.9-36.69.57-40.91-.77A1.92,1.92,0,0,1,169.7,482l-3.07-16.39c-2.28-8.17-1.47-12.25-1.47-12.25A104.37,104.37,0,0,0,163,424.79c-1.21-9.94-1.14-15.17-.8-17.89,1.33.16,5.27.34,11.42-1.88,0,0,13-4.53,34.34,0a53.12,53.12,0,0,1,9.06,2.82c4.64,1.88,13.05,4.63,14.1.29,0,0,.17-1.64,7.35,1.47a40.68,40.68,0,0,0,11.81,2.94c1.21,10.47,7,25.81,7,25.81,2.61,8.33,1.63,10.13,1.63,10.13-.49,7.51,1,11.92,1,11.92A16.29,16.29,0,0,1,262.53,468.9Z" fill="#2f2e41" data-secondary="true"/>
<g opacity="0.2">
<path d="M177.74,477.72a.16.16,0,0,1-.15-.12c-3.56-11.65-2.8-25.4-2.79-25.54.64-9.77-2.38-13.74-2.41-13.77a.09.09,0,0,1,0-.06c-4.05-15.07.28-31,.32-31.13a.17.17,0,0,1,.32.09c0,.16-4.35,16-.34,30.92.3.39,3.1,4.38,2.47,14,0,.14-.77,13.83,2.77,25.43a.16.16,0,0,1-.11.2Z"/>
</g>
<g opacity="0.2">
<path d="M171.13,420.41a.17.17,0,0,1-.17-.16.18.18,0,0,1,.17-.17,24.58,24.58,0,0,0,9-2.15A21.86,21.86,0,0,0,192.46,403a.16.16,0,0,1,.2-.11.16.16,0,0,1,.12.2,22.16,22.16,0,0,1-12.55,15.13,25.13,25.13,0,0,1-9.1,2.18Z"/>
</g>
<g opacity="0.2">
<path d="M220.05,473.14a.16.16,0,0,1-.16-.16l-.54-36.35a15.5,15.5,0,0,1,5.48-12.1L227,422.7a.16.16,0,0,1,.21.25L225,424.78a15.2,15.2,0,0,0-5.37,11.85l.55,36.35a.16.16,0,0,1-.16.16Z"/>
</g>
<g opacity="0.2">
<path d="M245.37,472.65l-.09,0a.16.16,0,0,1,0-.22l5.53-7.8c0-1.23.06-5,.74-5.33.4-.22,2.19-4.32,3.68-8.08a.17.17,0,0,1,.21-.09.16.16,0,0,1,.09.21c-.52,1.32-3.16,7.92-3.83,8.26-.35.17-.57,2.77-.57,5.08a.14.14,0,0,1,0,.09l-5.55,7.84A.15.15,0,0,1,245.37,472.65Z"/>
</g>
<g opacity="0.2">
<path d="M249.62,473.14l-.09,0a.16.16,0,0,1,0-.22l5.39-7.84a.16.16,0,0,1,.23-.05.17.17,0,0,1,0,.23l-5.39,7.84A.16.16,0,0,1,249.62,473.14Z"/>
</g>
<path d="M180.85,617.88s2.77,1.31.49-5.39c0,0-4.58-8.82,4.9-11.27,0,0,6.86-2.29,10,3.76,0,0,36.27,34.79,26,41.33,0,0-2.45,2.61-17.81,1.79,0,0-14.05-2.12-21.73-1.3,0,0-14.21,2.61-14.21-5.39l.49-21.57s-1-10.45,5.07-8.66C174,611.18,178.4,612.33,180.85,617.88Z" fill="#0071f2" data-primary="true"/>
<path d="M175.46,235.45s2.94,13.56-3.11,19.61l-4.9,6.53s2.13,4.74,10.78,8.82c0,0,13.24,4.25,15.2,17.15,0,0,2,.82-.66-8.82,0,0-2.28-6,3.76-7.68,0,0,9.26-4.9,4.3-12.41L195.71,249l-11.6-18.3-7-.07Z" fill="#f9b499"/>
<path d="M199.32,255.72l2.33,4.57a6.84,6.84,0,0,1-1,7.29s-12.27-.88-15.13-18.46Z" fill="#f7a48b"/>
<rect x="181.83" y="193.47" width="43.13" height="65.02" rx="21.56" fill="#f9b499"/>
<path d="M196.53,218.79s-2.91,12.52-8.8,6l-9.23,9.69s-.92,6.35-6.15,3.41c0,0-14.54-19.11-10.62-32.67,0,0,.49-1.31-1-3.1,0,0-2.94-3.27.17-5.89a6,6,0,0,0,.81-4.24s-1.63-7.68,6.21-13.4c0,0,5.72-6.37,13.56-2,0,0,2.29-5.39,7.84-.33,0,0,4.41-5.88,10.62-2.45,0,0,3.43.33,3.43,5.56,0,0,6.05-.66,6.7,3.1,0,0,2.94-2.12,8.49.82,0,0,2.62.49,3.43,6.37,0,0-.65,2.78,3.27,3.27,0,0,6.05,1,4.9,7.84,0,0-1.47,8.66-11.11,3.76,0,0-12.25-1.31-15,6.37,0,0,.33,5.55-6.37,6C197.67,217,196.37,216.5,196.53,218.79Z" fill="#2f2e41" data-secondary="true"/>
<g opacity="0.2">
<path d="M204.38,205.74a4,4,0,0,1-2.95-1.48,2.41,2.41,0,0,0-.4-.35c-.24-.13-.49-.24-.72-.34a5,5,0,0,0-4.25.12c-4.1,2.05-6.79.89-8.34-.45-1.22-1.07-1.91-2.47-1.8-2.8a.16.16,0,0,1,.21-.1.15.15,0,0,1,.1.19,5.64,5.64,0,0,0,2.29,2.91c1.41,1,3.84,1.74,7.4,0a5.34,5.34,0,0,1,4.52-.13c.24.1.49.22.74.34a2.28,2.28,0,0,1,.48.42c.88.9,2.52,2.57,6.05.09a.16.16,0,0,1,.23,0,.16.16,0,0,1,0,.22A6.24,6.24,0,0,1,204.38,205.74Zm-18.15-5.2Z"/>
</g>
<g opacity="0.2">
<path d="M170.72,186.77h-.05a.17.17,0,0,1-.11-.2,9.24,9.24,0,0,1,4.38-5.16,8.74,8.74,0,0,1,7.11.15.17.17,0,0,1,.09.22.17.17,0,0,1-.21.09,8.37,8.37,0,0,0-6.85-.16,9.12,9.12,0,0,0-4.21,5A.16.16,0,0,1,170.72,186.77Z"/>
</g>
<g opacity="0.2">
<path d="M164.47,203a6.23,6.23,0,0,1-2.48-.52.17.17,0,1,1,.14-.3,5.71,5.71,0,0,0,4.07.19,5.94,5.94,0,0,0,3.22-3.53.16.16,0,0,1,.22-.09.17.17,0,0,1,.09.21,6.26,6.26,0,0,1-3.42,3.71A5.23,5.23,0,0,1,164.47,203Z"/>
</g>
<g opacity="0.2">
<path d="M212.54,187.75a.15.15,0,0,1-.15-.1c-.41-1-.93-1.61-1.56-1.76a2,2,0,0,0-1.61.51.17.17,0,0,1-.12,0,.14.14,0,0,1-.12-.06c-.83-1-1.63-1.47-2.39-1.37-1.29.19-2.06,2-2.07,2a.15.15,0,0,1-.18.09.15.15,0,0,1-.13-.16c0-3.2-3.75-5-4-5.07-6.3-1.73-8.59,4.41-8.61,4.47a.16.16,0,0,1-.21.1.17.17,0,0,1-.1-.21c0-.06,2.42-6.49,9-4.67h0c.16.07,3.73,1.67,4.15,4.78a3.15,3.15,0,0,1,2-1.65,3,3,0,0,1,2.59,1.36,2.28,2.28,0,0,1,1.77-.48c.74.17,1.34.83,1.79,2a.17.17,0,0,1-.09.21Z"/>
</g>
<g opacity="0.2">
<path d="M217.44,201.64l-.06,0c-2.08-.83-3.34-1.93-3.75-3.27a3.51,3.51,0,0,1,.41-2.85.15.15,0,0,1,.22,0,.15.15,0,0,1,.05.22,3.28,3.28,0,0,0-.37,2.58c.38,1.24,1.58,2.27,3.56,3.06a.17.17,0,0,1-.06.32Z"/>
</g>
<g opacity="0.2">
<path d="M223.65,202.06a4.13,4.13,0,0,1-2.56-.89,6.45,6.45,0,0,1-2.34-4.76.17.17,0,0,1,.16-.17h0a.17.17,0,0,1,.16.17,6.28,6.28,0,0,0,2.22,4.51,3.84,3.84,0,0,0,3.07.75,3.66,3.66,0,0,0,2.48-1.74l.09-.17a.18.18,0,0,1,.23-.07.17.17,0,0,1,.06.23l-.1.18a4,4,0,0,1-2.7,1.89A4.08,4.08,0,0,1,223.65,202.06Z"/>
</g>
<g opacity="0.2">
<path d="M192.47,216.58a7.25,7.25,0,0,1-4.68-1.63,8.32,8.32,0,0,1-2.36-3.13.16.16,0,0,1,.1-.21.17.17,0,0,1,.21.1,8,8,0,0,0,2.27,3c2.14,1.74,4.88,2,8.14.82a.16.16,0,0,1,.21.1.17.17,0,0,1-.1.21A11.13,11.13,0,0,1,192.47,216.58Z"/>
</g>
<ellipse cx="181.83" cy="227.04" rx="5.88" ry="8.74" fill="#f9b499"/>
<path d="M120.4,289.36l-2.94,41s2.62,7.36,12.58,6.05c0,0,11.76-1.14,8.82-13.07s-7-32.67-7-32.67,3.1-5.72,1.31-14.54a8.58,8.58,0,0,1,0-3.43s.16-2.13-1.64-2.62c0,0,8.17-9,1.31-8.16,0,0,3.43-4.58-2.45-4.09,0,0-.66-4.9-8-2,0,0-15.22,6.53-12.64,20.33a3.31,3.31,0,0,0,1,1.77C112.85,280.09,119.32,286.52,120.4,289.36Z" fill="#f9b499"/>
<path d="M115.34,267.47l-.08,0a.15.15,0,0,1-.06-.22,20.65,20.65,0,0,1,15.15-9.56.16.16,0,1,1,0,.32,20.36,20.36,0,0,0-14.91,9.4A.16.16,0,0,1,115.34,267.47Z" fill="#f7a48b"/>
<path d="M119.75,274.82a.18.18,0,0,1-.13-.06.17.17,0,0,1,0-.23s4.77-3.95,8.16-7c0,0,2.95-3.12,4.88-5.69a.16.16,0,0,1,.23,0,.16.16,0,0,1,0,.22c-1.94,2.6-4.88,5.71-4.91,5.74-3.41,3.08-8.14,7-8.19,7A.13.13,0,0,1,119.75,274.82Z" fill="#f7a48b"/>
<path d="M120.89,270.9a.19.19,0,0,1-.1,0,.16.16,0,0,1,0-.23c0-.06,4.75-5.93,11.14-7.73a.16.16,0,0,1,.2.11.15.15,0,0,1-.11.2c-6.29,1.77-10.93,7.56-11,7.62A.16.16,0,0,1,120.89,270.9Z" fill="#f7a48b"/>
<path d="M129.71,285.6a.16.16,0,0,1-.16-.16c0-3.19-2.57-8.37-2.6-8.42-1.51-3.7,4.24-6.94,4.48-7.08a.17.17,0,0,1,.22.06.17.17,0,0,1-.06.23c-.06,0-5.74,3.24-4.34,6.65.1.21,2.63,5.29,2.63,8.56A.17.17,0,0,1,129.71,285.6Z" fill="#f7a48b"/>
</svg>

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,50 @@
@import './spectre-less/spectre.less';
@import './spectre-less/spectre-exp.less';
@import './spectre-less/spectre-icons.less';
@font-face {
font-family: backset;
src: url('../assets/font/backset.woff');
}
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
.container {
width: 1120px;
margin: 0 auto;
}
a {
&:hover {
text-decoration: none;
}
&:focus {
text-decoration: none;
box-shadow: none;
}
}
.navbar {
height: 2.4rem;
.navbar-section a {
display: flex;
align-items: center;
img {
width: 1.2rem;
}
span {
font-family: backset;
font-size: 1.2em;
padding-left: 0.5em;
color: #121212;
}
}
}

View File

@ -0,0 +1,16 @@
/*! Spectre.css Experimentals | MIT License | github.com/picturepan2/spectre */
// Core variables and mixins
@import 'src/variables.less';
@import 'src/mixins.less';
// Experimentals
@import 'src/calendars.less';
@import 'src/carousels.less';
@import 'src/comparison-sliders.less';
@import 'src/filters.less';
@import 'src/meters.less';
@import 'src/parallax.less';
@import 'src/progress.less';
@import 'src/sliders.less';
@import 'src/timelines.less';

View File

@ -0,0 +1,8 @@
/*! Spectre.css Icons | MIT License | github.com/picturepan2/spectre */
// Core variables and mixins
@import 'src/variables.less';
@import 'src/mixins.less';
// Icons
@import 'src/icons.less';

View File

@ -0,0 +1,50 @@
/*! Spectre.css | MIT License | github.com/picturepan2/spectre */
// Core variables and mixins
@import 'src/variables.less';
@import 'src/mixins.less';
// Reset and dependencies
@import 'src/normalize.less';
@import 'src/base.less';
// Core classes
@import 'src/typography.less';
@import 'src/asian.less';
@import 'src/tables.less';
@import 'src/buttons.less';
@import 'src/forms.less';
@import 'src/labels.less';
@import 'src/codes.less';
@import 'src/media.less';
// Layout
@import 'src/layout.less';
@import 'src/navbar.less';
@import 'src/panels.less';
@import 'src/empty.less';
// Components
@import 'src/accordions.less';
@import 'src/autocomplete.less';
@import 'src/avatars.less';
@import 'src/badges.less';
@import 'src/breadcrumbs.less';
@import 'src/bars.less';
@import 'src/cards.less';
@import 'src/chips.less';
@import 'src/dropdowns.less';
@import 'src/menus.less';
@import 'src/modals.less';
@import 'src/navs.less';
@import 'src/pagination.less';
@import 'src/popovers.less';
@import 'src/steps.less';
@import 'src/tabs.less';
@import 'src/tiles.less';
@import 'src/toasts.less';
@import 'src/tooltips.less';
// Utility classes
@import 'src/animations.less';
@import 'src/utilities.less';

View File

@ -0,0 +1,34 @@
// Accordions
.accordion {
.accordion-item {
input {
&:checked {
& ~ .accordion-header {
.icon {
transform: rotate(90deg);
}
}
& ~ .accordion-body {
max-height: 1000px;
}
}
}
.accordion-header {
display: block;
padding: @unit-1 @unit-2;
.icon {
transition: all .2s ease;
}
}
.accordion-body {
margin-bottom: @layout-spacing;
max-height: 0;
overflow: hidden;
transition: max-height .2s ease;
}
}
}

View File

@ -0,0 +1,20 @@
// Animations
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes slide-down {
0% {
opacity: 0;
transform: translateY(-@unit-8);
}
100% {
opacity: 1;
transform: translateY(0);
}
}

View File

@ -0,0 +1,33 @@
// Optimized for East Asian CJK
:lang(zh) {
font-family: @cjk-zh-font-family;
}
:lang(ja) {
font-family: @cjk-jp-font-family;
}
:lang(ko) {
font-family: @cjk-ko-font-family;
}
:lang(zh),
:lang(ja),
.cjk {
ins,
u {
border-bottom: @border-width solid;
text-decoration: none;
}
del + del,
del + s,
ins + ins,
ins + u,
s + del,
s + s,
u + ins,
u + u {
margin-left: .125em;
}
}

View File

@ -0,0 +1,41 @@
// Autocomplete
.form-autocomplete {
position: relative;
.form-autocomplete-input {
align-content: flex-start;
display: flex;
flex-wrap: wrap;
height: auto;
min-height: @unit-8;
padding: @unit-h;
&.is-focused {
border-color: @primary-color;
.control-shadow();
}
.form-input {
border-color: transparent;
box-shadow: none;
display: inline-block;
flex: 1 0 auto;
height: @unit-6;
line-height: @unit-4;
margin: @unit-h;
width: auto;
}
}
mark {
font-size: 1;
padding: .1em 0;
}
.menu {
left: 0;
position: absolute;
top: 100%;
width: 100%;
}
}

View File

@ -0,0 +1,77 @@
// Avatars
.avatar {
.avatar-base();
background: @primary-color;
border-radius: 50%;
color: fade(@light-color, 85%);
display: inline-block;
font-weight: 300;
line-height: 1;
margin: 0;
position: relative;
vertical-align: middle;
&.avatar-xs {
.avatar-base(@unit-4);
}
&.avatar-sm {
.avatar-base(@unit-6);
}
&.avatar-lg {
.avatar-base(@unit-12);
}
&.avatar-xl {
.avatar-base(@unit-16);
}
img {
border-radius: 50%;
height: 100%;
position: relative;
width: 100%;
z-index: @zindex-0;
}
.avatar-icon,
.avatar-presence {
background: @bg-color-light;
bottom: 14.64%;
height: 50%;
padding: @border-width-lg;
position: absolute;
right: 14.64%;
transform: translate(50%, 50%);
width: 50%;
z-index: @zindex-0 + 1;
}
.avatar-presence {
background: @gray-color;
box-shadow: 0 0 0 @border-width-lg @light-color;
border-radius: 50%;
height: .5em;
width: .5em;
&.online {
background: @success-color;
}
&.busy {
background: @error-color;
}
&.away {
background: @warning-color;
}
}
&[data-initial]::before {
color: currentColor;
content: attr(data-initial);
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
z-index: @zindex-0;
}
}

View File

@ -0,0 +1,70 @@
// Badges
.badge {
position: relative;
white-space: nowrap;
&[data-badge],
&:not([data-badge]) {
&::after {
background: @primary-color;
background-clip: padding-box;
border-radius: .5rem;
box-shadow: 0 0 0 .1rem @bg-color-light;
color: @light-color;
content: attr(data-badge);
display: inline-block;
transform: translate(-.1rem, -.5rem);
}
}
&[data-badge] {
&::after {
font-size: @font-size-sm;
height: 18px;
line-height: 1;
min-width: 18px;
padding: 3px 5px;
text-align: center;
white-space: nowrap;
}
}
&:not([data-badge]),
&[data-badge=''] {
&::after {
height: 6px;
min-width: 6px;
padding: 0;
width: 6px;
}
}
// Badges for Buttons
&.btn {
&::after {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
}
}
// Badges for Avatars
&.avatar {
&::after {
position: absolute;
top: 14.64%;
right: 14.64%;
transform: translate(50%, -50%);
z-index: @zindex-1;
}
}
&.avatar-xs {
&::after {
content: "";
height: @unit-2;
min-width: @unit-2;
padding: 0;
width: @unit-2;
}
}
}

View File

@ -0,0 +1,71 @@
// Bars
.bar {
background: @bg-color-dark;
border-radius: @border-radius;
display: flex;
flex-wrap: nowrap;
height: @unit-4;
width: 100%;
&.bar-sm {
height: @unit-1;
}
// TODO: attr() support
.bar-item {
background: @primary-color;
color: @light-color;
display: block;
font-size: @font-size-sm;
flex-shrink: 0;
line-height: @unit-4;
height: 100%;
position: relative;
text-align: center;
width: 0;
&:first-child {
border-bottom-left-radius: @border-radius;
border-top-left-radius: @border-radius;
}
&:last-child {
border-bottom-right-radius: @border-radius;
border-top-right-radius: @border-radius;
flex-shrink: 1;
}
}
}
// Slider bar
.bar-slider {
height: @border-width-lg;
margin: @layout-spacing 0;
position: relative;
.bar-item {
left: 0;
padding: 0;
position: absolute;
&:not(:last-child):first-child {
background: @bg-color-dark;
z-index: @zindex-0;
}
}
.bar-slider-btn {
background: @primary-color;
border: 0;
border-radius: 50%;
height: @unit-3;
padding: 0;
position: absolute;
right: 0;
top: 50%;
transform: translate(50%, -50%);
width: @unit-3;
&:active {
box-shadow: 0 0 0 .1rem @primary-color;
}
}
}

View File

@ -0,0 +1,40 @@
// Base
*,
*::before,
*::after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-size: @html-font-size;
line-height: @html-line-height;
-webkit-tap-highlight-color: transparent;
}
body {
background: @body-bg;
color: @body-font-color;
font-family: @body-font-family;
font-size: @font-size;
overflow-x: hidden;
text-rendering: optimizeLegibility;
}
a {
color: @link-color;
outline: none;
text-decoration: none;
&:focus {
.control-shadow();
}
&:focus,
&:hover,
&:active,
&.active {
color: @link-color-dark;
text-decoration: underline;
}
}

View File

@ -0,0 +1,29 @@
// Breadcrumbs
.breadcrumb {
list-style: none;
margin: @unit-1 0;
padding: @unit-1 0;
.breadcrumb-item {
color: @gray-color-dark;
display: inline-block;
margin: 0;
padding: @unit-1 0;
&:not(:last-child) {
margin-right: @unit-1;
a {
color: @gray-color-dark;
}
}
&:not(:first-child) {
&::before {
color: @gray-color-light;
content: "/";
padding-right: @unit-1;
}
}
}
}

View File

@ -0,0 +1,182 @@
// Buttons
.btn {
appearance: none;
background: @bg-color-light;
border: @border-width solid @primary-color;
border-radius: @border-radius;
color: @primary-color;
.control-transition();
cursor: pointer;
display: inline-block;
font-size: @font-size;
height: @control-size;
line-height: @line-height;
outline: none;
padding: @control-padding-v @control-padding-h;
text-align: center;
text-decoration: none;
user-select: none;
vertical-align: middle;
white-space: nowrap;
&:focus {
.control-shadow();
}
&:focus,
&:hover {
background: @secondary-color;
border-color: @primary-color-dark;
text-decoration: none;
}
&:active,
&.active {
background: @primary-color-dark;
border-color: darken(@primary-color-dark, 5%);
color: @light-color;
text-decoration: none;
&.loading {
&::after {
border-bottom-color: @light-color;
border-left-color: @light-color;
}
}
}
&[disabled],
&:disabled,
&.disabled {
cursor: default;
opacity: .5;
pointer-events: none;
}
// Button Primary
&.btn-primary {
background: @primary-color;
border-color: @primary-color-dark;
color: @light-color;
&:focus,
&:hover {
background: darken(@primary-color-dark, 2%);
border-color: darken(@primary-color-dark, 5%);
color: @light-color;
}
&:active,
&.active {
background: darken(@primary-color-dark, 4%);
border-color: darken(@primary-color-dark, 7%);
color: @light-color;
}
&.loading {
&::after {
border-bottom-color: @light-color;
border-left-color: @light-color;
}
}
}
// Button Link
&.btn-link {
background: transparent;
border-color: transparent;
color: @link-color;
&:focus,
&:hover,
&:active,
&.active {
color: @link-color-dark;
}
}
// Button Sizes
&.btn-sm {
font-size: @font-size-sm;
height: @control-size-sm;
padding: @control-padding-v-sm @control-padding-h * .75;
}
&.btn-lg {
font-size: @font-size-lg;
height: @control-size-lg;
padding: @control-padding-v-lg @control-padding-h * 1.5;
}
// Button Block
&.btn-block {
display: block;
width: 100%;
}
// Button Action
&.btn-action {
width: @control-size;
padding-left: 0;
padding-right: 0;
&.btn-sm {
width: @control-size-sm;
}
&.btn-lg {
width: @control-size-lg;
}
}
// Button Clear
&.btn-clear {
background: transparent;
border: 0;
color: currentColor;
height: @unit-4;
line-height: @unit-4;
margin-left: @unit-1;
margin-right: -2px;
opacity: .45;
padding: 0 2px;
text-decoration: none;
width: @unit-4;
&:hover {
opacity: .85;
}
&::before {
content: "\2715";
}
}
}
// Button groups
.btn-group {
display: inline-flex;
flex-wrap: wrap;
.btn {
flex: 1 0 auto;
&:first-child:not(:last-child) {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
&:not(:first-child):not(:last-child) {
border-radius: 0;
margin-left: -@border-width;
}
&:last-child:not(:first-child) {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
margin-left: -@border-width;
}
&:focus,
&:hover,
&:active,
&.active {
z-index: @zindex-0;
}
}
&.btn-group-block {
display: flex;
.btn {
flex: 1 0 0;
}
}
}

View File

@ -0,0 +1,206 @@
// Calendars
.calendar {
border: @border-width solid @border-color;
border-radius: @border-radius;
display: block;
min-width: 280px;
text-align: center;
.calendar-nav {
align-items: center;
background: @bg-color;
border-top-left-radius: @border-radius;
border-top-right-radius: @border-radius;
display: flex;
font-size: @font-size-lg;
padding: @layout-spacing;
}
.calendar-header,
.calendar-body {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: @layout-spacing 0;
.calendar-date {
flex: 0 0 14.28%; // 7 calendar-items each row
max-width: 14.28%;
}
}
.calendar-header {
background: @bg-color;
border-bottom: @border-width solid @border-color;
color: @gray-color;
font-size: @font-size-sm;
}
.calendar-body {
color: @gray-color-dark;
}
.calendar-date {
border: 0;
padding: @unit-1;
.date-item {
appearance: none;
background: transparent;
border: @border-width solid transparent;
border-radius: 50%;
color: @gray-color-dark;
.control-transition();
cursor: pointer;
height: @unit-7;
line-height: @unit-5;
outline: none;
padding: @unit-h;
position: relative;
text-align: center;
text-decoration: none;
vertical-align: middle;
white-space: nowrap;
width: @unit-7;
&.date-today {
border-color: @secondary-color-dark;
color: @primary-color;
}
&:focus {
.control-shadow();
}
&:focus,
&:hover {
background: @secondary-color-light;
border-color: @secondary-color-dark;
color: @primary-color;
text-decoration: none;
}
&:active,
&.active {
background: @primary-color-dark;
border-color: darken(@primary-color-dark, 5%);
color: @light-color;
}
// Calendar badge support
&.badge {
&::after {
position: absolute;
top: 3px;
right: 3px;
transform: translate(50%, -50%);
}
}
}
&.disabled .date-item,
&.disabled .calendar-event,
.date-item:disabled,
.calendar-event:disabled {
cursor: default;
opacity: .25;
pointer-events: none;
}
}
.calendar-range {
position: relative;
&::before {
background: @secondary-color;
content: "";
height: @unit-7;
left: 0;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}
&.range-start {
&::before {
left: 50%;
}
}
&.range-end {
&::before {
right: 50%;
}
}
.date-item {
color: @primary-color;
}
}
&.calendar-lg {
.calendar-body {
padding: 0;
.calendar-date {
border-bottom: @border-width solid @border-color;
border-right: @border-width solid @border-color;
display: flex;
flex-direction: column;
height: 5.5rem;
padding: 0;
&:nth-child(7n) {
border-right: 0;
}
&:nth-last-child(-n+7) {
border-bottom: 0;
}
}
}
.date-item {
align-self: flex-end;
height: @unit-7;
margin-right: @layout-spacing-sm;
margin-top: @layout-spacing-sm;
}
.calendar-range {
&::before {
top: 19px;
}
&.range-start {
&::before {
left: auto;
width: 19px;
}
}
&.range-end {
&::before {
right: 19px;
}
}
}
.calendar-events {
flex-grow: 1;
line-height: 1;
overflow-y: auto;
padding: @layout-spacing-sm;
}
.calendar-event {
background: @secondary-color;
border-radius: @border-radius;
color: @primary-color;
font-size: @font-size-sm;
display: block;
margin: @unit-h auto;
overflow: hidden;
padding: 3px 4px;
text-align: left;
text-overflow: ellipsis;
vertical-align: baseline;
white-space: nowrap;
}
}
}

View File

@ -0,0 +1,39 @@
// Cards
.card {
background: @bg-color-light;
border: @border-width solid @border-color;
border-radius: @border-radius;
display: flex;
flex-direction: column;
.card-header,
.card-body,
.card-footer {
padding: @layout-spacing-lg;
padding-bottom: 0;
&:last-child {
padding-bottom: @layout-spacing-lg;
}
}
.card-image {
padding-top: @layout-spacing-lg;
&:first-child {
padding-top: 0;
img {
border-top-left-radius: @border-radius;
border-top-right-radius: @border-radius;
}
}
&:last-child {
img {
border-bottom-left-radius: @border-radius;
border-bottom-right-radius: @border-radius;
}
}
}
}

View File

@ -0,0 +1,124 @@
// Carousels
.carousel {
background: @bg-color;
display: block;
overflow: hidden;
position: relative;
width: 100%;
.carousel-container {
height: 100%;
left: 0;
position: relative;
&::before {
content: "";
display: block;
padding-bottom: 56.25%;
}
.carousel-item {
animation: carousel-slideout 1s ease-in-out 1;
height: 100%;
left: 0;
margin: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
&:hover {
.item-prev,
.item-next {
opacity: 1;
}
}
}
.item-prev,
.item-next {
background: fade(@gray-color-light, 25%);
border-color: fade(@gray-color-light, 50%);
color: @gray-color-light;
opacity: 0;
position: absolute;
top: 50%;
transition: all .4s ease;
transform: translateY(-50%);
z-index: @zindex-2;
}
.item-prev {
left: 1rem;
}
.item-next {
right: 1rem;
}
}
.carousel-locator {
&:nth-of-type(1):checked ~ .carousel-container .carousel-item:nth-of-type(1),
&:nth-of-type(2):checked ~ .carousel-container .carousel-item:nth-of-type(2),
&:nth-of-type(3):checked ~ .carousel-container .carousel-item:nth-of-type(3),
&:nth-of-type(4):checked ~ .carousel-container .carousel-item:nth-of-type(4) {
animation: carousel-slidein .75s ease-in-out 1;
opacity: 1;
z-index: @zindex-1;
}
&:nth-of-type(1):checked ~ .carousel-nav .nav-item:nth-of-type(1),
&:nth-of-type(2):checked ~ .carousel-nav .nav-item:nth-of-type(2),
&:nth-of-type(3):checked ~ .carousel-nav .nav-item:nth-of-type(3),
&:nth-of-type(4):checked ~ .carousel-nav .nav-item:nth-of-type(4) {
color: @gray-color-light;
}
}
.carousel-nav {
bottom: @layout-spacing;
display: flex;
justify-content: center;
left: 50%;
position: absolute;
transform: translateX(-50%);
width: 10rem;
z-index: @zindex-2;
.nav-item {
color: fade(@gray-color-light, 50%);
display: block;
flex: 1 0 auto;
height: @unit-8;
margin: @unit-1;
max-width: 2.5rem;
position: relative;
&::before {
background: currentColor;
content: "";
display: block;
height: @border-width-lg;
position: absolute;
top: .5rem;
width: 100%;
}
}
}
}
@keyframes carousel-slidein {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(0);
}
}
@keyframes carousel-slideout {
0% {
opacity: 1;
transform: translateX(0);
}
100% {
opacity: 1;
transform: translateX(-50%);
}
}

View File

@ -0,0 +1,24 @@
// Chips
.chip {
align-items: center;
background: @bg-color-dark;
border-radius: 5rem;
color: @gray-color-dark;
display: inline-flex;
height: @unit-6;
margin: @unit-h;
max-width: 100%;
padding: @unit-h @unit-2 + @unit-h;
text-decoration: none;
vertical-align: middle;
&.active {
background: @primary-color;
color: @light-color;
}
.avatar {
margin-left: -(@unit-2 + @unit-h);
margin-right: @unit-1;
}
}

View File

@ -0,0 +1,32 @@
// Codes
code {
font-size: .65rem;
.label-base();
.label-variant(@code-color, lighten(@code-color, 33%));
}
.code {
border-radius: @border-radius;
color: @body-font-color;
line-height: @line-height;
position: relative;
&::before {
content: attr(data-lang);
color: @gray-color;
font-size: @font-size-sm;
position: absolute;
right: @layout-spacing;
top: @unit-h;
}
code {
background: @bg-color;
color: inherit;
display: block;
line-height: inherit;
overflow-x: auto;
padding: 1rem;
width: 100%;
}
}

View File

@ -0,0 +1,114 @@
// Image comparison slider
// Credit: http://codepen.io/solipsistacp/pen/Gpmaq
.comparison-slider {
height: 50vh;
overflow: hidden;
position: relative;
width: 100%;
.comparison-before,
.comparison-after {
height: 100%;
left: 0;
margin: 0;
overflow: hidden;
position: absolute;
top: 0;
img {
height: 100%;
object-fit: none;
object-position: left center;
position: absolute;
width: 100%;
}
}
.comparison-before {
width: 100%;
z-index: 1;
.comparison-label {
right: @unit-4;
}
}
.comparison-after {
max-width: 100%;
min-width: 0;
z-index: 2;
&::before {
background: transparent;
content: "";
cursor: default;
height: 100%;
left: 0;
position: absolute;
right: @unit-4;
top: 0;
z-index: @zindex-0;
}
&::after {
background: currentColor;
border-radius: 50%;
box-shadow: 0 -5px, 0 5px;
color: @light-color;
content: "";
height: 3px;
position: absolute;
right: @unit-2;
top: 50%;
transform: translate(50%, -50%);
width: 3px;
}
.comparison-label {
left: @unit-4;
}
}
.comparison-resizer {
animation: first-run 1.5s 1 ease-in-out;
cursor: ew-resize;
height: @unit-4;
left: 0;
max-width: 100%;
min-width: @unit-4;
opacity: 0;
outline: none;
position: relative;
resize: horizontal;
top: 50%;
transform: translateY(-50%) scaleY(30);
width: 0;
}
.comparison-label {
background: fade(@dark-color, 50%);
bottom: @unit-4;
color: @light-color;
padding: @unit-1 @unit-2;
position: absolute;
user-select: none;
}
}
@keyframes first-run {
0% {
width: 0;
}
25% {
width: @unit-12;
}
50% {
width: @unit-4;
}
75% {
width: @unit-6;
}
100% {
width: 0;
}
}

View File

@ -0,0 +1,36 @@
// Dropdown
.dropdown {
display: inline-block;
position: relative;
.menu {
animation: slide-down .15s ease 1;
display: none;
left: 0;
max-height: 50vh;
overflow-y: auto;
position: absolute;
top: 100%;
}
&.dropdown-right {
.menu {
left: auto;
right: 0;
}
}
&.active .menu,
.dropdown-toggle:focus + .menu,
.menu:hover {
display: block;
}
// Fix dropdown-toggle border radius in button groups
.btn-group {
.dropdown-toggle:nth-last-child(2) {
border-bottom-right-radius: @border-radius;
border-top-right-radius: @border-radius;
}
}
}

View File

@ -0,0 +1,21 @@
// Empty states (or Blank slates)
.empty {
background: @bg-color;
border-radius: @border-radius;
color: @gray-color-dark;
text-align: center;
padding: 4 * @layout-spacing;
.empty-icon {
margin-bottom: @layout-spacing-lg;
}
.empty-title,
.empty-subtitle {
margin: @layout-spacing auto;
}
.empty-action {
margin-top: @layout-spacing-lg;
}
}

View File

@ -0,0 +1,29 @@
// Filters
.filter {
.filter-nav {
margin: @layout-spacing 0;
}
.filter-body {
display: flex;
flex-wrap: wrap;
}
.filter-tag {
&#tag-all:checked ~ .filter-nav .chip[for="tag-all"],
&#tag-action:checked ~ .filter-nav .chip[for="tag-action"],
&#tag-roleplaying:checked ~ .filter-nav .chip[for="tag-roleplaying"],
&#tag-shooter:checked ~ .filter-nav .chip[for="tag-shooter"],
&#tag-sports:checked ~ .filter-nav .chip[for="tag-sports"] {
background: @primary-color;
color: @light-color;
}
&#tag-action:checked ~ .filter-body .column:not([data-tag~="tag-action"]),
&#tag-roleplaying:checked ~ .filter-body .column:not([data-tag~="tag-roleplaying"]),
&#tag-shooter:checked ~ .filter-body .column:not([data-tag~="tag-shooter"]),
&#tag-sports:checked ~ .filter-body .column:not([data-tag~="tag-sports"]) {
display: none;
}
}
}

View File

@ -0,0 +1,514 @@
// Forms
.form-group {
&:not(:last-child) {
margin-bottom: @layout-spacing;
}
}
fieldset {
margin-bottom: @layout-spacing-lg;
}
legend {
font-size: @font-size-lg;
font-weight: 500;
margin-bottom: @layout-spacing-lg;
}
// Form element: Label
.form-label {
display: block;
padding: @control-padding-v + @border-width 0;
&.label-sm {
padding: @control-padding-v-sm + @border-width 0;
}
&.label-lg {
padding: @control-padding-v-lg + @border-width 0;
}
}
// Form element: Input
.form-input {
appearance: none;
background: @bg-color-light;
background-image: none;
border: @border-width solid @border-color-dark;
border-radius: @border-radius;
color: @body-font-color;
.control-transition();
display: block;
font-size: @font-size;
height: @control-size;
line-height: @line-height;
max-width: 100%;
outline: none;
padding: @control-padding-v @control-padding-h;
position: relative;
width: 100%;
&:focus {
border-color: @primary-color;
.control-shadow();
}
&::placeholder {
color: @gray-color;
}
// Input sizes
&.input-sm {
font-size: @font-size-sm;
height: @control-size-sm;
padding: @control-padding-v-sm @control-padding-h;
}
&.input-lg {
font-size: @font-size-lg;
height: @control-size-lg;
padding: @control-padding-v-lg @control-padding-h;
}
&.input-inline {
display: inline-block;
vertical-align: middle;
width: auto;
}
// Textarea
textarea& {
height: auto;
}
// Input types
&[type="file"] {
height: auto;
}
}
// Form element: Input hint
.form-input-hint {
color: @gray-color;
font-size: @font-size-sm;
margin-top: @unit-1;
.has-success &,
.is-success + & {
color: @success-color;
}
.has-error &,
.is-error + & {
color: @error-color;
}
}
// Form element: Select
.form-select {
appearance: none;
border: @border-width solid @border-color-dark;
border-radius: @border-radius;
color: inherit;
font-size: @font-size;
height: @control-size;
line-height: @line-height;
outline: none;
padding: @control-padding-v @control-padding-h;
vertical-align: middle;
width: 100%;
&[size],
&[multiple] {
height: auto;
option {
padding: @unit-h @unit-1;
}
}
&:not([multiple]):not([size]) {
background: @bg-color-light url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23667189' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right (@control-icon-size / 2) center / .4rem .5rem;
padding-right: @control-icon-size + @control-padding-h;
}
&:focus {
border-color: @primary-color;
.control-shadow();
}
&::-ms-expand {
display: none;
}
// Select sizes
&.select-sm {
font-size: @font-size-sm;
height: @control-size-sm;
padding: @control-padding-v-sm (@control-icon-size + @control-padding-h) @control-padding-v-sm @control-padding-h;
}
&.select-lg {
font-size: @font-size-lg;
height: @control-size-lg;
padding: @control-padding-v-lg (@control-icon-size + @control-padding-h) @control-padding-v-lg @control-padding-h;
}
}
// Form Icons
.has-icon-left,
.has-icon-right {
position: relative;
.form-icon {
height: @control-icon-size;
margin: 0 @control-padding-v;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: @control-icon-size;
}
}
.has-icon-left {
.form-icon {
left: @border-width;
}
.form-input {
padding-left: @control-icon-size + @control-padding-v * 2;
}
}
.has-icon-right {
.form-icon {
right: @border-width;
}
.form-input {
padding-right: @control-icon-size + @control-padding-v * 2;
}
}
// Form element: Checkbox and Radio
.form-checkbox,
.form-radio,
.form-switch {
display: inline-block;
line-height: @line-height;
padding: (@control-size-sm - @line-height) / 2 (@control-icon-size + @control-padding-h);
position: relative;
input {
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
position: absolute;
width: 1px;
&:focus + .form-icon {
border-color: @primary-color;
.control-shadow();
}
&:checked + .form-icon {
background: @primary-color;
border-color: @primary-color;
}
}
.form-icon {
border: @border-width solid @border-color-dark;
.control-transition();
cursor: pointer;
display: inline-block;
position: absolute;
}
}
.form-checkbox,
.form-radio {
.form-icon {
background: @bg-color-light;
height: @control-icon-size;
left: 0;
top: (@control-size-sm - @control-icon-size) / 2;
width: @control-icon-size;
}
input {
&:active + .form-icon {
background: @bg-color-dark;
}
}
}
.form-checkbox {
.form-icon {
border-radius: @border-radius;
}
input {
&:checked + .form-icon {
&::before {
background-clip: padding-box;
border: @border-width-lg solid @light-color;
border-left-width: 0;
border-top-width: 0;
content: "";
height: 10px;
left: 50%;
margin-left: -3px;
margin-top: -6px;
position: absolute;
top: 50%;
transform: rotate(45deg);
width: 6px;
}
}
&:indeterminate + .form-icon {
background: @primary-color;
border-color: @primary-color;
&::before {
background: @bg-color-light;
content: "";
height: 2px;
left: 50%;
margin-left: -5px;
margin-top: -1px;
position: absolute;
top: 50%;
width: 10px;
}
}
}
}
.form-radio {
.form-icon {
border-radius: @control-icon-size / 2;
}
input {
&:checked + .form-icon {
&::before {
background: @bg-color-light;
border-radius: @border-radius;
content: "";
height: 4px;
left: 50%;
margin-left: -2px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 4px;
}
}
}
}
// Form element: Switch
.form-switch {
padding-left: (@unit-8 + @control-padding-h);
.form-icon {
background: @gray-color-light;
background-clip: padding-box;
border-radius: @unit-2 + @border-width;
height: @unit-4 + @border-width * 2;
left: 0;
top: (@control-size-sm - @unit-4) / 2 - @border-width;
width: @unit-8;
&::before {
background: @bg-color-light;
border-radius: @unit-2;
content: "";
display: block;
height: @unit-4;
left: 0;
position: absolute;
top: 0;
.control-transition();
width: @unit-4;
}
}
input {
&:checked + .form-icon {
&::before {
left: 14px;
}
}
&:active + .form-icon {
&::before {
background: @bg-color;
}
}
}
}
// Form element: Input groups
.input-group {
display: flex;
.input-group-addon {
background: @bg-color;
border: @border-width solid @border-color-dark;
border-radius: @border-radius;
line-height: @line-height;
padding: @control-padding-v @control-padding-h;
&.addon-sm {
font-size: @font-size-sm;
padding: @control-padding-v-sm @control-padding-h;
}
&.addon-lg {
font-size: @font-size-lg;
padding: @control-padding-v-lg @control-padding-h;
}
}
.form-input,
.form-select {
flex: 1 1 auto;
}
.input-group-btn {
z-index: @zindex-0;
}
.form-input,
.form-select,
.input-group-addon,
.input-group-btn {
&:first-child:not(:last-child) {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
&:not(:first-child):not(:last-child) {
border-radius: 0;
margin-left: -@border-width;
}
&:last-child:not(:first-child) {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
margin-left: -@border-width;
}
&:focus {
z-index: @zindex-0 + 1;
}
}
.form-select {
width: auto;
}
&.input-inline {
display: inline-flex;
}
}
// Form validation states
.form-input,
.form-select {
.has-success &,
&.is-success {
border-color: @success-color;
&:focus {
.control-shadow(@success-color);
}
}
.has-error &,
&.is-error {
border-color: @error-color;
&:focus {
.control-shadow(@error-color);
}
}
}
.form-checkbox,
.form-radio,
.form-switch {
.has-error &,
&.is-error {
.form-icon {
border-color: @error-color;
}
input {
&:checked + .form-icon {
background: @error-color;
border-color: @error-color;
}
&:focus + .form-icon {
border-color: @error-color;
.control-shadow(@error-color);
}
}
}
}
// validation based on :placeholder-shown (Edge doesn't support it yet)
.form-input {
&:not(:placeholder-shown) {
&:invalid {
border-color: @error-color;
&:focus {
.control-shadow(@error-color);
}
& + .form-input-hint {
color: @error-color;
}
}
}
}
// Form disabled and readonly
.form-input,
.form-select {
&:disabled,
&.disabled {
background-color: @bg-color-dark;
cursor: not-allowed;
opacity: .5;
}
}
.form-input {
&[readonly] {
background-color: @bg-color;
}
}
input {
&:disabled,
&.disabled {
& + .form-icon {
background: @bg-color-dark;
cursor: not-allowed;
opacity: .5;
}
}
}
.form-switch {
input {
&:disabled,
&.disabled {
& + .form-icon::before {
background: @bg-color-light;
}
}
}
}
// Form Horizontal
.form-horizontal {
padding: @layout-spacing;
.form-group {
display: flex;
}
.form-checkbox,
.form-radio,
.form-switch {
margin: (@control-size - @control-size-sm) / 2 0;
}
}

View File

@ -0,0 +1,656 @@
// CSS Icons
@icon-border-width: @border-width-lg;
.icon {
box-sizing: border-box;
display: inline-block;
font-size: inherit;
font-style: normal;
height: 1em;
position: relative;
text-indent: -9999px;
vertical-align: middle;
width: 1em;
&::before,
&::after {
display: block;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
}
// Icon arrows
.icon-arrow-down,
.icon-arrow-left,
.icon-arrow-right,
.icon-arrow-up,
.icon-downward,
.icon-back,
.icon-forward,
.icon-upward {
&::before {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-right: 0;
content: "";
height: .65em;
width: .65em;
}
}
.icon-arrow-down {
&::before {
transform: translate(-50%, -75%) rotate(225deg);
}
}
.icon-arrow-left {
&::before {
transform: translate(-25%, -50%) rotate(-45deg);
}
}
.icon-arrow-right {
&::before {
transform: translate(-75%, -50%) rotate(135deg);
}
}
.icon-arrow-up {
&::before {
transform: translate(-50%, -25%) rotate(45deg);
}
}
.icon-back,
.icon-forward {
&::after {
background: currentColor;
content: "";
height: @icon-border-width;
width: .8em;
}
}
.icon-downward,
.icon-upward {
&::after {
background: currentColor;
content: "";
height: .8em;
width: @icon-border-width;
}
}
.icon-back {
&::after {
left: 55%;
}
&::before {
transform: translate(-50%, -50%) rotate(-45deg);
}
}
.icon-downward {
&::after {
top: 45%;
}
&::before {
transform: translate(-50%, -50%) rotate(-135deg);
}
}
.icon-forward {
&::after {
left: 45%;
}
&::before {
transform: translate(-50%, -50%) rotate(135deg);
}
}
.icon-upward {
&::after {
top: 55%;
}
&::before {
transform: translate(-50%, -50%) rotate(45deg);
}
}
// Icon caret
.icon-caret {
&::before {
border-top: .3em solid currentColor;
border-right: .3em solid transparent;
border-left: .3em solid transparent;
content: "";
height: 0;
width: 0;
transform: translate(-50%, -25%);
}
}
// Icon menu
.icon-menu {
&::before {
background: currentColor;
box-shadow: 0 -.35em, 0 .35em;
content: "";
height: @icon-border-width;
width: 100%;
}
}
// Icon apps
.icon-apps {
&::before {
background: currentColor;
box-shadow: -.35em -.35em, -.35em 0, -.35em .35em, 0 -.35em, 0 .35em, .35em -.35em, .35em 0, .35em .35em;
content: "";
height: 3px;
width: 3px;
}
}
// Icon resize
.icon-resize-horiz,
.icon-resize-vert {
&::before,
&::after {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-right: 0;
content: "";
height: .45em;
width: .45em;
}
&::before {
transform: translate(-50%, -90%) rotate(45deg);
}
&::after {
transform: translate(-50%, -10%) rotate(225deg);
}
}
.icon-resize-horiz {
&::before {
transform: translate(-90%, -50%) rotate(-45deg);
}
&::after {
transform: translate(-10%, -50%) rotate(135deg);
}
}
// Icon more
.icon-more-horiz,
.icon-more-vert {
&::before {
background: currentColor;
box-shadow: -.4em 0, .4em 0;
border-radius: 50%;
content: "";
height: 3px;
width: 3px;
}
}
.icon-more-vert {
&::before {
box-shadow: 0 -.4em, 0 .4em;
}
}
// Icon plus, minus, cross
.icon-plus,
.icon-minus,
.icon-cross {
&::before {
background: currentColor;
content: "";
height: @icon-border-width;
width: 100%;
}
}
.icon-plus,
.icon-cross {
&::after {
background: currentColor;
content: "";
height: 100%;
width: @icon-border-width;
}
}
.icon-cross {
&::before {
width: 100%;
}
&::after {
height: 100%;
}
&::before,
&::after {
transform: translate(-50%, -50%) rotate(45deg);
}
}
// Icon check
.icon-check {
&::before {
border: @icon-border-width solid currentColor;
border-right: 0;
border-top: 0;
content: "";
height: .5em;
width: .9em;
transform: translate(-50%, -75%) rotate(-45deg);
}
}
// Icon stop
.icon-stop {
border: @icon-border-width solid currentColor;
border-radius: 50%;
&::before {
background: currentColor;
content: "";
height: @icon-border-width;
transform: translate(-50%, -50%) rotate(45deg);
width: 1em;
}
}
// Icon shutdown
.icon-shutdown {
border: @icon-border-width solid currentColor;
border-radius: 50%;
border-top-color: transparent;
&::before {
background: currentColor;
content: "";
height: .5em;
top: .1em;
width: @icon-border-width;
}
}
// Icon refresh
.icon-refresh {
&::before {
border: @icon-border-width solid currentColor;
border-radius: 50%;
border-right-color: transparent;
content: "";
height: 1em;
width: 1em;
}
&::after {
border: .2em solid currentColor;
border-top-color: transparent;
border-left-color: transparent;
content: "";
height: 0;
left: 80%;
top: 20%;
width: 0;
}
}
// Icon search
.icon-search {
&::before {
border: @icon-border-width solid currentColor;
border-radius: 50%;
content: "";
height: .75em;
left: 5%;
top: 5%;
transform: translate(0, 0) rotate(45deg);
width: .75em;
}
&::after {
background: currentColor;
content: "";
height: @icon-border-width;
left: 80%;
top: 80%;
transform: translate(-50%, -50%) rotate(45deg);
width: .4em;
}
}
// Icon edit
.icon-edit {
&::before {
border: @icon-border-width solid currentColor;
content: "";
height: .4em;
transform: translate(-40%, -60%) rotate(-45deg);
width: .85em;
}
&::after {
border: .15em solid currentColor;
border-top-color: transparent;
border-right-color: transparent;
content: "";
height: 0;
left: 5%;
top: 95%;
transform: translate(0, -100%);
width: 0;
}
}
// Icon delete
.icon-delete {
&::before {
border: @icon-border-width solid currentColor;
border-bottom-left-radius: @border-radius;
border-bottom-right-radius: @border-radius;
border-top: 0;
content: "";
height: .75em;
top: 60%;
width: .75em;
}
&::after {
background: currentColor;
box-shadow: -.25em .2em, .25em .2em;
content: "";
height: @icon-border-width;
top: @icon-border-width/2;
width: .5em;
}
}
// Icon share
.icon-share {
border: @icon-border-width solid currentColor;
border-radius: @border-radius;
border-right: 0;
border-top: 0;
&::before {
border: @icon-border-width solid currentColor;
border-left: 0;
border-top: 0;
content: "";
height: .4em;
left: 100%;
top: .25em;
transform: translate(-125%, -50%) rotate(-45deg);
width: .4em;
}
&::after {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-right: 0;
border-radius: 75% 0;
content: "";
height: .5em;
width: .6em;
}
}
// Icon flag
.icon-flag {
&::before {
background: currentColor;
content: "";
height: 1em;
left: 15%;
width: @icon-border-width;
}
&::after {
border: @icon-border-width solid currentColor;
border-bottom-right-radius: @border-radius;
border-left: 0;
border-top-right-radius: @border-radius;
content: "";
height: .65em;
top: 35%;
left: 60%;
width: .8em;
}
}
// Icon bookmark
.icon-bookmark {
&::before {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-top-left-radius: @border-radius;
border-top-right-radius: @border-radius;
content: "";
height: .9em;
width: .8em;
}
&::after {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-left: 0;
border-radius: @border-radius;
content: "";
height: .5em;
transform: translate(-50%, 35%) rotate(-45deg) skew(15deg, 15deg);
width: .5em;
}
}
// Icon download & upload
.icon-download,
.icon-upload {
border-bottom: @icon-border-width solid currentColor;
&::before {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-right: 0;
content: "";
height: .5em;
width: .5em;
transform: translate(-50%, -60%) rotate(-135deg);
}
&::after {
background: currentColor;
content: "";
height: .6em;
top: 40%;
width: @icon-border-width;
}
}
.icon-upload {
&::before {
transform: translate(-50%, -60%) rotate(45deg);
}
&::after {
top: 50%;
}
}
// Icon time
.icon-time {
border: @icon-border-width solid currentColor;
border-radius: 50%;
&::before {
background: currentColor;
content: "";
height: .4em;
transform: translate(-50%, -75%);
width: @icon-border-width;
}
&::after {
background: currentColor;
content: "";
height: .3em;
transform: translate(-50%, -75%) rotate(90deg);
transform-origin: 50% 90%;
width: @icon-border-width;
}
}
// Icon mail
.icon-mail {
&::before {
border: @icon-border-width solid currentColor;
border-radius: @border-radius;
content: "";
height: .8em;
width: 1em;
}
&::after {
border: @icon-border-width solid currentColor;
border-right: 0;
border-top: 0;
content: "";
height: .5em;
transform: translate(-50%, -90%) rotate(-45deg) skew(10deg, 10deg);
width: .5em;
}
}
// Icon people
.icon-people {
&::before {
border: @icon-border-width solid currentColor;
border-radius: 50%;
content: "";
height: .45em;
top: 25%;
width: .45em;
}
&::after {
border: @icon-border-width solid currentColor;
border-radius: 50% 50% 0 0;
content: "";
height: .4em;
top: 75%;
width: .9em;
}
}
// Icon message
.icon-message {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-radius: @border-radius;
border-right: 0;
&::before {
border: @icon-border-width solid currentColor;
border-left: 0;
border-bottom-right-radius: @border-radius;
border-top: 0;
content: "";
height: .8em;
left: 65%;
top: 40%;
width: .7em;
}
&::after {
background: currentColor;
border-radius: @border-radius;
content: "";
height: .3em;
left: 10%;
top: 100%;
transform: translate(0, -90%) rotate(45deg);
width: @icon-border-width;
}
}
// Icon photo
.icon-photo {
border: @icon-border-width solid currentColor;
border-radius: @border-radius;
&::before {
border: @icon-border-width solid currentColor;
border-radius: 50%;
content: "";
height: .25em;
left: 35%;
top: 35%;
width: .25em;
}
&::after {
border: @icon-border-width solid currentColor;
border-bottom: 0;
border-left: 0;
content: "";
height: .5em;
left: 60%;
transform: translate(-50%, 25%) rotate(-45deg);
width: .5em;
}
}
// Icon link
.icon-link {
&::before,
&::after {
border: @icon-border-width solid currentColor;
border-radius: 5em 0 0 5em;
border-right: 0;
content: "";
height: .5em;
width: .75em;
}
&::before {
transform: translate(-70%, -45%) rotate(-45deg);
}
&::after {
transform: translate(-30%, -55%) rotate(135deg);
}
}
// Icon location
.icon-location {
&::before {
border: @icon-border-width solid currentColor;
border-radius: 50% 50% 50% 0;
content: "";
height: .8em;
transform: translate(-50%, -60%) rotate(-45deg);
width: .8em;
}
&::after {
border: @icon-border-width solid currentColor;
border-radius: 50%;
content: "";
height: .2em;
transform: translate(-50%, -80%);
width: .2em;
}
}
// Icon emoji
.icon-emoji {
border: @icon-border-width solid currentColor;
border-radius: 50%;
&::before {
border-radius: 50%;
box-shadow: -.17em -.15em, .17em -.15em;
content: "";
height: .1em;
width: .1em;
}
&::after {
border: @icon-border-width solid currentColor;
border-bottom-color: transparent;
border-radius: 50%;
border-right-color: transparent;
content: "";
height: .5em;
transform: translate(-50%, -40%) rotate(-135deg);
width: .5em;
}
}
// Component icon support
.accordion,
.btn,
.toast,
.menu {
.icon {
vertical-align: -10%;
}
}

View File

@ -0,0 +1,33 @@
// Labels
.label {
display: inline-block;
.label-base();
.label-variant(lighten(@body-font-color, 5%), @bg-color);
line-height: 1;
&.label-rounded {
border-radius: 5rem;
padding-left: .4rem;
padding-right: .4rem;
}
&.label-primary {
.label-variant(@light-color, @primary-color);
}
&.label-secondary {
.label-variant(@primary-color, @secondary-color);
}
&.label-success {
.label-variant(@light-color, @success-color);
}
&.label-warning {
.label-variant(@light-color, @warning-color);
}
&.label-error {
.label-variant(@light-color, @error-color);
}
}

View File

@ -0,0 +1,422 @@
// Layout
.container {
margin-left: auto;
margin-right: auto;
padding-left: @layout-spacing;
padding-right: @layout-spacing;
width: 100%;
&:extend(.clearfix all);
&.grid-xl {
max-width: @size-xl + 2 * @layout-spacing * @html-font-size;
}
&.grid-lg {
max-width: @size-lg + 2 * @layout-spacing * @html-font-size;
}
&.grid-md {
max-width: @size-md + 2 * @layout-spacing * @html-font-size;
}
&.grid-sm {
max-width: @size-sm + 2 * @layout-spacing * @html-font-size;
}
&.grid-xs {
max-width: @size-xs + 2 * @layout-spacing * @html-font-size;
}
}
// Responsive breakpoint system
.show-xs,
.show-sm,
.show-md,
.show-lg,
.show-xl {
display: none !important;
}
// Responsive grid system
.columns {
display: flex;
flex-wrap: wrap;
margin-left: -@layout-spacing;
margin-right: -@layout-spacing;
&.col-gapless {
margin-left: 0;
margin-right: 0;
& > .column {
padding-left: 0;
padding-right: 0;
}
}
&.col-oneline {
flex-wrap: nowrap;
overflow-x: auto;
}
}
.column {
flex: 1;
max-width: 100%;
padding-left: @layout-spacing;
padding-right: @layout-spacing;
&.col-12,
&.col-11,
&.col-10,
&.col-9,
&.col-8,
&.col-7,
&.col-6,
&.col-5,
&.col-4,
&.col-3,
&.col-2,
&.col-1 {
flex: none;
}
}
.col-12 {
width: 100%;
}
.col-11 {
width: 91.66666667%;
}
.col-10 {
width: 83.33333333%;
}
.col-9 {
width: 75%;
}
.col-8 {
width: 66.66666667%;
}
.col-7 {
width: 58.33333333%;
}
.col-6 {
width: 50%;
}
.col-5 {
width: 41.66666667%;
}
.col-4 {
width: 33.33333333%;
}
.col-3 {
width: 25%;
}
.col-2 {
width: 16.66666667%;
}
.col-1 {
width: 8.33333333%;
}
.col-auto {
flex: 0 0 auto;
max-width: none;
width: auto;
}
.col-mx-auto {
margin-left: auto;
margin-right: auto;
}
.col-ml-auto {
margin-left: auto;
}
.col-mr-auto {
margin-right: auto;
}
@media screen and (max-width: @size-xl ) {
.col-xl-12,
.col-xl-11,
.col-xl-10,
.col-xl-9,
.col-xl-8,
.col-xl-7,
.col-xl-6,
.col-xl-5,
.col-xl-4,
.col-xl-3,
.col-xl-2,
.col-xl-1 {
flex: none;
}
.col-xl-12 {
width: 100%;
}
.col-xl-11 {
width: 91.66666667%;
}
.col-xl-10 {
width: 83.33333333%;
}
.col-xl-9 {
width: 75%;
}
.col-xl-8 {
width: 66.66666667%;
}
.col-xl-7 {
width: 58.33333333%;
}
.col-xl-6 {
width: 50%;
}
.col-xl-5 {
width: 41.66666667%;
}
.col-xl-4 {
width: 33.33333333%;
}
.col-xl-3 {
width: 25%;
}
.col-xl-2 {
width: 16.66666667%;
}
.col-xl-1 {
width: 8.33333333%;
}
.hide-xl {
display: none !important;
}
.show-xl {
display: block !important;
}
}
@media screen and (max-width: @size-lg ) {
.col-lg-12,
.col-lg-11,
.col-lg-10,
.col-lg-9,
.col-lg-8,
.col-lg-7,
.col-lg-6,
.col-lg-5,
.col-lg-4,
.col-lg-3,
.col-lg-2,
.col-lg-1 {
flex: none;
}
.col-lg-12 {
width: 100%;
}
.col-lg-11 {
width: 91.66666667%;
}
.col-lg-10 {
width: 83.33333333%;
}
.col-lg-9 {
width: 75%;
}
.col-lg-8 {
width: 66.66666667%;
}
.col-lg-7 {
width: 58.33333333%;
}
.col-lg-6 {
width: 50%;
}
.col-lg-5 {
width: 41.66666667%;
}
.col-lg-4 {
width: 33.33333333%;
}
.col-lg-3 {
width: 25%;
}
.col-lg-2 {
width: 16.66666667%;
}
.col-lg-1 {
width: 8.33333333%;
}
.hide-lg {
display: none !important;
}
.show-lg {
display: block !important;
}
}
@media screen and (max-width: @size-md ) {
.col-md-12,
.col-md-11,
.col-md-10,
.col-md-9,
.col-md-8,
.col-md-7,
.col-md-6,
.col-md-5,
.col-md-4,
.col-md-3,
.col-md-2,
.col-md-1 {
flex: none;
}
.col-md-12 {
width: 100%;
}
.col-md-11 {
width: 91.66666667%;
}
.col-md-10 {
width: 83.33333333%;
}
.col-md-9 {
width: 75%;
}
.col-md-8 {
width: 66.66666667%;
}
.col-md-7 {
width: 58.33333333%;
}
.col-md-6 {
width: 50%;
}
.col-md-5 {
width: 41.66666667%;
}
.col-md-4 {
width: 33.33333333%;
}
.col-md-3 {
width: 25%;
}
.col-md-2 {
width: 16.66666667%;
}
.col-md-1 {
width: 8.33333333%;
}
.hide-md {
display: none !important;
}
.show-md {
display: block !important;
}
}
@media screen and (max-width: @size-sm ) {
.col-sm-12,
.col-sm-11,
.col-sm-10,
.col-sm-9,
.col-sm-8,
.col-sm-7,
.col-sm-6,
.col-sm-5,
.col-sm-4,
.col-sm-3,
.col-sm-2,
.col-sm-1 {
flex: none;
}
.col-sm-12 {
width: 100%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-10 {
width: 83.33333333%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-8 {
width: 66.66666667%;
}
.col-sm-7 {
width: 58.33333333%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-5 {
width: 41.66666667%;
}
.col-sm-4 {
width: 33.33333333%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-2 {
width: 16.66666667%;
}
.col-sm-1 {
width: 8.33333333%;
}
.hide-sm {
display: none !important;
}
.show-sm {
display: block !important;
}
}
@media screen and (max-width: @size-xs) {
.col-xs-12,
.col-xs-11,
.col-xs-10,
.col-xs-9,
.col-xs-8,
.col-xs-7,
.col-xs-6,
.col-xs-5,
.col-xs-4,
.col-xs-3,
.col-xs-2,
.col-xs-1 {
flex: none;
}
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
.col-xs-9 {
width: 75%;
}
.col-xs-8 {
width: 66.66666667%;
}
.col-xs-7 {
width: 58.33333333%;
}
.col-xs-6 {
width: 50%;
}
.col-xs-5 {
width: 41.66666667%;
}
.col-xs-4 {
width: 33.33333333%;
}
.col-xs-3 {
width: 25%;
}
.col-xs-2 {
width: 16.66666667%;
}
.col-xs-1 {
width: 8.33333333%;
}
.hide-xs {
display: none !important;
}
.show-xs {
display: block !important;
}
}

View File

@ -0,0 +1,70 @@
// Media
.img-responsive {
display: block;
height: auto;
max-width: 100%;
}
// object-fit support is coming to Microsoft Edge
// https://developer.microsoft.com/en-us/microsoft-edge/platform/status/objectfitandobjectposition/
.img-fit-cover {
object-fit: cover;
}
.img-fit-contain {
object-fit: contain;
}
// Video responsive
.video-responsive {
display: block;
overflow: hidden;
padding: 0;
position: relative;
width: 100%;
&::before {
content: "";
display: block;
padding-bottom: 56.25%; // Default ratio 16:9, you can calculate this value by dividing 9 by 16
}
iframe,
object,
embed {
border: 0;
bottom: 0;
height: 100%;
left: 0;
position: absolute;
right: 0;
top: 0;
width: 100%;
}
video {
height: auto;
max-width: 100%;
width: 100%;
}
}
.video-responsive-4-3 {
&::before {
padding-bottom: 75%; // Ratio 4:3
}
}
.video-responsive-1-1 {
&::before {
padding-bottom: 100%; // Ratio 1:1
}
}
.figure {
margin: 0 0 @layout-spacing 0;
.figure-caption {
color: @gray-color-dark;
margin-top: @layout-spacing;
}
}

View File

@ -0,0 +1,56 @@
// Menus
.menu {
background: @bg-color-light;
border-radius: @border-radius;
list-style: none;
margin: 0;
min-width: @control-min-width;
padding: @unit-2;
.shadow-variant(.05rem);
transform: translateY(@layout-spacing-sm);
z-index: @zindex-1;
&.menu-nav {
background: transparent;
box-shadow: none;
}
.menu-item {
margin-top: 0;
padding: 0 @unit-2;
text-decoration: none;
user-select: none;
& > a {
border-radius: @border-radius;
color: inherit;
display: block;
margin: 0 -@unit-2;
padding: @unit-1 @unit-2;
text-decoration: none;
&:focus,
&:hover {
background: @secondary-color;
color: @primary-color;
}
&:active,
&.active {
background: @secondary-color;
color: @primary-color;
}
}
& + .menu-item {
margin-top: @unit-1;
}
}
.menu-badge {
float: right;
padding: @unit-1 0;
.btn {
margin-top: -@unit-h;
}
}
}

View File

@ -0,0 +1,57 @@
// Meters
// Credit: https://css-tricks.com/html5-meter-element/
.meter {
appearance: none;
background: @bg-color;
border: 0;
border-radius: @border-radius;
display: block;
width: 100%;
height: @unit-4;
&::-webkit-meter-inner-element {
display: block;
}
&::-webkit-meter-bar,
&::-webkit-meter-optimum-value,
&::-webkit-meter-suboptimum-value,
&::-webkit-meter-even-less-good-value {
border-radius: @border-radius;
}
&::-webkit-meter-bar {
background: @bg-color;
}
&::-webkit-meter-optimum-value {
background: @success-color;
}
&::-webkit-meter-suboptimum-value {
background: @warning-color;
}
&::-webkit-meter-even-less-good-value {
background: @error-color;
}
&::-moz-meter-bar,
&:-moz-meter-optimum,
&:-moz-meter-sub-optimum,
&:-moz-meter-sub-sub-optimum {
border-radius: @border-radius;
}
&:-moz-meter-optimum::-moz-meter-bar {
background: @success-color;
}
&:-moz-meter-sub-optimum::-moz-meter-bar {
background: @warning-color;
}
&:-moz-meter-sub-sub-optimum::-moz-meter-bar {
background: @error-color;
}
}

View File

@ -0,0 +1,175 @@
// Mixins
// Avatar mixin
.avatar-base(@size: @unit-8) {
font-size: @size / 2;
height: @size;
width: @size;
}
// Background color utility mixin
.bg-color-variant(@color: @primary-color) {
background: @color;
}
// Button variant mixin
.button-variant(@color: @primary-color) {
background: @color;
border-color: darken(@color, 3%);
color: @light-color;
&:focus {
.control-shadow(@color);
}
&:focus,
&:hover {
background: darken(@color, 2%);
border-color: darken(@color, 5%);
color: @light-color;
}
&:active,
&.active {
background: darken(@color, 7%);
border-color: darken(@color, 10%);
color: @light-color;
}
&.loading {
&::after {
border-bottom-color: @light-color;
border-left-color: @light-color;
}
}
}
.button-outline-variant(@color: @primary-color) {
background: @light-color;
border-color: @color;
color: @color;
&:focus {
.control-shadow(@color);
}
&:focus,
&:hover {
background: lighten(@color, 50%);
border-color: darken(@color, 2%);
color: @color;
}
&:active,
&.active {
background: @color;
border-color: darken(@color, 5%);
color: @light-color;
}
&.loading {
&::after {
border-bottom-color: @color;
border-left-color: @color;
}
}
}
// Clearfix mixin
.clearfix() {
&::after {
clear: both;
content: "";
display: table;
}
}
// Component focus shadow
.control-shadow(@color: @primary-color) {
box-shadow: 0 0 0 .1rem fade(@color, 20%);
}
// Component transition
.control-transition() {
transition: all .2s ease;
}
// Label base style
.label-base() {
border-radius: @border-radius;
line-height: 1;
padding: .15rem .2rem;
}
.label-variant(@color: @light-color, @bg-color: @primary-color) {
background: @bg-color;
color: @color;
}
// Margin utility mixin
.margin-variant(@id: 1, @size: 1) {
.m-@{id} {
margin: @size;
}
.mb-@{id} {
margin-bottom: @size;
}
.ml-@{id} {
margin-left: @size;
}
.mr-@{id} {
margin-right: @size;
}
.mt-@{id} {
margin-top: @size;
}
.mx-@{id} {
margin-left: @size;
margin-right: @size;
}
.my-@{id} {
margin-bottom: @size;
margin-top: @size;
}
}
// Padding utility mixin
.padding-variant(@id: 1, @size: 1) {
.p-@{id} {
padding: @size;
}
.pb-@{id} {
padding-bottom: @size;
}
.pl-@{id} {
padding-left: @size;
}
.pr-@{id} {
padding-right: @size;
}
.pt-@{id} {
padding-top: @size;
}
.px-@{id} {
padding-left: @size;
padding-right: @size;
}
.py-@{id} {
padding-bottom: @size;
padding-top: @size;
}
}
// Shadow mixin
.shadow-variant(@offset) {
box-shadow: 0 @offset (@offset + .05rem) * 2 fade(@dark-color, 30%);
}
// Text color utility mixin
.text-color-variant(@color: @primary-color) {
color: @color;
a& {
&:focus,
&:hover {
color: darken(@color, 5%);
}
}
}
// Toast variant mixin
.toast-variant(@color: @dark-color) {
background: fade(@color, 90%);
border-color: @color;
}

View File

@ -0,0 +1,73 @@
// Modals
.modal {
align-items: center;
bottom: 0;
display: none;
justify-content: center;
left: 0;
opacity: 0;
overflow: hidden;
padding: @layout-spacing;
position: fixed;
right: 0;
top: 0;
&:target,
&.active {
display: flex;
opacity: 1;
z-index: @zindex-4;
.modal-overlay {
background: fade(@bg-color, 75%);
bottom: 0;
cursor: default;
display: block;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.modal-container {
animation: slide-down .2s ease 1;
max-width: 640px;
z-index: @zindex-0;
}
}
&.modal-sm {
.modal-container {
max-width: @control-max-width;
}
}
}
.modal-container {
background: @bg-color-light;
border-radius: @border-radius;
display: block;
padding: 0;
.shadow-variant(.2rem);
text-align: left;
.modal-header {
padding: @layout-spacing-lg;
.modal-title {
margin: 0;
}
}
.modal-body {
max-height: 50vh;
overflow-y: auto;
padding: @layout-spacing-lg;
position: relative;
}
.modal-footer {
padding: @layout-spacing-lg;
text-align: right;
}
}

View File

@ -0,0 +1,29 @@
// Navbar
.navbar {
align-items: stretch;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.navbar-section {
align-items: center;
display: flex;
flex: 1 0 0;
&:last-child {
justify-content: flex-end;
}
}
.navbar-center {
align-items: center;
display: flex;
flex: 0 0 auto;
}
.navbar-brand {
font-size: @font-size-lg;
font-weight: 500;
text-decoration: none;
}
}

View File

@ -0,0 +1,34 @@
// Navs
.nav {
display: flex;
flex-direction: column;
list-style: none;
margin: @unit-1 0;
.nav-item {
a {
color: @gray-color-dark;
padding: @unit-1 @unit-2;
text-decoration: none;
&:focus,
&:hover {
color: @primary-color;
}
}
&.active {
& > a {
color: darken(@gray-color-dark, 10%);
font-weight: bold;
&:focus,
&:hover {
color: @primary-color;
}
}
}
}
& .nav {
margin-bottom: @unit-2;
margin-left: @unit-4;
}
}

View File

@ -0,0 +1,437 @@
/* Manually forked from Normalize.css */
/* normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
/**
* 1. Change the default font family in all browsers (opinionated).
* 2. Correct the line height in all browsers.
* 3. Prevent adjustments of font size after orientation changes in
* IE on Windows Phone and in iOS.
*/
/* Document
========================================================================== */
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 3 */
-webkit-text-size-adjust: 100%; /* 3 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers (opinionated).
*/
body {
margin: 0;
}
/**
* Add the correct display in IE 9-.
*/
article,
aside,
footer,
header,
nav,
section {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* Add the correct display in IE 9-.
* 1. Add the correct display in IE.
*/
figcaption,
figure,
main { /* 1 */
display: block;
}
/**
* Add the correct margin in IE 8 (removed).
*/
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers. (removed)
* 2. Correct the odd `em` font sizing in all browsers.
*/
/* Text-level semantics
========================================================================== */
/**
* 1. Remove the gray background on active links in IE 10.
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
*/
a {
background-color: transparent; /* 1 */
-webkit-text-decoration-skip: objects; /* 2 */
}
/**
* Remove the outline on focused links when they are also active or hovered
* in all browsers (opinionated).
*/
a:active,
a:hover {
outline-width: 0;
}
/**
* 1. Remove the bottom border in Firefox 39-.
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. (removed)
*/
/**
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
*/
b,
strong {
font-weight: inherit;
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: @mono-font-family; /* 1 (changed) */
font-size: 1em; /* 2 */
}
/**
* Add the correct font style in Android 4.3-.
*/
dfn {
font-style: italic;
}
/**
* Add the correct background and color in IE 9-. (Removed)
*/
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
font-weight: 400; /* (added) */
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Add the correct display in IE 9-.
*/
audio,
video {
display: inline-block;
}
/**
* Add the correct display in iOS 4-7.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Remove the border on images inside links in IE 10-.
*/
img {
border-style: none;
}
/**
* Hide the overflow in IE.
*/
svg:not(:root) {
overflow: hidden;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers (opinionated).
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 (changed) */
font-size: inherit; /* 1 (changed) */
line-height: inherit; /* 1 (changed) */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
* controls in Android 4.
* 2. Correct the inability to style clickable types in iOS and Safari.
*/
button,
html [type="button"], /* 1 */
[type="reset"],
[type="submit"] {
-webkit-appearance: button; /* 2 */
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule (removed).
*/
/**
* Change the border, margin, and padding in all browsers (opinionated) (changed).
*/
fieldset {
border: 0;
margin: 0;
padding: 0;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* 1. Add the correct display in IE 9-.
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
display: inline-block; /* 1 */
vertical-align: baseline; /* 2 */
}
/**
* Remove the default vertical scrollbar in IE.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10-.
* 2. Remove the padding in IE 10-.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in IE 9-.
* 1. Add the correct display in Edge, IE, and Firefox.
*/
details, /* 1 */
menu {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Scripting
========================================================================== */
/**
* Add the correct display in IE 9-.
*/
canvas {
display: inline-block;
}
/**
* Add the correct display in IE.
*/
template {
display: none;
}
/* Hidden
========================================================================== */
/**
* Add the correct display in IE 10-.
*/
[hidden] {
display: none;
}

View File

@ -0,0 +1,61 @@
// Pagination
.pagination {
display: flex;
list-style: none;
margin: @unit-1 0;
padding: @unit-1 0;
.page-item {
margin: @unit-1 @unit-o;
span {
display: inline-block;
padding: @unit-1 @unit-1;
}
a {
border-radius: @border-radius;
color: @gray-color-dark;
display: inline-block;
padding: @unit-1 @unit-2;
text-decoration: none;
&:focus,
&:hover {
color: @primary-color;
}
}
&.disabled {
a {
cursor: default;
opacity: .5;
pointer-events: none;
}
}
&.active {
a {
background: @primary-color;
color: @light-color;
}
}
&.page-prev,
&.page-next {
flex: 1 0 50%;
}
&.page-next {
text-align: right;
}
.page-item-title {
margin: 0;
}
.page-item-subtitle {
margin: 0;
opacity: .5;
}
}
}

View File

@ -0,0 +1,23 @@
// Panels
.panel {
border: @border-width solid @border-color;
border-radius: @border-radius;
display: flex;
flex-direction: column;
.panel-header,
.panel-footer {
flex: 0 0 auto;
padding: @layout-spacing-lg;
}
.panel-nav {
flex: 0 0 auto;
}
.panel-body {
flex: 1 1 auto;
overflow-y: auto;
padding: 0 @layout-spacing-lg;
}
}

View File

@ -0,0 +1,129 @@
// Parallax
@parallax-deg: 3deg;
@parallax-offset: 6.5px;
@parallax-offset-z: 100px;
@parallax-perspective: 1000px;
@parallax-scale: 1 - unit(@parallax-offset-z / @parallax-perspective);
.parallax {
display: block;
height: auto;
position: relative;
width: auto;
.parallax-content {
height: auto;
.shadow-variant(1rem);
transform: perspective(@parallax-perspective);
transform-style: preserve-3d;
transition: all .4s ease;
width: 100%;
&::before {
content: "";
display: block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
}
.parallax-front {
align-items: center;
color: @light-color;
display: flex;
height: 100%;
justify-content: center;
left: 0;
position: absolute;
text-align: center;
text-shadow: 0 0 20px fade(@dark-color, 50%);
top: 0;
transform: translateZ(@parallax-offset-z) scale(@parallax-scale);
transition: all .4s ease;
width: 100%;
z-index: @zindex-0;
}
.parallax-top-left {
.parallax-dir();
left: 0;
top: 0;
&:hover ~ .parallax-content {
transform: perspective(@parallax-perspective) rotateX(-@parallax-deg) rotateY(@parallax-deg);
&::before {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0) 50%);
}
.parallax-front {
transform: translate3d(-@parallax-offset, -@parallax-offset, @parallax-offset-z) scale(@parallax-scale);
}
}
}
.parallax-top-right {
.parallax-dir();
right: 0;
top: 0;
&:hover ~ .parallax-content {
transform: perspective(@parallax-perspective) rotateX(-@parallax-deg) rotateY(-@parallax-deg);
&::before {
background: linear-gradient(-135deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0) 50%);
}
.parallax-front {
transform: translate3d(@parallax-offset, -@parallax-offset, @parallax-offset-z) scale(@parallax-scale);
}
}
}
.parallax-bottom-left {
.parallax-dir();
bottom: 0;
left: 0;
&:hover ~ .parallax-content {
transform: perspective(@parallax-perspective) rotateX(@parallax-deg) rotateY(@parallax-deg);
&::before {
background: linear-gradient(45deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0) 50%);
}
.parallax-front {
transform: translate3d(-@parallax-offset, @parallax-offset, @parallax-offset-z) scale(@parallax-scale);
}
}
}
.parallax-bottom-right {
.parallax-dir();
bottom: 0;
right: 0;
&:hover ~ .parallax-content {
transform: perspective(@parallax-perspective) rotateX(@parallax-deg) rotateY(-@parallax-deg);
&::before {
background: linear-gradient(-45deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0) 50%);
}
.parallax-front {
transform: translate3d(@parallax-offset, @parallax-offset, @parallax-offset-z) scale(@parallax-scale);
}
}
}
}
// Mixin: Parallax direction
.parallax-dir() {
height: 50%;
position: absolute;
width: 50%;
z-index: @zindex-3;
}

View File

@ -0,0 +1,70 @@
// Popovers
.popover {
display: inline-block;
position: relative;
.popover-container {
content: attr(data-tooltip);
opacity: 0;
left: 50%;
padding: @layout-spacing;
position: absolute;
top: 0;
transform: translate(-50%, -50%) scale(0);
transition: transform .2s ease;
width: @control-max-width;
z-index: @zindex-4;
}
:focus + .popover-container,
&:hover .popover-container,
.popover-container:hover {
display: block;
opacity: 1;
transform: translate(-50%, -100%) scale(1);
}
&.popover-right {
.popover-container {
left: 100%;
top: 50%;
}
:focus + .popover-container,
&:hover .popover-container,
.popover-container:hover {
transform: translate(0, -50%) scale(1);
}
}
&.popover-bottom {
.popover-container {
left: 50%;
top: 100%;
}
:focus + .popover-container,
&:hover .popover-container,
.popover-container:hover {
transform: translate(-50%, 0) scale(1);
}
}
&.popover-left {
.popover-container {
left: 0;
top: 50%;
}
:focus + .popover-container,
&:hover .popover-container,
.popover-container:hover {
transform: translate(-100%, -50%) scale(1);
}
}
.card {
border: 0;
.shadow-variant(.2rem);
}
}

View File

@ -0,0 +1,45 @@
// Progress
// Credit: https://css-tricks.com/html5-progress-element/
.progress {
appearance: none;
background: @bg-color-dark;
border: 0;
border-radius: @border-radius;
color: @primary-color;
height: @unit-1;
position: relative;
width: 100%;
&::-webkit-progress-bar {
background: transparent;
border-radius: @border-radius;
}
&::-webkit-progress-value {
background: @primary-color;
border-radius: @border-radius;
}
&::-moz-progress-bar {
background: @primary-color;
border-radius: @border-radius;
}
&:indeterminate {
animation: progress-indeterminate 1.5s linear infinite;
background: @bg-color-dark linear-gradient(to right, @primary-color 30%, @bg-color-dark 30%) top left / 150% 150% no-repeat;
&::-moz-progress-bar {
background: transparent;
}
}
}
@keyframes progress-indeterminate {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}

View File

@ -0,0 +1,93 @@
// Sliders
// Credit: https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/
.slider {
appearance: none;
background: transparent;
display: block;
width: 100%;
height: @unit-6;
&:focus {
.control-shadow();
outline: none;
}
// Slider Thumb
&::-webkit-slider-thumb {
-webkit-appearance: none;
background: @primary-color;
border: 0;
border-radius: 50%;
height: @unit-3;
margin-top: -(@unit-3 - @unit-h) / 2 ;
transition: transform .2s ease;
width: @unit-3;
}
&::-moz-range-thumb {
background: @primary-color;
border: 0;
border-radius: 50%;
height: @unit-3;
transition: transform .2s ease;
width: @unit-3;
}
&::-ms-thumb {
background: @primary-color;
border: 0;
border-radius: 50%;
height: @unit-3;
transition: transform .2s ease;
width: @unit-3;
}
&:active {
&::-webkit-slider-thumb {
transform: scale(1.25);
}
&::-moz-range-thumb {
transform: scale(1.25);
}
&::-ms-thumb {
transform: scale(1.25);
}
}
&:disabled,
&.disabled {
&::-webkit-slider-thumb {
background: @gray-color-light;
transform: scale(1);
}
&::-moz-range-thumb {
background: @gray-color-light;
transform: scale(1);
}
&::-ms-thumb {
background: @gray-color-light;
transform: scale(1);
}
}
// Slider Track
&::-webkit-slider-runnable-track {
background: @bg-color-dark;
border-radius: @border-radius;
height: @unit-h;
width: 100%;
}
&::-moz-range-track {
background: @bg-color-dark;
border-radius: @border-radius;
height: @unit-h;
width: 100%;
}
&::-ms-track {
background: @bg-color-dark;
border-radius: @border-radius;
height: @unit-h;
width: 100%;
}
&::-ms-fill-lower {
background: @primary-color;
}
}

View File

@ -0,0 +1,70 @@
// Steps
.step {
display: flex;
flex-wrap: nowrap;
list-style: none;
margin: @unit-1 0;
width: 100%;
.step-item {
flex: 1 1 0;
margin-top: 0;
min-height: 20px;
text-align: center;
position: relative;
&:not(:first-child)::before {
background: @primary-color;
content: "";
height: 2px;
left: -50%;
position: absolute;
top: 9px;
width: 100%;
}
a {
color: @gray-color;
display: inline-block;
padding: 20px 10px 0;
text-decoration: none;
&::before {
background: @primary-color;
border: @border-width-lg solid @light-color;
border-radius: 50%;
content: "";
display: block;
height: @unit-3;
left: 50%;
position: absolute;
top: @unit-1;
transform: translateX(-50%);
width: @unit-3;
z-index: @zindex-0;
}
}
&.active {
a {
&::before {
background: @light-color;
border: @border-width-lg solid @primary-color;
}
}
& ~ .step-item {
&::before {
background: @border-color;
}
a {
&::before {
background: @gray-color-light;
}
}
}
}
}
}

View File

@ -0,0 +1,45 @@
// Tables
.table {
border-collapse: collapse;
border-spacing: 0;
text-align: left;
width: 100%;
&.table-striped {
tbody {
tr:nth-of-type(odd) {
background: @bg-color;
}
}
}
&.table-hover {
tbody {
tr {
&:hover {
background: @bg-color-dark;
}
}
}
}
&,
&.table-striped {
tbody {
tr {
&.active {
background: @bg-color-dark;
}
}
}
}
td,
th {
border-bottom: @border-width solid @border-color;
padding: @unit-3 @unit-2;
}
th {
border-bottom-width: @border-width-lg;
}
}

View File

@ -0,0 +1,62 @@
// Tabs
.tab {
align-items: center;
border-bottom: @border-width solid @border-color;
display: flex;
flex-wrap: wrap;
list-style: none;
margin: @unit-1 0 @unit-1 - @border-width 0;
.tab-item {
margin-top: 0;
&.tab-action {
flex: 1 0 auto;
text-align: right;
}
a {
border-bottom: @border-width-lg solid transparent;
color: inherit;
display: block;
margin: 0 @unit-2 0 0;
padding: @unit-2 @unit-1 @unit-2 - @border-width-lg @unit-1;
text-decoration: none;
&:focus,
&:hover {
color: @link-color;
}
}
&.active a,
a.active {
border-bottom-color: @primary-color;
color: @link-color;
}
}
&.tab-block {
.tab-item {
flex: 1 0 0;
text-align: center;
a {
margin: 0;
}
.badge {
&[data-badge]::after {
position: absolute;
right: -4px;
top: -4px;
transform: translate(0, 0);
}
}
}
}
&:not(.tab-block) {
.badge {
padding-right: 2px;
}
}
}

View File

@ -0,0 +1,38 @@
// Tiles
.tile {
align-content: space-between;
align-items: flex-start;
display: flex;
.tile-icon,
.tile-action {
flex: 0 0 auto;
}
.tile-content {
flex: 1 1 auto;
&:not(:first-child) {
padding-left: @unit-2;
}
&:not(:last-child) {
padding-right: @unit-2;
}
}
.tile-title,
.tile-subtitle {
line-height: @line-height;
}
&.tile-centered {
align-items: center;
.tile-content {
overflow: hidden;
}
.tile-title,
.tile-subtitle {
margin-bottom: 0;
.text-ellipsis;
}
}
}

View File

@ -0,0 +1,55 @@
// Timelines
.timeline {
.timeline-item {
display: flex;
margin-bottom: @unit-6;
position: relative;
&::before {
background: @border-color;
content: "";
height: 100%;
left: 11px;
position: absolute;
top: @unit-6;
width: 2px;
}
.timeline-left {
flex: 0 0 auto;
}
.timeline-content {
flex: 1 1 auto;
padding: 2px 0 2px @layout-spacing-lg;
}
.timeline-icon {
border-radius: 50%;
color: @light-color;
display: block;
height: @unit-6;
text-align: center;
width: @unit-6;
&::before {
border: @border-width-lg solid @primary-color;
border-radius: 50%;
content: "";
display: block;
height: @unit-2;
left: @unit-2;
position: absolute;
top: @unit-2;
width: @unit-2;
}
&.icon-lg {
background: @primary-color;
font-size: @font-size-lg;
line-height: @line-height;
&::before {
content: none;
}
}
}
}
}

View File

@ -0,0 +1,41 @@
// Toasts
.toast {
border: @border-width solid @dark-color;
border-radius: @border-radius;
color: @light-color;
display: block;
padding: @layout-spacing;
.toast-variant(@dark-color);
width: 100%;
&.toast-primary {
.toast-variant(@primary-color);
}
&.toast-success {
.toast-variant(@success-color);
}
&.toast-warning {
.toast-variant(@warning-color);
}
&.toast-error {
.toast-variant(@error-color);
}
a {
color: @light-color;
text-decoration: underline;
&:focus,
&:hover,
&:active,
&.active {
opacity: .75;
}
}
.btn-clear {
margin: 2px -2px 2px 4px;
}
}

View File

@ -0,0 +1,77 @@
// Tooltips
.tooltip {
position: relative;
&::after {
background: fade(@dark-color, 90%);
border-radius: @border-radius;
bottom: 100%;
color: @light-color;
content: attr(data-tooltip);
display: block;
font-size: @font-size-sm;
left: 50%;
max-width: @control-max-width;
opacity: 0;
overflow: hidden;
padding: @unit-1 @unit-2;
pointer-events: none;
position: absolute;
text-overflow: ellipsis;
transform: translate(-50%, @unit-2);
transition: all .2s ease;
white-space: nowrap;
z-index: @zindex-3;
}
&:focus,
&:hover {
&::after {
opacity: 1;
transform: translate(-50%, -@unit-1);
}
}
&[disabled],
&.disabled {
pointer-events: auto;
}
&.tooltip-right {
&::after {
bottom: 50%;
left: 100%;
transform: translate(-@unit-1, 50%);
}
&:focus,
&:hover {
&::after {
transform: translate(@unit-1, 50%);
}
}
}
&.tooltip-bottom {
&::after {
bottom: auto;
top: 100%;
transform: translate(-50%, -@unit-2);
}
&:focus,
&:hover {
&::after {
transform: translate(-50%, @unit-1);
}
}
}
&.tooltip-left {
&::after {
bottom: 50%;
left: auto;
right: 100%;
transform: translate(@unit-2, 50%);
}
&:focus,
&:hover {
&::after {
transform: translate(-@unit-1, 50%);
}
}
}
}

View File

@ -0,0 +1,127 @@
// Typography
// Headings
h1,
h2,
h3,
h4,
h5,
h6 {
color: inherit;
font-weight: 500;
line-height: 1.2;
margin-bottom: .25em;
margin-top: 0;
}
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
font-weight: 500;
}
h1,
.h1 {
font-size: 2rem;
}
h2,
.h2 {
font-size: 1.6rem;
}
h3,
.h3 {
font-size: 1.4rem;
}
h4,
.h4 {
font-size: 1.2rem;
}
h5,
.h5 {
font-size: 1rem;
}
h6,
.h6 {
font-size: .8rem;
}
// Paragraphs
p {
line-height: 1.2 * @line-height;
margin: 0 0 @unit-4;
}
// Semantic text elements
a,
ins,
u {
text-decoration-skip: ink edges;
}
abbr[title] {
border-bottom: @border-width dotted;
cursor: help;
text-decoration: none;
}
kbd {
.label-base();
.label-variant(@light-color, @dark-color);
}
mark {
.label-base();
.label-variant(@body-font-color, @highlight-color);
}
// Blockquote
blockquote {
border-left: @border-width-lg solid @border-color;
margin-left: 0;
padding: @unit-2 @unit-4;
p:last-child {
margin-bottom: 0;
}
}
// Lists
ul,
ol {
margin: @unit-4 0 @unit-4 @unit-4;
padding: 0;
ul,
ol {
margin: @unit-4 0 @unit-4 @unit-4;
}
li {
margin-top: @unit-2;
}
}
ul {
list-style: disc inside;
ul {
list-style-type: circle;
}
}
ol {
list-style: decimal inside;
ol {
list-style-type: lower-alpha;
}
}
dl {
dt {
font-weight: bold;
}
dd {
margin: @unit-2 0 @unit-4 0;
}
}

View File

@ -0,0 +1,7 @@
@import 'utilities/colors.less';
@import 'utilities/display.less';
@import 'utilities/divider.less';
@import 'utilities/loading.less';
@import 'utilities/position.less';
@import 'utilities/shapes.less';
@import 'utilities/text.less';

View File

@ -0,0 +1,45 @@
// Text colors
.text-primary {
.text-color-variant(@primary-color);
}
.text-secondary {
.text-color-variant(@secondary-color-dark);
}
.text-gray {
.text-color-variant(@gray-color);
}
.text-light {
.text-color-variant(@light-color);
}
.text-success {
.text-color-variant(@success-color);
}
.text-warning {
.text-color-variant(@warning-color);
}
.text-error {
.text-color-variant(@error-color);
}
// Background colors
.bg-primary {
.bg-color-variant(@primary-color);
}
.bg-secondary {
.bg-color-variant(@secondary-color);
}
.bg-dark {
.bg-color-variant(@dark-color);
}
.bg-gray {
.bg-color-variant(@bg-color);
}
.bg-success {
.bg-color-variant(@success-color);
}
.bg-warning {
.bg-color-variant(@warning-color);
}
.bg-error {
.bg-color-variant(@error-color);
}

View File

@ -0,0 +1,47 @@
// Display
.d-block {
display: block;
}
.d-inline {
display: inline;
}
.d-inline-block {
display: inline-block;
}
.d-flex {
display: flex;
}
.d-inline-flex {
display: inline-flex;
}
.d-none,
.hide {
display: none !important;
}
.d-visible {
visibility: visible;
}
.d-invisible {
visibility: hidden;
}
.text-hide {
background: transparent;
border: 0;
color: transparent;
font-size: 0;
line-height: 0;
text-shadow: none;
}
.text-assistive {
border: 0;
clip: rect(0,0,0,0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.hand {
cursor: pointer;
}

View File

@ -0,0 +1,50 @@
// Divider
.divider,
.divider-vert {
display: block;
position: relative;
&[data-content]::after {
background: @bg-color-light;
color: @gray-color;
content: attr(data-content);
display: inline-block;
font-size: @font-size-sm;
padding: 0 @unit-2;
transform: translateY(-@font-size-sm + @border-width);
}
}
.divider {
border-top: @border-width solid @border-color;
height: @border-width;
margin: @unit-2 0;
&[data-content] {
margin: @unit-4 0;
}
}
.divider-vert {
display: block;
padding: @unit-4;
&::before {
border-left: @border-width solid @border-color;
bottom: @unit-2;
content: "";
display: block;
left: 50%;
position: absolute;
top: @unit-2;
transform: translateX(-50%);
}
&[data-content]::after {
left: 50%;
padding: @unit-1 0;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
}

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