├── .devcontainer └── devcontainer.json ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── build-layer.sh ├── docs ├── 00-setup.md ├── 01-use.md ├── 404.html ├── Gemfile ├── LICENSE.txt ├── _config.yml ├── _includes │ ├── custom-head.html │ ├── disqus_comments.html │ ├── footer.html │ ├── google-analytics.html │ ├── head.html │ ├── header.html │ ├── social-icons │ │ ├── devto.svg │ │ ├── dribbble.svg │ │ ├── facebook.svg │ │ ├── flickr.svg │ │ ├── github.svg │ │ ├── gitlab.svg │ │ ├── google_scholar.svg │ │ ├── instagram.svg │ │ ├── keybase.svg │ │ ├── linkedin.svg │ │ ├── mastodon.svg │ │ ├── microdotblog.svg │ │ ├── pinterest.svg │ │ ├── rss.svg │ │ ├── stackoverflow.svg │ │ ├── telegram.svg │ │ ├── twitter.svg │ │ └── youtube.svg │ ├── social-item.html │ ├── social.html │ └── svg_symbol.html ├── _layouts │ ├── base.html │ ├── home.html │ ├── page.html │ └── post.html ├── _sass │ └── minima │ │ ├── _base.scss │ │ ├── _layout.scss │ │ ├── custom-styles.scss │ │ ├── custom-variables.scss │ │ ├── initialize.scss │ │ └── skins │ │ ├── auto.scss │ │ ├── classic.scss │ │ ├── dark.scss │ │ ├── solarized-dark.scss │ │ ├── solarized-light.scss │ │ └── solarized.scss ├── assets │ ├── DejaVuSansCircle.png │ ├── css │ │ └── style.scss │ └── favicon.ico ├── index.md ├── minima.gemspec └── script │ ├── bootstrap │ ├── build │ ├── cibuild │ └── server ├── lib ├── libX11.so.6 ├── libXau.so.6 ├── libXext.so.6 ├── libXrender.so.1 ├── libblkid.so.1 ├── libbrotlicommon.so.1 ├── libbrotlidec.so.1 ├── libbz2.so.1 ├── libc.so.6 ├── libcairo-gobject.so.2 ├── libcairo.so.2 ├── libdatrie.so.1 ├── libffi.so.8 ├── libfontconfig.so.1 ├── libfreetype.so.6 ├── libfribidi.so.0 ├── libgcc_s.so.1 ├── libgdk_pixbuf-2.0.so.0 ├── libgif.so.7 ├── libgio-2.0.so.0 ├── libglib-2.0.so.0 ├── libgmodule-2.0.so.0 ├── libgobject-2.0.so.0 ├── libgraphite2.so.3 ├── libharfbuzz.so.0 ├── libjpeg.so.62 ├── liblzma.so.5 ├── libm.so.6 ├── libmount.so.1 ├── libpango-1.0.so.0 ├── libpangocairo-1.0.so.0 ├── libpangoft2-1.0.so.0 ├── libpcre2-8.so.0 ├── libpixman-1.so.0 ├── libpng16.so.16 ├── librsvg-2.so.2 ├── libselinux.so.1 ├── libstdc++.so.6 ├── libthai.so.0 ├── libxcb-render.so.0 ├── libxcb-shm.so.0 ├── libxcb.so.1 ├── libxml2.so.2 └── libz.so.1 ├── nodejs └── test │ ├── canvas-font.js │ ├── canvas-svg.js │ ├── chart-line.js │ ├── fabric-rectangle.js │ └── konva-circle.js └── package-sam.yml /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "public.ecr.aws/amazonlinux/amazonlinux:2023", 3 | "features": { 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | # github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | # patreon: # Replace with a single Patreon username 5 | # open_collective: # Replace with a single Open Collective username 6 | # ko_fi: # Replace with a single Ko-fi username 7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | # liberapay: # Replace with a single Liberapay username 10 | # issuehunt: # Replace with a single IssueHunt username 11 | # otechie: # Replace with a single Otechie username 12 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | 14 | custom: ['https://paypal.me/charoitel'] 15 | 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | docs/.jekyll-cache 3 | docs/_site 4 | docs/Gemfile.lock 5 | nodejs/node_modules 6 | nodejs/node*/node_modules 7 | nodejs/package*.json 8 | package*.json 9 | canvas-nodejs_v*.zip 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2025 Charoite Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Canvas Layer for AWS Lambda 2 | 3 | ![GitHub](https://img.shields.io/github/license/charoitel/lambda-layer-canvas-nodejs) 4 | 5 | Canvas Layer for AWS Lambda is published and available on [AWS Serverless Application Repository](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:990551184979:applications~lambda-layer-canvas-nodejs), and GitHub at [charoitel/lambda-layer-canvas-nodejs](https://github.com/charoitel/lambda-layer-canvas-nodejs). The layer aims to provide a Cairo backed Mozilla Web Canvas API implementation layer for AWS Lambda, powered by [node-canvas](https://github.com/Automattic/node-canvas). 6 | 7 | ## About node-canvas 8 | 9 | [node-canvas](https://github.com/Automattic/node-canvas) is a Cairo backed Canvas implementation for Node.js. It implements the [Mozilla Web Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) as closely as possible. For the latest API compliance, you may check [Compatibility Status](https://github.com/Automattic/node-canvas/wiki/Compatibility-Status). 10 | 11 | ## How this layer is built? 12 | 13 | The layer is built from source of node-canvas npm package on [amazonlinux](https://hub.docker.com/_/amazonlinux) dev container instance, with following native dependencies installed. You may check the build layer script, ``` build-layer.sh ```, which is available in repository, for details. 14 | 15 | ```bash 16 | gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel librsvg2-devel pango-devel bzip2-devel jq python3 17 | ``` 18 | 19 | Since AWS Lambda is a secure and isolated runtime and execution environment, the layer aims to target AWS Lambda compatible and native build. As there are canvas libraries and frameworks relying on node-canvas running on Node.js runtime, this layer may also try to include and support those libraries and frameworks. Currently, following libraries and frameworks are included when building and packaging the layer: 20 | 21 | - [Chart.js](#chartjs-support) 22 | - [Fabric.js](#fabricjs-support) 23 | - [Konva](#konva-support) 24 | 25 | ### Chart.js support 26 | 27 | [Chart.js](https://github.com/chartjs/chart.js) provides a set of frequently used chart types, plugins, and customization options. In addition to a reasonable set of built-in chart types, there are also community-maintained chart types. 28 | 29 | > Current supported version chart.js@4.4.9 with chartjs-node-canvas@5.0.0 30 | 31 | ### Fabric.js support 32 | 33 | [Fabric.js](https://github.com/fabricjs/fabric.js) provides a missing and interactive object model for canvas, as well as an SVG parser, layer of interactivity, and a whole suite of other indispensable tools. 34 | 35 | > Current supported version fabric@6.6.4 36 | 37 | ### Konva support 38 | 39 | [Konva](https://github.com/konvajs/konva) enables high performance animations, transitions, node nesting, layering, filtering, caching, event handling for desktop and mobile applications, and much more. 40 | 41 | > Current supported version konva@9.3.20 42 | -------------------------------------------------------------------------------- /build-layer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Setup environment before build layer 4 | # yum update -y 5 | # yum groupinstall "Development Tools" -y 6 | # yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel librsvg2-devel pango-devel bzip2-devel jq python3 -y 7 | # 8 | # Setting Up Node.js, refer https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html for details 9 | # curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash 10 | # . ~/.nvm/nvm.sh 11 | # nvm install --lts 12 | # 13 | set -e 14 | 15 | LAYER_NAME=canvas-nodejs 16 | LAYER_DESCRIPTION="Cairo backed Mozilla Web Canvas API implementation layer for AWS Lambda" 17 | LAYER_VERSION=3.1.0 18 | LAYER_AUTHOR="Charoite Lee" 19 | 20 | DOT_CHAR="." 21 | NODE_VERSION=$(node -v) 22 | NODE_VERSION=${NODE_VERSION:1} 23 | SEMVER_VERSION=7.7.1 24 | 25 | # Remove packaged layer if exists 26 | if [ -n "$(find . -name 'canvas-nodejs_v*.zip')" ]; then 27 | rm canvas-nodejs_v*.zip 28 | fi 29 | 30 | # Clean and prepare Node.js modules and dependencies 31 | if [ "$(ls -A lib)" ]; then 32 | rm lib/* 33 | fi 34 | cd nodejs 35 | if [ "$(ls -A node*)" ]; then 36 | rm -rf node* 37 | fi 38 | rm -rf node_modules node${NODE_VERSION%%$DOT_CHAR*} package*.json ../package-lock.json 39 | npm init -y 40 | npm install canvas --build-from-source 41 | npm install fabric 42 | npm install konva 43 | npm install chartjs-node-canvas chart.js 44 | npm install mocha --save-dev 45 | jq --arg LAYER_NAME "$LAYER_NAME" --arg LAYER_DESCRIPTION "$LAYER_DESCRIPTION" --arg LAYER_VERSION "$LAYER_VERSION" --arg LAYER_AUTHOR "$LAYER_AUTHOR" --arg SEMVER_VERSION "$SEMVER_VERSION" '.name = $LAYER_NAME | .description = $LAYER_DESCRIPTION | .version = $LAYER_VERSION | .license = "MIT" | .author = $LAYER_AUTHOR | .scripts.test = "mocha" | .overrides.semver = $SEMVER_VERSION ' package.json > package-tmp.json 46 | mv -f package-tmp.json package.json 47 | 48 | # Test if installed modules and dependencies work fine 49 | npm test 50 | cp package-lock.json .. 51 | npm rm mocha 52 | 53 | # Prepare and package layer 54 | mkdir node${NODE_VERSION%%$DOT_CHAR*} 55 | mv node_modules node${NODE_VERSION%%$DOT_CHAR*} 56 | cd .. 57 | find nodejs/node${NODE_VERSION%%$DOT_CHAR*} -type f -name '*.node' 2>/dev/null | grep -v 'obj\.target' | xargs ldd | awk 'NF == 4 { system("cp " $3 " lib") }' 58 | zip -q -r canvas-nodejs_v$LAYER_VERSION-node${NODE_VERSION%%$DOT_CHAR*}.zip . -x LICENSE README.md .git/**\* .github/**\* .gitignore nodejs/test/**\* *.yml build-layer.sh 59 | -------------------------------------------------------------------------------- /docs/00-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Setup 4 | permalink: /setup/ 5 | --- 6 | 7 | ## Prerequisites 8 | 9 | In order to start to use [lambda-layer-canvas-nodejs](https://github.com/charoitel/lambda-layer-canvas-nodejs) published on [AWS Serverless Application Repository](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:990551184979:applications~lambda-layer-canvas-nodejs), you must have your AWS account with following services available: 10 | 11 | - [AWS Serverless Application Repository](https://aws.amazon.com/serverless/serverlessrepo) 12 | - [AWS Lambda](https://aws.amazon.com/lambda) 13 | 14 | ## Serverless application deployment 15 | 16 | Once you have your AWS account ready, there are two ways to deploy [lambda-layer-canvas-nodejs](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:990551184979:applications~lambda-layer-canvas-nodejs) and make it available in your AWS Lambda console: 17 | 18 | - [Deploy through AWS Serverless Application Repository](#deploy-through-aws-serverless-application-repository) 19 | - [Deploy through AWS Lambda console](#deploy-through-aws-lambda-console) 20 | 21 | ### Deploy through AWS Serverless Application Repository 22 | 23 | 1. Open https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:990551184979:applications~lambda-layer-canvas-nodejs 24 | 2. Click **Deploy** button 25 | 3. Login to your AWS account if you haven't login yet 26 | 4. Edit **_Name_** (Optional) 27 | 5. Click **Deploy** button 28 | 6. Deployment is started and in progress 29 | 7. Check your AWS Lambda console once the deployment is completed 30 | 31 | ### Deploy through AWS Lambda console 32 | 33 | 1. Login to your AWS account and open your AWS Lambda console 34 | 2. Click **Create application** button 35 | 3. Select **_Serverless application_** 36 | 4. Input `lambda-layer-canvas-nodejs` into search box and press _Enter_ key 37 | 5. Click on the title of `lambda-layer-canvas-nodejs` card 38 | 6. Edit **_Name_** (Optional) 39 | 7. Click **Deploy** button 40 | 8. Deployment is started and in progress 41 | 9. Check your AWS Lambda console once the deployment is completed 42 | 43 | ### Using canvas layer 44 | 45 | After the deployment is completed, you may refer [usage example](/lambda-layer-canvas-nodejs/{% link 01-use.md %}) and follow the example where a Lambda function uses the canvas layer to generate PNG graphic with colored text and circle rendered. 46 | 47 | ## Setup environment to build the layer 48 | 49 | Alternately, you may setup your own environment to build the layer according to your specific needs. When using the layer with nodejs-18.x in Amazon Linux, it requires glibc-2.28, meanwhile, compiling glibc-2.28 requires make-4.x or later[^1]. 50 | 51 | ```console 52 | $ wget https://ftp.gnu.org/gnu/make/make-4.3.tar.gz 53 | $ tar -xzvf make-4.3.tar.gz 54 | $ cd make-4.3/ 55 | $ ./configure --prefix=/usr 56 | $ make 57 | $ make install 58 | ``` 59 | Once make-4.x or later is ready, we may start to compiling glibc-2.28 on Amazon Linux. However, during `make install` there would be an error due to `cannot found -lnss_test2` which could be ignored[^2]. 60 | 61 | ```console 62 | $ wget https://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz 63 | $ tar -xzvf glibc-2.28.tar.gz 64 | $ cd glibc-2.28 65 | $ mkdir build && cd build 66 | $ ../configure --prefix=/usr --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin 67 | $ make 68 | $ make install 69 | ... 70 | /usr/bin/ld: cannot find -lnss_test2 71 | collect2: error: ld returned 1 exit status 72 | Execution of gcc -B/usr/bin/ failed! 73 | ... 74 | ``` 75 | 76 | To test if the installation of the compiled glibc-2.28 is success or not, we may check if `GLIBC_2.28` is enabled[^1] [^2]. 77 | 78 | ```console 79 | $ ls -l /lib64/libc.so.6 80 | lrwxrwxrwx 1 root root 12 Jul 3 15:14 /lib64/libc.so.6 -> libc-2.28.so 81 | $ strings /lib64/libc.so.6 | grep GLIBC 82 | ... 83 | GLIBC_2.22 84 | GLIBC_2.23 85 | GLIBC_2.24 86 | GLIBC_2.25 87 | GLIBC_2.26 88 | GLIBC_2.27 89 | GLIBC_2.28 90 | GLIBC_PRIVATE 91 | ... 92 | ``` 93 | 94 | Once your environment is ready, you may execute the build layer script, ``` build-layer.sh ```, to build the layer and deploy through the AWS Lambda console. 95 | 96 | --- 97 | 98 | [^1]: [Centos 7 升级 Glibc-2.28](https://cloud.tencent.com/developer/article/2021784) 99 | [^2]: [CentOS 7.6 编译安装最新版本glibc2.30 实录](https://www.jianshu.com/p/1070373a50f6) -------------------------------------------------------------------------------- /docs/01-use.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Use 4 | permalink: /use/ 5 | --- 6 | 7 | ## Using canvas layer in function 8 | 9 | Before starting to use the canvas layer, it is required to have the layer deployed through AWS Serverless Application Repository or AWS Lambda console, you may refer [setup information](/lambda-layer-canvas-nodejs/{% link 00-setup.md %}) for details. Then, you may create your Lambda function using: 10 | 11 | * AWS Lambda console editor; or 12 | * Local tool in your machine; or 13 | * Any way you may prefer 14 | 15 | Following is an example where a Lambda function uses the canvas layer to generate PNG graphic with colored text and circle rendered. There is no environment variable setting is required in this example. 16 | 17 | ## Function structure 18 | 19 | The setup of the function may look like the following structure. For font file, you may use any supported font file you like, in this example, we are going to use DejaVu Sans[^2] which could be originally found in Amazon Linux 2 EC2 instance. 20 | 21 | ``` 22 | /var/task/ 23 | . 24 | ├── fonts/ 25 | ├── DejaVuSans.ttf 26 | ├── fonts.conf 27 | ├── index.js 28 | ``` 29 | 30 | ## Font configuration using fonts.config 31 | 32 | Since AWS Lambda does not appear to support even the basic fonts on its own, so we create the fonts directory at the root directory for our Lambda function with following font configuration file[^1]. 33 | 34 | ```xml 35 | 36 | 37 | 38 | /var/task/fonts 39 | /tmp/fonts-cache/ 40 | 41 | 42 | ``` 43 | 44 | ## Build function code in index.js 45 | 46 | Once the setup is ready, we may put following function code and test it in AWS Lambda console. 47 | 48 | ```javascript 49 | let { registerFont, createCanvas } = require('canvas'); 50 | 51 | exports.handler = async (event) => { 52 | registerFont(__dirname.concat('/fonts/DejaVuSans.ttf'), { family: 'DejaVu Sans' }); 53 | 54 | let canvas = createCanvas(300, 300); 55 | var ctxCircle = canvas.getContext('2d'); 56 | var X = canvas.width / 2; 57 | var Y = canvas.height / 2; 58 | var R = 45; 59 | ctxCircle.beginPath(); 60 | ctxCircle.arc(X, Y, R, 0, 2 * Math.PI, false); 61 | ctxCircle.lineWidth = 3; 62 | ctxCircle.strokeStyle = '#FF9900'; 63 | ctxCircle.stroke(); 64 | 65 | var ctxText = canvas.getContext('2d'); 66 | ctxText.font = '40px "DejaVu Sans"'; 67 | ctxText.fillStyle = '#146EB4'; 68 | ctxText.fillText('DejaVu Sans', 15, 120); 69 | 70 | const response = { 71 | statusCode: 200, 72 | body: JSON.stringify(canvas.toDataURL()), 73 | }; 74 | 75 | return response; 76 | }; 77 | ``` 78 | Following is the sample response from the above example function code. 79 | 80 | ```JSON 81 | { 82 | "statusCode": 200, 83 | "body": "\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nO3dd3hc5Zn38e99RpI7LhoZTAvhNRBKKAGWloRACsUyNs0hhJqNLZpkU5bsJrtEpJEC2MgBWwYSEjYJmB7JxlSTpSRLaAmBEKqzNBfJDdvYkubc7x8ajc6ojqwyM/Lvc12+POfRc87cmnLrPOc8BUREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREtkWW7QDyRcnMms+625Mt226cXX9D6X9nMyaBkosWjqRg2OlgR4fGZ8zZARgNJIB1hi9z7K9u/nTBlqIlK+YftzLLIUsvFPTVgXa8vCbe0GiruqnWYPCRwzrwdYYtc3gR54UCgmeXzz2xu/23afHy2qswrm7ZNvjVqqrS83p93Fk1XyC0pZGiv9dVle7T2+P2q8qFRfHVw77t2GXAKADzdrWGObYDcLi5zUgUNYbxitqn3Lh51LoRdy+77ZjNAxy19FIwwM9X5FAM7A52kMPJwPcwapss/DBeXru0ZGbNV6lc2meJdDBJBH4bELZsO5wWv/KBUb09riWC89sU/aK3x+xP2126ZFx8zfCnwb5LMlllKAA+b87tG7bb0OtELwNvoBNWV2IYX3C3O+L1G18qmVnz2WwHlGvW3DD5/wx7NFI0wj6Ond6bY44rX7ydm58aKWoMLHF7b47Zr2Y8V1iUSCzBOSRS6ji/x+3MwIOJ1rRpVN24TUNCD3Yx7ASMOcB72QpZ+k6/nck4LKuvKv1k2/Jx5Yu3o7BhdCwsLHYPD3W3ww2mAuNSlYx93W1pSUXtZauqSuf2V4x5ycJf4PaVlk03zqMXZ0SB+TRgRKRo8cobpqzoRYT9Kj70w3KwQ1MFxjoPOa1+bumjbeuubk5S7wFLmPHclfEhH07D7NtAbjd3pVN9dtG97TWszhJWh/vOqBneMNTOAn4IxKM/c+ei+rml8/oqzny323lLh27YbuP7tCZ4t1hiz1Wzp7y5NceLz6x9CueoVIExpe6G0t/3Qaj9Il5R+zbQ+rnqabwzniuMD10+E/cP6+ZO/k0/hCj9KCeahB8smLyprqp0QejBQcD/Rn9mxpyS8sUHZSm0nLPstmM2O0S/aBYmYlt1PSY+88G9cI6MFC2vGztice8i7D/Fs2r3Jpqs4PUeJ9cFhzTWVZVeq2SVn3Lq4vbquSe+t+PlNaUNjfYc8IlkcZFbeAPw+Z4ca/zMB/YPw9hUjC/j9gnM4zRfsK4D+6vDQ4mg4Tdr55y8to9/jTSjLr63eEhsyMngR+MchLETsJ3BGodV5vasw5K6LdvfzYJDGjM5ZuDBL93C8pZtczuHysqrqKwMu9qvLfOm8xyzSMHtVB7T1JNjDKQgtE84abcCX+rv5+yP96878Use2NGs4BtuXgrsSnOrow54xbH7R60ffmtP7nBOLF88ZH3gpaH7VIMDHXaiuevHRmA1+MsOzxQGBb9bPueEZX3xO/SXnGgSttXBbXYCOGplVekz3e27/aW1uzcl+InBqXT/+602qMzkOllP+2GNr6g9MoFfZtgUMvjD4LDMnEvq5pYu6q4uQLyi5gWw1Jln6H7c6rmTH85kXwBOXxiLTxj+T5o/vM0xBOxTP6f0783HXzQP/IKWn9VVlWb8WSmuqH3HYLfk5pK6qtITMo6rCyUVi6Y5fmek6Dd1VaVn9cWx2+rv9694Zu1Z5rTe3Aj8mLo5k5+IV9RcADYbGNrVc8Xcp66cO/kv3T1P8rt0C/D/MggrNHgA/Furqia/kcnvMdByoknYVt2cyU/QpmkYYmd3t9/4SxYfFSZ41uA0MkvG4xyq4hW1t1BZ2aevRQhPG3YqGZ7FGuyG8UB8Zs30TOq7pV9oDwLrUbOwZPuRXyGSrMz5Y0uyylUJY016iffbxfP+fv86Eq+o/RnYPLpIVi3PFZo9vsOsB3frql7JJYtPILSHyCxZAQQOJztWlWH9AZeTCauZ3RLdcvz4rmqXlC8+KAzCR5L9vJqPgD1s5mckzD8xcv2IYUWbfUQCPg1WCWkf/n+Nrz7kO30bfyrwV8AqQ/fjCBM7FW32EWM8GBp6sIsZ0wweidSO4fbzTK7ZNQaFvwVamwXO1DGz7huTcVhBmNb3ys1yuu8VQKyRlyHaJrSDistrv9SvT9pP7187CTsTuALAnYccmxpYYoe6cSMKCQp2NOObwPuRPcY1eeLnnR0ufuUDozwIbwWKWn8Vvwf3kzz0vUMPRteN2zTEmmyC41/C+B7wVo/jHmA5dQ0rygN/2iJXZAx22/6Ch8Z3NLSi5KKFI93CO4FhyaLNhp27qmrSwpY6kez0N+BvYy5edFtBzJcAn0qWf3dsRe19a6pK/9ZHv8JjAVy1cm6nzdj3gLuAu+Iza6bjNp/mPyBFHiSuBb7Y1cHXzz5+dbyi9n7gjGTRsIKw4AxgfneBjbr43mLgpEjRRoY23dlZ/Vyx6qZJy0vKa//kxhEtZRZwd7xi0RV1m7f/VV9dQ0rq1/evHWM6ELpRXl9VelP0R3XwIXDruMvufzhoKvhfYAIAzqT4xYv2rLtx0uvtjvdxcBKWrAfgdmX93NKfta22CpbT/O8x8MriitqpYMf0KPYBlLNnWPVzJr2GsS5a1liY2L2jumHBsIuAPVIFbt+IJquOrL1x0j8tlphM61lKLIZf2buoW9VVlX4pk2tuAHU3TL4Z7NpUgdsx8YsX7dndfmG7s6LMmoVDY0VnAkNSe8HddT+d8lEm+2ZbCFcR6e2PMxr85vjQ5e/HK2r/u7ii9tzumkqZGIj3rx3z6+pvSE9WUauvn/quOf+ZtkvMO+w4bNjh0V3riofPziSA+qrJ99VXlVZkGPGAy9mEBeY4H0ZLAsLidtVmPFdoWHlrgf2hbu6k32XyDKtmT3kT45eRfU9hxnOFWxlwr2xJbPkpzQN2AcwLwq90VR9g9dg/Pwb8M1J02Ljyxd1e13EnPbFtZXPQKynw+ezh8/miV3O6L+A8r+aS0bENo1vq7Fq4Yiev5nSfzxd9Pnt4Ze/O6uvnlj6KcSXQduRgCfB1g9uawsQ78Yra1fGK2kfjFbXfGzdz0Zf7e7jX1rx/bayNFRZd3W2txKaFRC4FuNshHVXzgOh3ZUUu3/3tiRxOWGB4WpcDD7xdwho/dPmhwM6t+4S/6tGThETv6owYN2TlwT0Ms098dOMp9W682rIdhMGhXdUHaO7G4LdFi4Ig0eVZ1vjymgMwPhMpemPVDSc+2ekOSV7NcJ/Pl72aH/gC7vdqXmMCmzBex3gUWIjzS2Du6GDj2Jb9Jg5579PAQoxHMV5nApu8mte8mvuSx/qSX59qymek7obS6wwvxemqs+xYmptl/xW4Pxxfs+H9eMWinySbw31uq96/CId7V1x73Mbu6q26adoGvPV5MN+rw4ohGyJbE/vr9x5oOZ2wHEt/Az1oN9A14XwubTvmz/boOdzTLjSa+R6d1e1v5qSGxLh5Rs2agqAgbUA0bmd3dTaRsPSBzmbc1uE8B+2twXgY+A7OFGAvYGvORguT+05NHusRRrDGq3nCF3CVz89s2MyqqsmL67bssA/wNYxFRG9AdMRtPPiVQ2JFbxbPqpm6FXF3a2vev9S+5n/qQfXouMiOb7QYz0W2CofEiu4dX74407uFOStnL7onjWyzvb5tBTM+Hd0OEsHf4hW1W/2E5u3P4nojreMh7Gewi8Nw6O6swjK647d8zgnL4hW1jwMtd8t2iK/ZdHwdtH8RKhcW2Wr/eqQkEQaedkbq8xhPjK9d+O7S0+5e94Xoj4poz4H/w3gHZxXORowNH4XDz6a5YyJ1idHvA88A42nupb4L7bucDAGOxjka42qv5nmM20nwO7uQzuevWnBIYx3cAdyx23lLh24Ys+FwT9hhhh2E+SF0fDt/jIV2b/HM2nMymc+sv9+/VsGH3ddpObRviLyEbb8jADQFjQsLwsKf0JrQPh9a+Fq8fFEtQbg4jCWWrL5+6rs9izH7cjxh+ZjoZzsgrG9XxXwc3nfzEJqlDQTeattf8dCIREPTVeCzwCO3ljPlmU+b4vYLzFO3993D8+ggYRXXDy/F0sZqPlQ/e/L7AD6fAzD+AzgVp2Bk8HG7ZwH+hvM4Ac8Ar7OBf9hltKtYXDGq1JIJ668fT3zZypiWOkg1wzH2JGQvjCOBY4F9SU9iB+McTMC1Xs3dBFxj0/lrVy9Bsuf3E8l/AJRc+sBEmgpODAP/pnnaHzYz5+btL/n90yt+ftI7HR1vQN8/AAs3dF+ptXJ0o6Maa+ecvDZeXnMOZnfReoOlAPOpuE0NmgqIly96FwufxHiiqID7Prhucl2PYs6C3G0SVlYGYBOiRaEF7RKWhT39S9YNt15nv7EzHhnd1ND4MM13HTs6M+k+jB6MQhj50fD7iPTcMGzyjpfXxNvWM/O05mBg9gu/mcN9PjUYLwJfpbM/YiE7WBn72wXMshkstBm81FGy6o6Vsclm8JJdwJ1Wxkwr49METMA5AyftgnIyljMIecmrecDn8S89ea5Vs6e8uWrupKr6sc8daEbbfnZDE0Hw7x3tN9DvX3+pmzu5BjjKm89w2zPfBexM3BY0NNqH8Yra323V3c0BlLNnWOPWfWZvYLto2ZCCsF3HNjc2RTbDunGbhlE5raG/4+tKbOiW6yBtUPFG4A7cHsN5wwqb1m5uSKz5aGXTWu6a1nJnieLy2iVmHNfT51t22zGbSypqfuvYxcmiosaG4Ewg1WM5PmvJBMKmVOfbmIdr3tnntPMIKW3z1XLgf/6yeaIDqTZhl02zXrLprADuBO70akYDpwNnA5+j+YtvwEkEnOTV3E+MWfbNtLujXausDFfBj+Iza3fFKYv8ZHLz8KP0a3gD/f71p7qq0ueBo+IVtQcbfppjxwKfof13v/mPQ8wnF8+qOat+zuT7BzzYDORswgoSwVFtit7u8JTVrS7yeQvG14/cZWUWe+yOu+z+XWjiG5GitwqC2JcyGVQawHaZNznSecAvCLk4td18NtU6xCKROAtrfb/Pjy8aOcwaSiOHCHEWA1fbBTwXr9hzHnjaRaxMWTdDS7rct4x1wC3ALV7Np4F/A84EYskqU0lwnFfzU7ZwjVWwJdNjh2FQFVgYTVgTdry8tviD60h9rrL1/vW3ZOJ6HpLz4AcjP+dBeCzYV8D3j1QdYaH9dvtLa/dbMbv07exE27ncbRI29/yNbPqDHVVz87Rb24kgPKKjegMlaCo4gUhzwLHLMx0B78auW/u8dXMmv0D67AUHlsxadGBqq01z8JwxD7Xc4QuBX5FgH7uAyXZBy90lT2vu7Xzpwsy6Hpy+MEZ0MsZesDJetjLOAfYDbqf1bugw4LsM4SVfQMbdB1YXP/sakNYfqWFzkBZrtt6/gbTqpmkbVv38xAfrqkr/ra5q0gEEfgxEukrAsERIeWf7Z1NOJqziSxYf22YKXELn1x1WDoPH07bd++WWdaYMS7udHW4ueqKzulHJW847dVuxy+dOHxAdevN4wfGzao4A9m4pP3DYG+w9dBnASziftTLOs4v4R/rRPO2ObJOP2j6TGOI7DTuArbzu0xkr47Vk4joUI9pt5VM4z/h8vuWewTWjD0pjtPnMBwVNaaMpsvn+ZUvdnMlPxGJMJto9BnJyivKcS1g7Xl4TN0vvDAksrZ87ucP+VaM2DHsGWk/pDZtafEnNpzqqOxBCC9PuMo4YsSaj62lhkCjrvlbXtsQKfgOtTSRzO3PpjfvucPyIP6X1/J82+vGPgUsYyyF2AX/s6FiOpd09Cz3MrENt8yDefmFlvMAYjsSpgNSwrQKMH7OAe/0mxna1f/GwFZ8h/TP/8cqxL6at1JTN9y+bVswufRuntQnofXOW3NdyKmGNu+z+XRoarbb57kXKlsASszrbp3kGTr8+UhSzwP57t/OWbvV1lN4I3NIuTm9ODD+8s7otxpfXHIBbr0/B188+fjVu0Yul8Xc37PyXpzbt3zIZIkXWGI4Zuu4wK+NGm5YaStKOx8Ln0rbxbhNRSUXNHhj99sUdf8nio0qerp27/d8fWEjIgaRPQTSVGM96dedTqZj7f6QVOI+0nfQwm+9fVp2+MEbg0ZtcObnkXk4krB1n1AyPly8qizUVvAgcFvmRg12y8oYpXfbBsaHhz4HoiPWDN4ze+Gj8kgd2zOj5L6+Jl1TUfideXntt97W75oE/nR4cPy25aGGHnfsASmYtOjA0W0wvLlRHhYRpzcLvLT9//PpE60lDwoOF0y77n5e7O87q2Se9AqTmx3Ln5PjM2pM6q7/9Jb//pEMNnXRk7AthQaIQ58LQY2+UvFZz0afeuv1c4GpamzITgad9HmnTu+x86cJh8Zm1NwFT2hxyQdvnyPb711dKZtbeU1xee2FXsUfFJwy/tHk0QAv7Q3/F1hsDfpdwXPni7TxIjIm5lQAHOxzWAFPBx7W5w9LkTkX93Em3dHigiLqfTvloXPnikwML/0TLOnXOUQSxN4oram9199ogVvhy3Zj19SUrKQqHDBtNY2wvCxIHgp3Q0MgXaG5a9Hol57r3P34yvsPwVzD2TcZxiBcMe664ovYaAp4dtXbEOw3FG0Y2NPi+BMFXPfRv0jxc5e8Yq9MWhNgKq4uff3Tntfuv3BwWjQdYm0j/vDYRdPt6ppjPxq3lS204d5XMrJ2dCMLbt1sz6q0N49cX+hb7FGEwNWFUACMxf5Aw2K/NWXJfG4Xbv9VvHntFySu1Tx4x/JU7rxj/21M+WfjhkHjBuu1jQeKJJ67f/7zT//n9evfw2M1NwTc6iGdhR7ODZvv96zPOnmac4gXDr4tX1D7s2CMehC/EGoJ3RsdszbrEhkIvHLWTe/gpw88nPZl/VBAEObnwS78lLIPd4hW1HdzlDYn2TO/kSulfwsAvXD1ncofXVzqyeu6Jr5aULz46tPDeyPS8ww3KzaycsIn46uF4AVgCCMLOn7037pqWCGfVTA9Ce5zUX13by+A2Qtiw3UZoNDBr7TZtrHPjVAu5vrPDZsonVB59TeyscdevOqP9z2BZ/bjnl3awW4fqbii9paRi8WmOt8w8UOTOt4JE8K0N222EzbHmV7D1ZXytyZrOjFnhiwPUa9KAz/9x076cuuyH0fLtgHubX2BrP1TS7f4x2DkdduvO8vvXD4YBUwyfYqHhBc5aHAqGgyc6+gY0uHNers7tnhNNwqQE8Ghgdlrdh5sO7kmyarFq7okvDin0Qx3m0t1g2HTLwa8OLHFFT5+zI8nYT2w+bnfsr2EQHtUX0xP7zewP3Pv1MY8UBB0MIjHstp4tVGFeuDk82eC+DCo/0BQ0HtGfi3rUvf/xk+582bFfQtvpkjPyDu5n1c098ZQ3557Yaf+tbL1/2ecvBnBM/dzSe7MdSWcGuknYQPMA5vXAGseXBWYvkAheLByS+HNfjGVKHqMiPmvJNSQSJ2F+LPBpzItxi2N8hLMa89fMg5dwf3DV8k3PRHss94W6qtKl8Ssf2NM2B98Am+SwP839k9YZLHe3Vyzwe1aNHX5fX8xV5LcwkQQPA2N2LVrBYcNf3fLHTfsOiVQJmxK0vfvarQ8WTN4EnFJcXvslAr5uIZ/F2CH54/8Df94suKV5ipqMZn3YendNS9TDo8CjnL5wevEOww4mCI419wOAvTGfAIwp9LBwVGyTjS1YzycKV2x5bcsuty5vLPnNyqpJf8w0xoF+//paY9D4uQIKDrSQA0KCA8D3suYpd8bS/Hs0Aesx3nLnBfPwnrriF57s6cpLAy3r453yRXFFzRejy8Sb+RmrbpicE9MK+y2MI8GfgZYZWetxPm8XpHUG3Gb4AvbFeRJS3RzepIhD7Xz6dUk36X+51CTMaUH6LAeQiLWb6iYb3DES3EprsvqYkCnbarICsBm8ApxA8xhAgIls4faMOpdKTlPCylQYpPX0DvD3Oqs6oBYwi+bJ8AAc52t2IU93tcu2wMr4X4xzabk0bpSyIDeHm0jmlLAy5ObRUfibV8Q3/qPTygMkOY7ux60FXGcX8ED2IsotNoN7cKJr7F3rN9NtR1DJXTpF7sKOM2qGNw0LJ4ZecC74ZZEf3VVXVTqt0x0HgC+kiDW8RMsYQeNZxvA5m0ZWp9bJNV5NIfAHSC0N9ipwoJXRl0uCyQDRGVYn4hW1DzYMtY2hx/7SJlk1EfiPO91xoKzhCloHNK8lYJqSVXtWRiMBX6d1eu19gEuzGJL0ghJWzzQ6fDM5lUvWeDW7At+OFP1njya028bYdN7BuCpS9F2fR6/XLpSBp4TVHWMd2F8duyHwYO/6qtKeLSPWP+ZCau755xnb/WrP27wPuJHW+cKGE9DrcaMy8HQNK894NYcBLUtChQQcZdPpyRJR2yxfwKE4f6LlD7XxLzaDP2c3KukJnWHln+hiCrcrWWUumZzuSBV4WrNa8oASVh7x+RwAtMzDHpLgmmzGk5cCfkDrdDRTkvPGS55QwsonzesGNjfjnbvbT2ss3bHp/B1omeTQkq+p5AklrDzh8xgPnJIqMH6SvWjynPF9WnrAO6f7zWQ0X71knxJWvgg4k+aJ4gD+YGVktWtFPrMZvITzVHKzgARZ7QQsmVPCyh/npB45t2cxjsEhOruscXYWI5EeUMLKAz6ffSA1T/lmhnBPNuMZJO4EWtZePNSrydpKS5I5Jax8YJwe2bpf8zr1XnKF6dpUgXNa9qKRTClh5YdjU48so+mKJRPGvZHHx3ZRU3KEElaO82qG07r0mWPk5PJLeSnB47QuJXGEX8+wbIYj3VPCynXNy0a1zM3+sk1nRTbDGUzsQlZCambWoYxKTUEjOUoJK9cZR6ceOxkv0SUZMh5PPQ75QhYjkQwoYeW+6NCRHi99Jt0I015TDdPJcUpYuW+v1KMYg2DtuxzjvBbZ2jNrcUhGlLBymFdSQOtqOE7Im9mMZ1Aaweu0XnifmHzNJUcpYeWyHdmd1uE471oZm7IZzmBk57AR+CC5WcQEPpHNeKRrSli5LIx8eVxnV/3GeCPy+JNZjES6oYSVywK2Sz021mQxksEtTHttR2UtDumWElZua/3yOB9lMY7BLYi8tqESVi5Twspl0S9PoITVb6J/DEwJK5cpYeUy0xnWgPDUmoVgkWa45BwlLBHJG0pYuUxNlYERPauKnm1JzlHCymW6GDww1PTOG0pYuU1nWANBNzfyhhJWLgsjzRNnbBYjGdyCyGsbqkmYy5SwclnAP1OPjYlZjGRwc/ZIPTaWZTES6YYSVi77gLeBxuTWLsnZR6UP+a8ZAeyY3Gzgw8gfCck5Slg5zCppAt5u2Uw7E5C+8TF70bKaNryZfM0lRylh5TpLm69JS1H1NY/MN+b8I4uRSAaUsHKd87fUY+PILEYyOEVfU4u81pKTlLBynaetknNM1uIYvL6YehTwRBbjkAwoYeU642lgS3JrP7+Z7bMZzmDi1UygtZm9mY80Z36uU8LKcclZRv/UsklCK7v0oWNoueDuPGOXpZaulxylhJUPoktRwSlZi2OwMU6OPH68i5qSI5Sw8kHI3anHxkn+S8ZkMZpBwasZjTMpUnRP1oKRjClh5QG7gFeBF5KbQ2ngtGzGM0h8FZJL0xvPWlla9xHJUUpY+cL4dWTr7KzFMXi0vobO7VmMQ3pACStfJPgdrcN0Pu83c3A2w8lnPo+DgKOSm43AHVkMR3pACStP2IWsBO5NFTj/nr1o8pzxX7TeHVxoZdRlNyDJlBJWPjG+D4QAOKf4AvbNbkD5x+ezD8aUlk2cH2c1IOkRJaw8YjN4BahNbgY438pmPHmp+eyq5XN/n12o4Tj5RAkr34T8MLL1dZ/PEVmLJc/4PI6i+e5gsoBrsheNbA0lrDxjF/Iszn3JzQDj576QWFaDygNeSQEBN9Fy7cq42y7guexGJT2lhJWPEswENia3PsMaLsxmOHlhAuXA/smtTQRckc1wZOsoYeUhu5h3gR9Ein7g89gtW/HkOr+J3YHKSFGlfVMzi+YjJax8NZbrgb8nt0YTsNAXUpTNkHKRV1NIwG8gtfbgq8CcLIYkvaCEladsGg0Y5wINyaJDWauLyO0Y12EcntzaQsA5VpbqgCt5Rgkrj9kM/gyRrg3Opb4gMgPBNs6rOR2nPFJ0hU3n+awFJL1m3VeRXOaOUc09kalSPga+YmU8lc24ss1v5nBCHoPUSkM1zGCKGZ7NuKR3dIaV58xwQv4VeCtZNAx4YFvuBe/z2I+QxbQmq9cp4hwlq/ynhDUI2EWsAY4DViSLxuEs2RbvHPo8diNgCaRWc/6QgOPtfNZmMy7pG0pYg4SV8RbwZUh9MXcm4BmfzwFZDGtA+Xz2IeB/gJ2SResJmWTTeSebcUnfUcIaRKyMl2meQnlzsmgCxlJfMPiXB/NqPovxFLBLsmgzxkl2IS9mMy7pW0pYg4yVsRQ4EVifLBqL84jPH7xzwXs1pwMP09oMXEfICTYjbYk0GQR0l3CQ8nnsl7yWs1OkeAFjKbdpqb5bec0rKWBHfoBzJa2f5eWEnKgzq8FJCWsQ85vYnRhLgD0ixX8m4Kv5fl0n+bvdCRwSKX6dgOPz/XeTzilhDXL+S8bQwK2kLw+2HvgvxnKjTSORpdC2ildSwAQuAa6mdbgNNK96869WxrrsRCYDQQlrG+HVzACqgCGR4r9gXGQzeCZLYfWIz+cQjJuAQyPFWzC+xXSq1M9q8FPC2oYkv/C/AvaJFuP8FvhRcjmxnJO8Hvcdmiffi35mX2ttpg0AAAJ5SURBVCHgXA232XYoYW1jvJpCjItwvg+Miv4IZxHO9+1Cns1WfFE+nwMwLgfOhLRJCjcBP2MsPxosNxAkM0pY2yi/kV0oYDZwagc/fgrj1xRy10D3EE9ec5tG87qBn+2gyl0EXGbTeW8g45LcoIS1jfObOZiQ/wSm0P7zsBmowbmPBEvtYpb3Sww3sgMFHItxMk4pMLRNlRC4H/ihlaVWwJZtkBKWAMnrRDG+jXMaUNhJtVcxHgOeIcE/GMHrdk5qqubMnudGRlLAnjh7YRwJHEv6NbWoRuAujB8lVwySbZwSlqTxX1BCI1+juUl2SHf1gXeBt4E6YAOwAWND88EYCal/cWB3WofOdM54Nrl8/B1a5FSilLCkU34ze5PgVIxjgSNo31TrK5txnsF4jAT32EX8o5+eR/KcEpZkxK9nGMM5EuNonP0w9gImQo/nkW8A3gReo7lbwhMU8IydnxqwLdIpJSzZal5JATuzG86uOGNTTcDm/0k2DZubiMYaQv7JWJblW+96ERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERER4f8DqOCCaaubKHMAAAAASUVORK5CYII=\"" 84 | } 85 | ``` 86 | As a result, the generated PNG graphic with colored text and circle rendered may look like as follow. 87 | 88 | ![](/assets/DejaVuSansCircle.png) 89 | 90 | --- 91 | 92 | [^1]: [AWS Lambda Fonts & libfontconfig](https://medium.com/creditorwatch/aws-lambda-fonts-libfontconfig-5e837281a4ce) 93 | [^2]: [DejaVu Fonts](https://dejavu-fonts.github.io/) 94 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /404.html 3 | layout: default 4 | --- 5 | 6 | 19 | 20 |
21 |

404

22 | 23 |

Page not found :(

24 |

The requested page could not be found.

25 |
26 | -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | gem "minima" 2 | -------------------------------------------------------------------------------- /docs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-present Parker Moore and the minima contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: Canvas Layer for AWS Lambda 2 | description: > 3 | Cairo backed Mozilla Web Canvas API implementation layer for AWS Lambda 4 | theme: minima 5 | minima: 6 | social_links: 7 | - { platform: github, user_url: "https://github.com/charoitel/lambda-layer-canvas-nodejs" } 8 | - { platform: linkedin, user_url: "https://www.linkedin.com/in/charoitel" } 9 | -------------------------------------------------------------------------------- /docs/_includes/custom-head.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/disqus_comments.html: -------------------------------------------------------------------------------- 1 | {%- if page.comments != false and jekyll.environment == "production" -%} 2 | 3 |
4 | 19 | 20 | {%- endif -%} 21 | -------------------------------------------------------------------------------- /docs/_includes/footer.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /docs/_includes/google-analytics.html: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /docs/_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {%- seo -%} 6 | 7 | {%- feed_meta -%} 8 | {%- if jekyll.environment == 'production' and site.google_analytics -%} 9 | {%- include google-analytics.html -%} 10 | {%- endif -%} 11 | 12 | {%- include custom-head.html -%} 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/_includes/header.html: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/devto.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/dribbble.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/flickr.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/github.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/gitlab.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/google_scholar.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/instagram.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/keybase.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/linkedin.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/mastodon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/microdotblog.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/pinterest.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/rss.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/stackoverflow.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/telegram.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-icons/youtube.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/social-item.html: -------------------------------------------------------------------------------- 1 |
  • {% assign entry = include.item %} 2 | 3 | 4 | 5 | 6 | 7 |
  • 8 | -------------------------------------------------------------------------------- /docs/_includes/social.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /docs/_includes/svg_symbol.html: -------------------------------------------------------------------------------- 1 | 2 | {%- include social-icons/{{ include.key }}.svg -%} 3 | 4 | -------------------------------------------------------------------------------- /docs/_layouts/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {%- include head.html -%} 5 | 6 | 7 | 8 | {%- include header.html -%} 9 | 10 |
    11 |
    12 | {{ content }} 13 |
    14 |
    15 | 16 | {%- include footer.html -%} 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | 5 |
    6 | {%- if page.title -%} 7 |

    {{ page.title }}

    8 | {%- endif -%} 9 | 10 | {{ content }} 11 | 12 | 13 | {% if site.paginate %} 14 | {% assign posts = paginator.posts %} 15 | {% else %} 16 | {% assign posts = site.posts %} 17 | {% endif %} 18 | 19 | 20 | {%- if posts.size > 0 -%} 21 | {%- if page.list_title -%} 22 |

    {{ page.list_title }}

    23 | {%- endif -%} 24 |
      25 | {%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%} 26 | {%- for post in posts -%} 27 |
    • 28 | 29 |

      30 | 31 | {{ post.title | escape }} 32 | 33 |

      34 | {%- if site.show_excerpts -%} 35 | {{ post.excerpt }} 36 | {%- endif -%} 37 |
    • 38 | {%- endfor -%} 39 |
    40 | 41 | {% if site.paginate %} 42 |
    43 | 56 |
    57 | {%- endif %} 58 | 59 | {%- endif -%} 60 | 61 |
    -------------------------------------------------------------------------------- /docs/_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 |
    5 | 6 |
    7 |

    {{ page.title | escape }}

    8 |
    9 | 10 |
    11 | {{ content }} 12 |
    13 | 14 |
    15 | -------------------------------------------------------------------------------- /docs/_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 |
    5 | 6 |
    7 |

    {{ page.title | escape }}

    8 | 27 |
    28 | 29 |
    30 | {{ content }} 31 |
    32 | 33 | {%- if site.disqus.shortname -%} 34 | {%- include disqus_comments.html -%} 35 | {%- endif -%} 36 | 37 | 38 |
    39 | -------------------------------------------------------------------------------- /docs/_sass/minima/_base.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: $base-font-size; 3 | } 4 | 5 | /** 6 | * Reset some basic elements 7 | */ 8 | body, h1, h2, h3, h4, h5, h6, 9 | p, blockquote, pre, hr, 10 | dl, dd, ol, ul, figure { 11 | margin: 0; 12 | padding: 0; 13 | 14 | } 15 | 16 | 17 | 18 | /** 19 | * Basic styling 20 | */ 21 | body { 22 | font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family; 23 | color: $text-color; 24 | background-color: $background-color; 25 | -webkit-text-size-adjust: 100%; 26 | -webkit-font-feature-settings: "kern" 1; 27 | -moz-font-feature-settings: "kern" 1; 28 | -o-font-feature-settings: "kern" 1; 29 | font-feature-settings: "kern" 1; 30 | font-kerning: normal; 31 | display: flex; 32 | min-height: 100vh; 33 | flex-direction: column; 34 | overflow-wrap: break-word; 35 | } 36 | 37 | 38 | 39 | /** 40 | * Set `margin-bottom` to maintain vertical rhythm 41 | */ 42 | h1, h2, h3, h4, h5, h6, 43 | p, blockquote, pre, 44 | ul, ol, dl, figure, 45 | %vertical-rhythm { 46 | margin-bottom: $spacing-unit * .5; 47 | } 48 | 49 | hr { 50 | margin-top: $spacing-unit; 51 | margin-bottom: $spacing-unit; 52 | } 53 | 54 | /** 55 | * `main` element 56 | */ 57 | main { 58 | display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */ 59 | } 60 | 61 | 62 | 63 | /** 64 | * Images 65 | */ 66 | img { 67 | max-width: 100%; 68 | vertical-align: middle; 69 | } 70 | 71 | 72 | 73 | /** 74 | * Figures 75 | */ 76 | figure > img { 77 | display: block; 78 | } 79 | 80 | figcaption { 81 | font-size: $small-font-size; 82 | } 83 | 84 | 85 | 86 | /** 87 | * Lists 88 | */ 89 | ul, ol { 90 | margin-left: $spacing-unit; 91 | } 92 | 93 | li { 94 | > ul, 95 | > ol { 96 | margin-bottom: 0; 97 | } 98 | } 99 | 100 | 101 | 102 | /** 103 | * Headings 104 | */ 105 | h1, h2, h3, h4, h5, h6 { 106 | font-weight: $base-font-weight; 107 | } 108 | 109 | 110 | 111 | /** 112 | * Links 113 | */ 114 | a { 115 | color: $link-base-color; 116 | text-decoration: none; 117 | 118 | &:visited { 119 | color: $link-visited-color; 120 | } 121 | 122 | &:hover { 123 | color: $link-hover-color; 124 | text-decoration: underline; 125 | } 126 | 127 | .social-media-list &:hover { 128 | text-decoration: none; 129 | 130 | .username { 131 | text-decoration: underline; 132 | } 133 | } 134 | } 135 | 136 | 137 | /** 138 | * Blockquotes 139 | */ 140 | blockquote { 141 | color: $brand-color; 142 | border-left: 4px solid $border-color-01; 143 | padding-left: $spacing-unit * .5; 144 | @include relative-font-size(1.125); 145 | font-style: italic; 146 | 147 | > :last-child { 148 | margin-bottom: 0; 149 | } 150 | 151 | i, em { 152 | font-style: normal; 153 | } 154 | } 155 | 156 | 157 | 158 | /** 159 | * Code formatting 160 | */ 161 | pre, 162 | code { 163 | font-family: $code-font-family; 164 | font-size: 0.9375em; 165 | border: 1px solid $border-color-01; 166 | border-radius: 3px; 167 | background-color: $code-background-color; 168 | } 169 | 170 | code { 171 | padding: 1px 5px; 172 | } 173 | 174 | pre { 175 | padding: 8px 12px; 176 | overflow-x: auto; 177 | 178 | > code { 179 | border: 0; 180 | padding-right: 0; 181 | padding-left: 0; 182 | } 183 | } 184 | 185 | .highlight { 186 | border-radius: 3px; 187 | background: $code-background-color; 188 | @extend %vertical-rhythm; 189 | 190 | .highlighter-rouge & { 191 | background: $code-background-color; 192 | } 193 | } 194 | 195 | 196 | 197 | /** 198 | * Wrapper 199 | */ 200 | .wrapper { 201 | max-width: calc(#{$content-width} - (#{$spacing-unit})); 202 | margin-right: auto; 203 | margin-left: auto; 204 | padding-right: $spacing-unit * .5; 205 | padding-left: $spacing-unit * .5; 206 | @extend %clearfix; 207 | 208 | @media screen and (min-width: $on-large) { 209 | max-width: calc(#{$content-width} - (#{$spacing-unit} * 2)); 210 | padding-right: $spacing-unit; 211 | padding-left: $spacing-unit; 212 | } 213 | } 214 | 215 | 216 | 217 | /** 218 | * Clearfix 219 | */ 220 | %clearfix:after { 221 | content: ""; 222 | display: table; 223 | clear: both; 224 | } 225 | 226 | 227 | 228 | /** 229 | * Icons 230 | */ 231 | 232 | .orange { 233 | color: #f66a0a; 234 | } 235 | 236 | .grey { 237 | color: #828282; 238 | } 239 | 240 | .svg-icon { 241 | width: 1.25em; 242 | height: 1.25em; 243 | display: inline-block; 244 | fill: currentColor; 245 | vertical-align: text-bottom; 246 | } 247 | 248 | 249 | /** 250 | * Tables 251 | */ 252 | table { 253 | margin-bottom: $spacing-unit; 254 | width: 100%; 255 | text-align: $table-text-align; 256 | color: $table-text-color; 257 | border-collapse: collapse; 258 | border: 1px solid $table-border-color; 259 | tr { 260 | &:nth-child(even) { 261 | background-color: $table-zebra-color; 262 | } 263 | } 264 | th, td { 265 | padding: ($spacing-unit * 33.3333333333 * .01) ($spacing-unit * .5); 266 | } 267 | th { 268 | background-color: $table-header-bg-color; 269 | border: 1px solid $table-header-border; 270 | } 271 | td { 272 | border: 1px solid $table-border-color; 273 | } 274 | 275 | @include media-query($on-laptop) { 276 | display: block; 277 | overflow-x: auto; 278 | -webkit-overflow-scrolling: touch; 279 | -ms-overflow-style: -ms-autohiding-scrollbar; 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /docs/_sass/minima/_layout.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Site header 3 | */ 4 | .site-header { 5 | border-top: 5px solid $border-color-03; 6 | border-bottom: 1px solid $border-color-01; 7 | min-height: $spacing-unit * 1.865; 8 | line-height: $base-line-height * $base-font-size * 2.25; 9 | 10 | // Positioning context for the mobile navigation icon 11 | position: relative; 12 | } 13 | 14 | .site-title { 15 | @include relative-font-size(1.625); 16 | font-weight: 300; 17 | letter-spacing: -1px; 18 | margin-bottom: 0; 19 | float: left; 20 | 21 | @include media-query($on-palm) { 22 | padding-right: 45px; 23 | } 24 | 25 | &, 26 | &:visited { 27 | color: $site-title-color; 28 | } 29 | } 30 | 31 | .site-nav { 32 | position: absolute; 33 | top: 9px; 34 | right: $spacing-unit * .5; 35 | background-color: $background-color; 36 | border: 1px solid $border-color-01; 37 | border-radius: 5px; 38 | text-align: right; 39 | 40 | .nav-trigger { 41 | display: none; 42 | } 43 | 44 | .menu-icon { 45 | float: right; 46 | width: 36px; 47 | height: 26px; 48 | line-height: 0; 49 | padding-top: 10px; 50 | text-align: center; 51 | 52 | > svg path { 53 | fill: $border-color-03; 54 | } 55 | } 56 | 57 | label[for="nav-trigger"] { 58 | display: block; 59 | float: right; 60 | width: 36px; 61 | height: 36px; 62 | z-index: 2; 63 | cursor: pointer; 64 | } 65 | 66 | input ~ .trigger { 67 | clear: both; 68 | display: none; 69 | } 70 | 71 | input:checked ~ .trigger { 72 | display: block; 73 | padding-bottom: 5px; 74 | } 75 | 76 | .page-link { 77 | color: $text-color; 78 | line-height: $base-line-height; 79 | display: block; 80 | padding: 5px 10px; 81 | 82 | // Gaps between nav items, but not on the last one 83 | &:not(:last-child) { 84 | margin-right: 0; 85 | } 86 | margin-left: 20px; 87 | } 88 | 89 | @media screen and (min-width: $on-medium) { 90 | position: static; 91 | float: right; 92 | border: none; 93 | background-color: inherit; 94 | 95 | label[for="nav-trigger"] { 96 | display: none; 97 | } 98 | 99 | .menu-icon { 100 | display: none; 101 | } 102 | 103 | input ~ .trigger { 104 | display: block; 105 | } 106 | 107 | .page-link { 108 | display: inline; 109 | padding: 0; 110 | 111 | &:not(:last-child) { 112 | margin-right: 20px; 113 | } 114 | margin-left: auto; 115 | } 116 | } 117 | } 118 | 119 | 120 | 121 | /** 122 | * Site footer 123 | */ 124 | .site-footer { 125 | border-top: 1px solid $border-color-01; 126 | padding: $spacing-unit 0; 127 | } 128 | 129 | .footer-heading { 130 | @include relative-font-size(1.125); 131 | margin-bottom: $spacing-unit * .5; 132 | } 133 | 134 | .feed-subscribe .svg-icon { 135 | padding: 5px 5px 2px 0 136 | } 137 | 138 | .contact-list, 139 | .social-media-list { 140 | list-style: none; 141 | margin-left: 0; 142 | } 143 | 144 | .footer-col-wrapper, 145 | .social-links { 146 | @include relative-font-size(0.9375); 147 | color: $brand-color; 148 | } 149 | 150 | .footer-col { 151 | margin-bottom: $spacing-unit * .5; 152 | } 153 | 154 | .footer-col-1, 155 | .footer-col-2 { 156 | width: calc(50% - (#{$spacing-unit} / 2)); 157 | } 158 | 159 | .footer-col-3 { 160 | width: calc(100% - (#{$spacing-unit} / 2)); 161 | } 162 | 163 | @media screen and (min-width: $on-large) { 164 | .footer-col-1 { 165 | width: calc(35% - (#{$spacing-unit} / 2)); 166 | } 167 | 168 | .footer-col-2 { 169 | width: calc(20% - (#{$spacing-unit} / 2)); 170 | } 171 | 172 | .footer-col-3 { 173 | width: calc(45% - (#{$spacing-unit} / 2)); 174 | } 175 | } 176 | 177 | @media screen and (min-width: $on-medium) { 178 | .footer-col-wrapper { 179 | display: flex 180 | } 181 | 182 | .footer-col { 183 | width: calc(100% - (#{$spacing-unit} / 2)); 184 | padding: 0 ($spacing-unit * .5); 185 | 186 | &:first-child { 187 | padding-right: $spacing-unit * .5; 188 | padding-left: 0; 189 | } 190 | 191 | &:last-child { 192 | padding-right: 0; 193 | padding-left: $spacing-unit * .5; 194 | } 195 | } 196 | } 197 | 198 | 199 | 200 | /** 201 | * Page content 202 | */ 203 | .page-content { 204 | padding: $spacing-unit 0; 205 | flex: 1 0 auto; 206 | } 207 | 208 | .page-heading { 209 | @include relative-font-size(2); 210 | } 211 | 212 | .post-list-heading { 213 | @include relative-font-size(1.75); 214 | } 215 | 216 | .post-list { 217 | margin-left: 0; 218 | list-style: none; 219 | 220 | > li { 221 | margin-bottom: $spacing-unit; 222 | } 223 | } 224 | 225 | .post-meta { 226 | font-size: $small-font-size; 227 | color: $brand-color; 228 | } 229 | 230 | .post-link { 231 | display: block; 232 | @include relative-font-size(1.5); 233 | } 234 | 235 | 236 | 237 | /** 238 | * Posts 239 | */ 240 | .post-header { 241 | margin-bottom: $spacing-unit; 242 | } 243 | 244 | .post-title, 245 | .post-content h1 { 246 | @include relative-font-size(2.625); 247 | letter-spacing: -1px; 248 | line-height: 1.15; 249 | 250 | @media screen and (min-width: $on-large) { 251 | @include relative-font-size(2.625); 252 | } 253 | } 254 | 255 | .post-content { 256 | margin-bottom: $spacing-unit; 257 | 258 | h1, h2, h3, h4, h5, h6 { margin-top: $spacing-unit } 259 | 260 | h2 { 261 | @include relative-font-size(1.75); 262 | 263 | @media screen and (min-width: $on-large) { 264 | @include relative-font-size(2); 265 | } 266 | } 267 | 268 | h3 { 269 | @include relative-font-size(1.375); 270 | 271 | @media screen and (min-width: $on-large) { 272 | @include relative-font-size(1.625); 273 | } 274 | } 275 | 276 | h4 { 277 | @include relative-font-size(1.25); 278 | } 279 | 280 | h5 { 281 | @include relative-font-size(1.125); 282 | } 283 | h6 { 284 | @include relative-font-size(1.0625); 285 | } 286 | } 287 | 288 | 289 | .social-media-list { 290 | display: table; 291 | margin: 0 auto; 292 | li { 293 | float: left; 294 | margin: 5px 10px 5px 0; 295 | &:last-of-type { margin-right: 0 } 296 | a { 297 | display: block; 298 | padding: 10px 12px; 299 | border: 1px solid $border-color-01; 300 | &:hover { border-color: $border-color-02 } 301 | } 302 | } 303 | } 304 | 305 | 306 | 307 | /** 308 | * Pagination navbar 309 | */ 310 | .pagination { 311 | margin-bottom: $spacing-unit; 312 | @extend .social-media-list; 313 | li { 314 | a, div { 315 | min-width: 41px; 316 | text-align: center; 317 | box-sizing: border-box; 318 | } 319 | div { 320 | display: block; 321 | padding: $spacing-unit * .25; 322 | border: 1px solid transparent; 323 | 324 | &.pager-edge { 325 | color: $border-color-01; 326 | border: 1px dashed; 327 | } 328 | } 329 | } 330 | } 331 | 332 | 333 | 334 | /** 335 | * Grid helpers 336 | */ 337 | @media screen and (min-width: $on-large) { 338 | .one-half { 339 | width: calc(50% - (#{$spacing-unit} / 2)); 340 | } 341 | } 342 | -------------------------------------------------------------------------------- /docs/_sass/minima/custom-styles.scss: -------------------------------------------------------------------------------- 1 | // Placeholder to allow defining custom styles that override everything else. 2 | // (Use `_sass/minima/custom-variables.scss` to override variable defaults) 3 | -------------------------------------------------------------------------------- /docs/_sass/minima/custom-variables.scss: -------------------------------------------------------------------------------- 1 | // Placeholder to allow overriding predefined variables smoothly. 2 | -------------------------------------------------------------------------------- /docs/_sass/minima/initialize.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | // Define defaults for each variable. 4 | 5 | $base-font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Segoe UI Emoji", "Segoe UI Symbol", "Apple Color Emoji", Roboto, Helvetica, Arial, sans-serif !default; 6 | $code-font-family: "Menlo", "Inconsolata", "Consolas", "Roboto Mono", "Ubuntu Mono", "Liberation Mono", "Courier New", monospace; 7 | $base-font-size: 16px !default; 8 | $base-font-weight: 400 !default; 9 | $small-font-size: $base-font-size * 0.875 !default; 10 | $base-line-height: 1.5 !default; 11 | 12 | $spacing-unit: 30px !default; 13 | 14 | $table-text-align: left !default; 15 | 16 | // Width of the content area 17 | $content-width: 800px !default; 18 | 19 | $on-palm: 600px !default; 20 | $on-laptop: 800px !default; 21 | 22 | $on-medium: $on-palm !default; 23 | $on-large: $on-laptop !default; 24 | 25 | // Use media queries like this: 26 | // @include media-query($on-palm) { 27 | // .wrapper { 28 | // padding-right: $spacing-unit / 2; 29 | // padding-left: $spacing-unit / 2; 30 | // } 31 | // } 32 | // Notice the following mixin uses max-width, in a deprecated, desktop-first 33 | // approach, whereas media queries used elsewhere now use min-width. 34 | @mixin media-query($device) { 35 | @media screen and (max-width: $device) { 36 | @content; 37 | } 38 | } 39 | 40 | @mixin relative-font-size($ratio) { 41 | font-size: #{$ratio}rem; 42 | } 43 | 44 | // Import pre-styling-overrides hook and style-partials. 45 | @import 46 | "minima/custom-variables", // Hook to override predefined variables. 47 | "minima/base", // Defines element resets. 48 | "minima/layout", // Defines structure and style based on CSS selectors. 49 | "minima/custom-styles" // Hook to override existing styles. 50 | ; 51 | -------------------------------------------------------------------------------- /docs/_sass/minima/skins/auto.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | // Default color scheme settings 4 | // These are overridden in classic.css and dark.scss 5 | 6 | $color-scheme-auto: true !default; 7 | $color-scheme-dark: false !default; 8 | 9 | 10 | // Light mode 11 | // ---------- 12 | 13 | $lm-brand-color: #828282 !default; 14 | $lm-brand-color-light: lighten($lm-brand-color, 40%) !default; 15 | $lm-brand-color-dark: darken($lm-brand-color, 25%) !default; 16 | 17 | $lm-site-title-color: $lm-brand-color-dark !default; 18 | 19 | $lm-text-color: #111111 !default; 20 | $lm-background-color: #fdfdfd !default; 21 | $lm-code-background-color: #eeeeff !default; 22 | 23 | $lm-link-base-color: #2a7ae2 !default; 24 | $lm-link-visited-color: darken($lm-link-base-color, 15%) !default; 25 | $lm-link-hover-color: $lm-text-color !default; 26 | 27 | $lm-border-color-01: $lm-brand-color-light !default; 28 | $lm-border-color-02: lighten($lm-brand-color, 35%) !default; 29 | $lm-border-color-03: $lm-brand-color-dark !default; 30 | 31 | $lm-table-text-color: lighten($lm-text-color, 18%) !default; 32 | $lm-table-zebra-color: lighten($lm-brand-color, 46%) !default; 33 | $lm-table-header-bg-color: lighten($lm-brand-color, 43%) !default; 34 | $lm-table-header-border: lighten($lm-brand-color, 37%) !default; 35 | $lm-table-border-color: $lm-border-color-01 !default; 36 | 37 | 38 | // Syntax highlighting styles should be adjusted appropriately for every "skin" 39 | // ---------------------------------------------------------------------------- 40 | 41 | @mixin lm-highlight { 42 | .highlight { 43 | .c { color: #998; font-style: italic } // Comment 44 | .err { color: #a61717; background-color: #e3d2d2 } // Error 45 | .k { font-weight: bold } // Keyword 46 | .o { font-weight: bold } // Operator 47 | .cm { color: #998; font-style: italic } // Comment.Multiline 48 | .cp { color: #999; font-weight: bold } // Comment.Preproc 49 | .c1 { color: #998; font-style: italic } // Comment.Single 50 | .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special 51 | .gd { color: #000; background-color: #fdd } // Generic.Deleted 52 | .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific 53 | .ge { font-style: italic } // Generic.Emph 54 | .gr { color: #a00 } // Generic.Error 55 | .gh { color: #999 } // Generic.Heading 56 | .gi { color: #000; background-color: #dfd } // Generic.Inserted 57 | .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific 58 | .go { color: #888 } // Generic.Output 59 | .gp { color: #555 } // Generic.Prompt 60 | .gs { font-weight: bold } // Generic.Strong 61 | .gu { color: #aaa } // Generic.Subheading 62 | .gt { color: #a00 } // Generic.Traceback 63 | .kc { font-weight: bold } // Keyword.Constant 64 | .kd { font-weight: bold } // Keyword.Declaration 65 | .kp { font-weight: bold } // Keyword.Pseudo 66 | .kr { font-weight: bold } // Keyword.Reserved 67 | .kt { color: #458; font-weight: bold } // Keyword.Type 68 | .m { color: #099 } // Literal.Number 69 | .s { color: #d14 } // Literal.String 70 | .na { color: #008080 } // Name.Attribute 71 | .nb { color: #0086B3 } // Name.Builtin 72 | .nc { color: #458; font-weight: bold } // Name.Class 73 | .no { color: #008080 } // Name.Constant 74 | .ni { color: #800080 } // Name.Entity 75 | .ne { color: #900; font-weight: bold } // Name.Exception 76 | .nf { color: #900; font-weight: bold } // Name.Function 77 | .nn { color: #555 } // Name.Namespace 78 | .nt { color: #000080 } // Name.Tag 79 | .nv { color: #008080 } // Name.Variable 80 | .ow { font-weight: bold } // Operator.Word 81 | .w { color: #bbb } // Text.Whitespace 82 | .mf { color: #099 } // Literal.Number.Float 83 | .mh { color: #099 } // Literal.Number.Hex 84 | .mi { color: #099 } // Literal.Number.Integer 85 | .mo { color: #099 } // Literal.Number.Oct 86 | .sb { color: #d14 } // Literal.String.Backtick 87 | .sc { color: #d14 } // Literal.String.Char 88 | .sd { color: #d14 } // Literal.String.Doc 89 | .s2 { color: #d14 } // Literal.String.Double 90 | .se { color: #d14 } // Literal.String.Escape 91 | .sh { color: #d14 } // Literal.String.Heredoc 92 | .si { color: #d14 } // Literal.String.Interpol 93 | .sx { color: #d14 } // Literal.String.Other 94 | .sr { color: #009926 } // Literal.String.Regex 95 | .s1 { color: #d14 } // Literal.String.Single 96 | .ss { color: #990073 } // Literal.String.Symbol 97 | .bp { color: #999 } // Name.Builtin.Pseudo 98 | .vc { color: #008080 } // Name.Variable.Class 99 | .vg { color: #008080 } // Name.Variable.Global 100 | .vi { color: #008080 } // Name.Variable.Instance 101 | .il { color: #099 } // Literal.Number.Integer.Long 102 | } 103 | } 104 | 105 | 106 | // Dark mode 107 | // --------- 108 | 109 | $dm-brand-color: #999999 !default; 110 | $dm-brand-color-light: lighten($dm-brand-color, 5%) !default; 111 | $dm-brand-color-dark: darken($dm-brand-color, 35%) !default; 112 | 113 | $dm-site-title-color: $dm-brand-color-light !default; 114 | 115 | $dm-text-color: #bbbbbb !default; 116 | $dm-background-color: #181818 !default; 117 | $dm-code-background-color: #212121 !default; 118 | 119 | $dm-link-base-color: #79b8ff !default; 120 | $dm-link-visited-color: $dm-link-base-color !default; 121 | $dm-link-hover-color: $dm-text-color !default; 122 | 123 | $dm-border-color-01: $dm-brand-color-dark !default; 124 | $dm-border-color-02: $dm-brand-color-light !default; 125 | $dm-border-color-03: $dm-brand-color !default; 126 | 127 | $dm-table-text-color: $dm-text-color !default; 128 | $dm-table-zebra-color: lighten($dm-background-color, 4%) !default; 129 | $dm-table-header-bg-color: lighten($dm-background-color, 10%) !default; 130 | $dm-table-header-border: lighten($dm-background-color, 21%) !default; 131 | $dm-table-border-color: $dm-border-color-01 !default; 132 | 133 | 134 | // Syntax highlighting styles should be adjusted appropriately for every "skin" 135 | // List of tokens: https://github.com/rouge-ruby/rouge/wiki/List-of-tokens 136 | // Some colors come from Material Theme Darker: 137 | // https://github.com/material-theme/vsc-material-theme/blob/master/scripts/generator/settings/specific/darker-hc.ts 138 | // https://github.com/material-theme/vsc-material-theme/blob/master/scripts/generator/color-set.ts 139 | // ---------------------------------------------------------------------------- 140 | 141 | @mixin dm-highlight { 142 | .highlight { 143 | .c { color: #545454; font-style: italic } // Comment 144 | .err { color: #f07178; background-color: #e3d2d2 } // Error 145 | .k { color: #89DDFF; font-weight: bold } // Keyword 146 | .o { font-weight: bold } // Operator 147 | .cm { color: #545454; font-style: italic } // Comment.Multiline 148 | .cp { color: #545454; font-weight: bold } // Comment.Preproc 149 | .c1 { color: #545454; font-style: italic } // Comment.Single 150 | .cs { color: #545454; font-weight: bold; font-style: italic } // Comment.Special 151 | .gd { color: #000; background-color: #fdd } // Generic.Deleted 152 | .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific 153 | .ge { font-style: italic } // Generic.Emph 154 | .gr { color: #f07178 } // Generic.Error 155 | .gh { color: #999 } // Generic.Heading 156 | .gi { color: #000; background-color: #dfd } // Generic.Inserted 157 | .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific 158 | .go { color: #888 } // Generic.Output 159 | .gp { color: #555 } // Generic.Prompt 160 | .gs { font-weight: bold } // Generic.Strong 161 | .gu { color: #aaa } // Generic.Subheading 162 | .gt { color: #f07178 } // Generic.Traceback 163 | .kc { font-weight: bold } // Keyword.Constant 164 | .kd { font-weight: bold } // Keyword.Declaration 165 | .kp { font-weight: bold } // Keyword.Pseudo 166 | .kr { font-weight: bold } // Keyword.Reserved 167 | .kt { color: #FFCB6B; font-weight: bold } // Keyword.Type 168 | .m { color: #F78C6C } // Literal.Number 169 | .s { color: #C3E88D } // Literal.String 170 | .na { color: #008080 } // Name.Attribute 171 | .nb { color: #EEFFFF } // Name.Builtin 172 | .nc { color: #FFCB6B; font-weight: bold } // Name.Class 173 | .no { color: #008080 } // Name.Constant 174 | .ni { color: #800080 } // Name.Entity 175 | .ne { color: #900; font-weight: bold } // Name.Exception 176 | .nf { color: #82AAFF; font-weight: bold } // Name.Function 177 | .nn { color: #555 } // Name.Namespace 178 | .nt { color: #FFCB6B } // Name.Tag 179 | .nv { color: #EEFFFF } // Name.Variable 180 | .ow { font-weight: bold } // Operator.Word 181 | .w { color: #EEFFFF } // Text.Whitespace 182 | .mf { color: #F78C6C } // Literal.Number.Float 183 | .mh { color: #F78C6C } // Literal.Number.Hex 184 | .mi { color: #F78C6C } // Literal.Number.Integer 185 | .mo { color: #F78C6C } // Literal.Number.Oct 186 | .sb { color: #C3E88D } // Literal.String.Backtick 187 | .sc { color: #C3E88D } // Literal.String.Char 188 | .sd { color: #C3E88D } // Literal.String.Doc 189 | .s2 { color: #C3E88D } // Literal.String.Double 190 | .se { color: #EEFFFF } // Literal.String.Escape 191 | .sh { color: #C3E88D } // Literal.String.Heredoc 192 | .si { color: #C3E88D } // Literal.String.Interpol 193 | .sx { color: #C3E88D } // Literal.String.Other 194 | .sr { color: #C3E88D } // Literal.String.Regex 195 | .s1 { color: #C3E88D } // Literal.String.Single 196 | .ss { color: #C3E88D } // Literal.String.Symbol 197 | .bp { color: #999 } // Name.Builtin.Pseudo 198 | .vc { color: #FFCB6B } // Name.Variable.Class 199 | .vg { color: #EEFFFF } // Name.Variable.Global 200 | .vi { color: #EEFFFF } // Name.Variable.Instance 201 | .il { color: #F78C6C } // Literal.Number.Integer.Long 202 | } 203 | } 204 | 205 | 206 | // Mode selection 207 | // -------------- 208 | 209 | 210 | // Classic skin (always light mode) 211 | // Assign outside of the if construct to establish global variable scope 212 | 213 | $brand-color: $lm-brand-color; 214 | $brand-color-light: $lm-brand-color-light; 215 | $brand-color-dark: $lm-brand-color-dark; 216 | 217 | $site-title-color: $lm-site-title-color; 218 | 219 | $text-color: $lm-text-color; 220 | $background-color: $lm-background-color; 221 | $code-background-color: $lm-code-background-color; 222 | 223 | $link-base-color: $lm-link-base-color; 224 | $link-visited-color: $lm-link-visited-color; 225 | $link-hover-color: $lm-link-hover-color; 226 | 227 | $border-color-01: $lm-border-color-01; 228 | $border-color-02: $lm-border-color-02; 229 | $border-color-03: $lm-border-color-03; 230 | 231 | $table-text-color: $lm-table-text-color; 232 | $table-zebra-color: $lm-table-zebra-color; 233 | $table-header-bg-color: $lm-table-header-bg-color; 234 | $table-header-border: $lm-table-header-border; 235 | $table-border-color: $lm-table-border-color; 236 | 237 | 238 | @if $color-scheme-auto { 239 | 240 | // Auto mode 241 | 242 | :root { 243 | --minima-brand-color: #{$lm-brand-color}; 244 | --minima-brand-color-light: #{$lm-brand-color-light}; 245 | --minima-brand-color-dark: #{$lm-brand-color-dark}; 246 | 247 | --minima-site-title-color: #{$lm-site-title-color}; 248 | 249 | --minima-text-color: #{$lm-text-color}; 250 | --minima-background-color: #{$lm-background-color}; 251 | --minima-code-background-color: #{$lm-code-background-color}; 252 | 253 | --minima-link-base-color: #{$lm-link-base-color}; 254 | --minima-link-visited-color: #{$lm-link-visited-color}; 255 | --minima-link-hover-color: #{$lm-link-hover-color}; 256 | 257 | --minima-border-color-01: #{$lm-border-color-01}; 258 | --minima-border-color-02: #{$lm-border-color-02}; 259 | --minima-border-color-03: #{$lm-border-color-03}; 260 | 261 | --minima-table-text-color: #{$lm-table-text-color}; 262 | --minima-table-zebra-color: #{$lm-table-zebra-color}; 263 | --minima-table-header-bg-color: #{$lm-table-header-bg-color}; 264 | --minima-table-header-border: #{$lm-table-header-border}; 265 | --minima-table-border-color: #{$lm-table-border-color}; 266 | } 267 | 268 | @include lm-highlight; 269 | 270 | @media (prefers-color-scheme: dark) { 271 | :root { 272 | --minima-brand-color: #{$dm-brand-color}; 273 | --minima-brand-color-light: #{$dm-brand-color-light}; 274 | --minima-brand-color-dark: #{$dm-brand-color-dark}; 275 | 276 | --minima-site-title-color: #{$dm-site-title-color}; 277 | 278 | --minima-text-color: #{$dm-text-color}; 279 | --minima-background-color: #{$dm-background-color}; 280 | --minima-code-background-color: #{$dm-code-background-color}; 281 | 282 | --minima-link-base-color: #{$dm-link-base-color}; 283 | --minima-link-visited-color: #{$dm-link-visited-color}; 284 | --minima-link-hover-color: #{$dm-link-hover-color}; 285 | 286 | --minima-border-color-01: #{$dm-border-color-01}; 287 | --minima-border-color-02: #{$dm-border-color-02}; 288 | --minima-border-color-03: #{$dm-border-color-03}; 289 | 290 | --minima-table-text-color: #{$dm-table-text-color}; 291 | --minima-table-zebra-color: #{$dm-table-zebra-color}; 292 | --minima-table-header-bg-color: #{$dm-table-header-bg-color}; 293 | --minima-table-header-border: #{$dm-table-header-border}; 294 | --minima-table-border-color: #{$dm-table-border-color}; 295 | } 296 | 297 | @include dm-highlight; 298 | } 299 | 300 | $brand-color: var(--minima-brand-color); 301 | $brand-color-light: var(--minima-brand-color-light); 302 | $brand-color-dark: var(--minima-brand-color-dark); 303 | 304 | $site-title-color: var(--minima-site-title-color); 305 | 306 | $text-color: var(--minima-text-color); 307 | $background-color: var(--minima-background-color); 308 | $code-background-color: var(--minima-code-background-color); 309 | 310 | $link-base-color: var(--minima-link-base-color); 311 | $link-visited-color: var(--minima-link-visited-color); 312 | $link-hover-color: var(--minima-link-hover-color); 313 | 314 | $border-color-01: var(--minima-border-color-01); 315 | $border-color-02: var(--minima-border-color-02); 316 | $border-color-03: var(--minima-border-color-03); 317 | 318 | $table-text-color: var(--minima-table-text-color); 319 | $table-zebra-color: var(--minima-table-zebra-color); 320 | $table-header-bg-color: var(--minima-table-header-bg-color); 321 | $table-header-border: var(--minima-table-header-border); 322 | $table-border-color: var(--minima-table-border-color); 323 | 324 | 325 | } @else if $color-scheme-dark { 326 | 327 | // Dark skin (always dark mode) 328 | 329 | $brand-color: $dm-brand-color; 330 | $brand-color-light: $dm-brand-color-light; 331 | $brand-color-dark: $dm-brand-color-dark; 332 | 333 | $site-title-color: $dm-site-title-color; 334 | 335 | $text-color: $dm-text-color; 336 | $background-color: $dm-background-color; 337 | $code-background-color: $dm-code-background-color; 338 | 339 | $link-base-color: $dm-link-base-color; 340 | $link-visited-color: $dm-link-visited-color; 341 | $link-hover-color: $dm-link-hover-color; 342 | 343 | $border-color-01: $dm-border-color-01; 344 | $border-color-02: $dm-border-color-02; 345 | $border-color-03: $dm-border-color-03; 346 | 347 | $table-text-color: $dm-table-text-color; 348 | $table-zebra-color: $dm-table-zebra-color; 349 | $table-header-bg-color: $dm-table-header-bg-color; 350 | $table-header-border: $dm-table-header-border; 351 | $table-border-color: $dm-table-border-color; 352 | 353 | @include dm-highlight; 354 | 355 | 356 | } @else { 357 | 358 | // Classic skin syntax highlighting 359 | @include lm-highlight; 360 | 361 | } 362 | -------------------------------------------------------------------------------- /docs/_sass/minima/skins/classic.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | $color-scheme-auto: false; 4 | $color-scheme-dark: false; 5 | @import "minima/skins/auto"; 6 | -------------------------------------------------------------------------------- /docs/_sass/minima/skins/dark.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | $color-scheme-auto: false; 4 | $color-scheme-dark: true; 5 | @import "minima/skins/auto"; 6 | -------------------------------------------------------------------------------- /docs/_sass/minima/skins/solarized-dark.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | $sol-is-auto: false; 4 | $sol-is-dark: true; 5 | @import "minima/skins/solarized"; 6 | -------------------------------------------------------------------------------- /docs/_sass/minima/skins/solarized-light.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | $sol-is-auto: false; 4 | @import "minima/skins/solarized"; 5 | -------------------------------------------------------------------------------- /docs/_sass/minima/skins/solarized.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | // Solarized skin 4 | // ============== 5 | // Created by Sander Voerman using the Solarized 6 | // color scheme by Ethan Schoonover . 7 | 8 | // This style sheet implements three options for the minima.skin setting: 9 | // "solarized-light" for light mode, "solarized-dark" for dark mode, and 10 | // "solarized" for light or dark mode depending on user preference. 11 | $sol-is-auto: true !default; 12 | $sol-is-dark: false !default; 13 | 14 | 15 | // Color scheme 16 | // ------------ 17 | // The inline comments show the canonical L*a*b values for each color. 18 | 19 | $sol-base03: #002b36; // 15 -12 -12 20 | $sol-base02: #073642; // 20 -12 -12 21 | $sol-base01: #586e75; // 45 -07 -07 22 | $sol-base00: #657b83; // 50 -07 -07 23 | $sol-base0: #839496; // 60 -06 -03 24 | $sol-base1: #93a1a1; // 65 -05 -02 25 | $sol-base2: #eee8d5; // 92 -00 10 26 | $sol-base3: #fdf6e3; // 97 00 10 27 | $sol-yellow: #b58900; // 60 10 65 28 | $sol-orange: #cb4b16; // 50 50 55 29 | $sol-red: #dc322f; // 50 65 45 30 | $sol-magenta: #d33682; // 50 65 -05 31 | $sol-violet: #6c71c4; // 50 15 -45 32 | $sol-blue: #268bd2; // 55 -10 -45 33 | $sol-cyan: #2aa198; // 60 -35 -05 34 | $sol-green: #859900; // 60 -20 65 35 | 36 | 37 | // Mixed colors 38 | // ------------ 39 | // While not part of the original Solarized base tones, these derived tones 40 | // are meant to replicate the visual style of the classic skin. They should 41 | // not be used in cases where sufficiently contrasting colors are needed. 42 | 43 | $sol-light-mix1: mix($sol-base1, $sol-base3); 44 | $sol-light-mix2: mix($sol-blue, $sol-base00); 45 | $sol-light-mix3: mix($sol-base2, $sol-base3); 46 | $sol-dark-mix1: mix($sol-base01, $sol-base03); 47 | $sol-dark-mix2: mix($sol-blue, $sol-base0); 48 | $sol-dark-mix3: mix($sol-base02, $sol-base03); 49 | 50 | 51 | // Mode selection 52 | // -------------- 53 | 54 | $sol-mono3: $sol-base3; 55 | $sol-mono2: $sol-base2; 56 | $sol-mono1: $sol-base1; 57 | $sol-mono00: $sol-base00; 58 | $sol-mono01: $sol-base01; 59 | $sol-mix1: $sol-light-mix1; 60 | $sol-mix2: $sol-light-mix2; 61 | $sol-mix3: $sol-light-mix3; 62 | 63 | @if $sol-is-dark { 64 | $sol-mono3: $sol-base03; 65 | $sol-mono2: $sol-base02; 66 | $sol-mono1: $sol-base01; 67 | $sol-mono00: $sol-base0; 68 | $sol-mono01: $sol-base1; 69 | $sol-mix1: $sol-dark-mix1; 70 | $sol-mix2: $sol-dark-mix2; 71 | $sol-mix3: $sol-dark-mix3; 72 | } 73 | 74 | @if $sol-is-auto { 75 | :root { 76 | --solarized-mono3: #{$sol-base3}; 77 | --solarized-mono2: #{$sol-base2}; 78 | --solarized-mono1: #{$sol-base1}; 79 | --solarized-mono00: #{$sol-base00}; 80 | --solarized-mono01: #{$sol-base01}; 81 | --solarized-mix1: #{$sol-light-mix1}; 82 | --solarized-mix2: #{$sol-light-mix2}; 83 | --solarized-mix3: #{$sol-light-mix3}; 84 | } 85 | 86 | @media (prefers-color-scheme: dark) { 87 | :root { 88 | --solarized-mono3: #{$sol-base03}; 89 | --solarized-mono2: #{$sol-base02}; 90 | --solarized-mono1: #{$sol-base01}; 91 | --solarized-mono00: #{$sol-base0}; 92 | --solarized-mono01: #{$sol-base1}; 93 | --solarized-mix1: #{$sol-dark-mix1}; 94 | --solarized-mix2: #{$sol-dark-mix2}; 95 | --solarized-mix3: #{$sol-dark-mix3}; 96 | } 97 | } 98 | 99 | $sol-mono3: var(--solarized-mono3); 100 | $sol-mono2: var(--solarized-mono2); 101 | $sol-mono1: var(--solarized-mono1); 102 | $sol-mono00: var(--solarized-mono00); 103 | $sol-mono01: var(--solarized-mono01); 104 | $sol-mix1: var(--solarized-mix1); 105 | $sol-mix2: var(--solarized-mix2); 106 | $sol-mix3: var(--solarized-mix3); 107 | } 108 | 109 | 110 | // Minima color variables 111 | // ---------------------- 112 | 113 | $brand-color: $sol-mono1 !default; 114 | $brand-color-light: $sol-mix1 !default; 115 | $brand-color-dark: $sol-mono00 !default; 116 | 117 | $site-title-color: $sol-mono00 !default; 118 | 119 | $text-color: $sol-mono01 !default; 120 | $background-color: $sol-mono3 !default; 121 | $code-background-color: $sol-mono2 !default; 122 | 123 | $link-base-color: $sol-blue !default; 124 | $link-visited-color: $sol-mix2 !default; 125 | $link-hover-color: $sol-mono00 !default; 126 | 127 | $border-color-01: $brand-color-light !default; 128 | $border-color-02: $sol-mono1 !default; 129 | $border-color-03: $sol-mono00 !default; 130 | 131 | $table-text-color: $sol-mono00 !default; 132 | $table-zebra-color: $sol-mix3 !default; 133 | $table-header-bg-color: $sol-mono2 !default; 134 | $table-header-border: $sol-mono1 !default; 135 | $table-border-color: $sol-mono1 !default; 136 | 137 | 138 | // Syntax highlighting styles 139 | // -------------------------- 140 | 141 | .highlight { 142 | .c { color: $sol-mono1; font-style: italic } // Comment 143 | .err { color: $sol-red } // Error 144 | .k { color: $sol-mono01; font-weight: bold } // Keyword 145 | .o { color: $sol-mono01; font-weight: bold } // Operator 146 | .cm { color: $sol-mono1; font-style: italic } // Comment.Multiline 147 | .cp { color: $sol-mono1; font-weight: bold } // Comment.Preproc 148 | .c1 { color: $sol-mono1; font-style: italic } // Comment.Single 149 | .cs { color: $sol-mono1; font-weight: bold; font-style: italic } // Comment.Special 150 | .gd { color: $sol-red } // Generic.Deleted 151 | .gd .x { color: $sol-red } // Generic.Deleted.Specific 152 | .ge { color: $sol-mono00; font-style: italic } // Generic.Emph 153 | .gr { color: $sol-red } // Generic.Error 154 | .gh { color: $sol-mono1 } // Generic.Heading 155 | .gi { color: $sol-green } // Generic.Inserted 156 | .gi .x { color: $sol-green } // Generic.Inserted.Specific 157 | .go { color: $sol-mono00 } // Generic.Output 158 | .gp { color: $sol-mono00 } // Generic.Prompt 159 | .gs { color: $sol-mono01; font-weight: bold } // Generic.Strong 160 | .gu { color: $sol-mono1 } // Generic.Subheading 161 | .gt { color: $sol-red } // Generic.Traceback 162 | .kc { color: $sol-mono01; font-weight: bold } // Keyword.Constant 163 | .kd { color: $sol-mono01; font-weight: bold } // Keyword.Declaration 164 | .kp { color: $sol-mono01; font-weight: bold } // Keyword.Pseudo 165 | .kr { color: $sol-mono01; font-weight: bold } // Keyword.Reserved 166 | .kt { color: $sol-violet; font-weight: bold } // Keyword.Type 167 | .m { color: $sol-cyan } // Literal.Number 168 | .s { color: $sol-magenta } // Literal.String 169 | .na { color: $sol-cyan } // Name.Attribute 170 | .nb { color: $sol-blue } // Name.Builtin 171 | .nc { color: $sol-violet; font-weight: bold } // Name.Class 172 | .no { color: $sol-cyan } // Name.Constant 173 | .ni { color: $sol-violet } // Name.Entity 174 | .ne { color: $sol-violet; font-weight: bold } // Name.Exception 175 | .nf { color: $sol-blue; font-weight: bold } // Name.Function 176 | .nn { color: $sol-mono00 } // Name.Namespace 177 | .nt { color: $sol-blue } // Name.Tag 178 | .nv { color: $sol-cyan } // Name.Variable 179 | .ow { color: $sol-mono01; font-weight: bold } // Operator.Word 180 | .w { color: $sol-mono1 } // Text.Whitespace 181 | .mf { color: $sol-cyan } // Literal.Number.Float 182 | .mh { color: $sol-cyan } // Literal.Number.Hex 183 | .mi { color: $sol-cyan } // Literal.Number.Integer 184 | .mo { color: $sol-cyan } // Literal.Number.Oct 185 | .sb { color: $sol-magenta } // Literal.String.Backtick 186 | .sc { color: $sol-magenta } // Literal.String.Char 187 | .sd { color: $sol-magenta } // Literal.String.Doc 188 | .s2 { color: $sol-magenta } // Literal.String.Double 189 | .se { color: $sol-magenta } // Literal.String.Escape 190 | .sh { color: $sol-magenta } // Literal.String.Heredoc 191 | .si { color: $sol-magenta } // Literal.String.Interpol 192 | .sx { color: $sol-magenta } // Literal.String.Other 193 | .sr { color: $sol-green } // Literal.String.Regex 194 | .s1 { color: $sol-magenta } // Literal.String.Single 195 | .ss { color: $sol-magenta } // Literal.String.Symbol 196 | .bp { color: $sol-mono1 } // Name.Builtin.Pseudo 197 | .vc { color: $sol-cyan } // Name.Variable.Class 198 | .vg { color: $sol-cyan } // Name.Variable.Global 199 | .vi { color: $sol-cyan } // Name.Variable.Instance 200 | .il { color: $sol-cyan } // Literal.Number.Integer.Long 201 | } 202 | -------------------------------------------------------------------------------- /docs/assets/DejaVuSansCircle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/docs/assets/DejaVuSansCircle.png -------------------------------------------------------------------------------- /docs/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | # Only the main Sass file needs front matter (the dashes are enough) 3 | --- 4 | 5 | @import 6 | "minima/skins/{{ site.minima.skin | default: 'classic' }}", 7 | "minima/initialize"; 8 | -------------------------------------------------------------------------------- /docs/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/docs/assets/favicon.ico -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | --- 4 | 5 | ![GitHub](https://img.shields.io/github/license/charoitel/lambda-layer-canvas-nodejs)  ![Watch on GitHub](https://img.shields.io/github/watchers/charoitel/lambda-node-canvas.svg?style=social)  ![Fork on GitHub](https://img.shields.io/github/forks/charoitel/lambda-node-canvas.svg?style=social)  ![Star on GitHub](https://img.shields.io/github/stars/charoitel/lambda-node-canvas.svg?style=social) 6 | 7 | Canvas Layer for AWS Lambda is published and available on [AWS Serverless Application Repository](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:990551184979:applications~lambda-layer-canvas-nodejs), and GitHub at [charoitel/lambda-layer-canvas-nodejs](https://github.com/charoitel/lambda-layer-canvas-nodejs). The layer aims to provide a Cairo backed Mozilla Web Canvas API implementation layer for AWS Lambda, powered by [node-canvas](https://github.com/Automattic/node-canvas). 8 | 9 | ## About node-canvas 10 | 11 | [node-canvas](https://github.com/Automattic/node-canvas) is a Cairo backed Canvas implementation for Node.js. It implements the [Mozilla Web Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) as closely as possible. For the latest API compliance, you may check [Compatibility Status](https://github.com/Automattic/node-canvas/wiki/Compatibility-Status). 12 | 13 | ## How this layer is built? 14 | 15 | The layer is built from source of node-canvas npm package on [amazonlinux](https://hub.docker.com/_/amazonlinux) dev container instance, with following native dependencies installed. You may check the build layer script, ``` build-layer.sh ```, which is available in repository, for details. 16 | 17 | ```bash 18 | gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel librsvg2-devel pango-devel bzip2-devel jq python3 19 | ``` 20 | 21 | Since AWS Lambda is a secure and isolated runtime and execution environment, the layer aims to target AWS Lambda compatible and native build. As there are canvas libraries and frameworks relying on node-canvas running on Node.js runtime, this layer may also try to include and support those libraries and frameworks. Currently, following libraries and frameworks are included when building and packaging the layer: 22 | 23 | - [Chart.js](#chartjs-support) 24 | - [Fabric.js](#fabricjs-support) 25 | - [Konva](#konva-support) 26 | 27 | ### Chart.js support 28 | 29 | [Chart.js](https://github.com/chartjs/chart.js) provides a set of frequently used chart types, plugins, and customization options. In addition to a reasonable set of built-in chart types, there are also community-maintained chart types. 30 | 31 | ### Fabric.js support 32 | 33 | [Fabric.js](https://github.com/fabricjs/fabric.js) provides a missing and interactive object model for canvas, as well as an SVG parser, layer of interactivity, and a whole suite of other indispensable tools. 34 | 35 | ### Konva support 36 | 37 | [Konva](https://github.com/konvajs/konva) enables high performance animations, transitions, node nesting, layering, filtering, caching, event handling for desktop and mobile applications, and much more. 38 | -------------------------------------------------------------------------------- /docs/minima.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Gem::Specification.new do |spec| 4 | spec.name = "minima" 5 | spec.version = "3.0.0.dev" 6 | spec.authors = ["Joel Glovier"] 7 | spec.email = ["jglovier@github.com"] 8 | 9 | spec.summary = "A beautiful, minimal theme for Jekyll." 10 | spec.homepage = "https://github.com/jekyll/minima" 11 | spec.license = "MIT" 12 | 13 | spec.metadata["plugin_type"] = "theme" 14 | 15 | spec.files = `git ls-files -z`.split("\x0").select do |f| 16 | f.match(%r!^(assets|_(includes|layouts|sass)/|(LICENSE|README)((\.(txt|md|markdown)|$)))!i) 17 | end 18 | 19 | spec.add_runtime_dependency "jekyll", ">= 3.5", "< 5.0" 20 | spec.add_runtime_dependency "jekyll-feed", "~> 0.9" 21 | spec.add_runtime_dependency "jekyll-seo-tag", "~> 2.1" 22 | 23 | spec.add_development_dependency "bundler" 24 | end 25 | -------------------------------------------------------------------------------- /docs/script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | gem install bundler 6 | bundle install 7 | -------------------------------------------------------------------------------- /docs/script/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | echo "Building the example site..." 6 | bundle exec jekyll build 7 | -------------------------------------------------------------------------------- /docs/script/cibuild: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | script/build 6 | 7 | if test -e "./_site/index.html";then 8 | echo "It builds!" 9 | rm -Rf _site 10 | else 11 | echo "Huh. That's odd. The example site doesn't seem to build." 12 | exit 1 13 | fi 14 | 15 | gem build minima.gemspec 16 | -------------------------------------------------------------------------------- /docs/script/server: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | bundle exec jekyll serve 4 | -------------------------------------------------------------------------------- /lib/libX11.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libX11.so.6 -------------------------------------------------------------------------------- /lib/libXau.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libXau.so.6 -------------------------------------------------------------------------------- /lib/libXext.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libXext.so.6 -------------------------------------------------------------------------------- /lib/libXrender.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libXrender.so.1 -------------------------------------------------------------------------------- /lib/libblkid.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libblkid.so.1 -------------------------------------------------------------------------------- /lib/libbrotlicommon.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libbrotlicommon.so.1 -------------------------------------------------------------------------------- /lib/libbrotlidec.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libbrotlidec.so.1 -------------------------------------------------------------------------------- /lib/libbz2.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libbz2.so.1 -------------------------------------------------------------------------------- /lib/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libc.so.6 -------------------------------------------------------------------------------- /lib/libcairo-gobject.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libcairo-gobject.so.2 -------------------------------------------------------------------------------- /lib/libcairo.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libcairo.so.2 -------------------------------------------------------------------------------- /lib/libdatrie.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libdatrie.so.1 -------------------------------------------------------------------------------- /lib/libffi.so.8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libffi.so.8 -------------------------------------------------------------------------------- /lib/libfontconfig.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libfontconfig.so.1 -------------------------------------------------------------------------------- /lib/libfreetype.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libfreetype.so.6 -------------------------------------------------------------------------------- /lib/libfribidi.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libfribidi.so.0 -------------------------------------------------------------------------------- /lib/libgcc_s.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libgcc_s.so.1 -------------------------------------------------------------------------------- /lib/libgdk_pixbuf-2.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libgdk_pixbuf-2.0.so.0 -------------------------------------------------------------------------------- /lib/libgif.so.7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libgif.so.7 -------------------------------------------------------------------------------- /lib/libgio-2.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libgio-2.0.so.0 -------------------------------------------------------------------------------- /lib/libglib-2.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libglib-2.0.so.0 -------------------------------------------------------------------------------- /lib/libgmodule-2.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libgmodule-2.0.so.0 -------------------------------------------------------------------------------- /lib/libgobject-2.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libgobject-2.0.so.0 -------------------------------------------------------------------------------- /lib/libgraphite2.so.3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libgraphite2.so.3 -------------------------------------------------------------------------------- /lib/libharfbuzz.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libharfbuzz.so.0 -------------------------------------------------------------------------------- /lib/libjpeg.so.62: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libjpeg.so.62 -------------------------------------------------------------------------------- /lib/liblzma.so.5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/liblzma.so.5 -------------------------------------------------------------------------------- /lib/libm.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libm.so.6 -------------------------------------------------------------------------------- /lib/libmount.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libmount.so.1 -------------------------------------------------------------------------------- /lib/libpango-1.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libpango-1.0.so.0 -------------------------------------------------------------------------------- /lib/libpangocairo-1.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libpangocairo-1.0.so.0 -------------------------------------------------------------------------------- /lib/libpangoft2-1.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libpangoft2-1.0.so.0 -------------------------------------------------------------------------------- /lib/libpcre2-8.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libpcre2-8.so.0 -------------------------------------------------------------------------------- /lib/libpixman-1.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libpixman-1.so.0 -------------------------------------------------------------------------------- /lib/libpng16.so.16: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libpng16.so.16 -------------------------------------------------------------------------------- /lib/librsvg-2.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/librsvg-2.so.2 -------------------------------------------------------------------------------- /lib/libselinux.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libselinux.so.1 -------------------------------------------------------------------------------- /lib/libstdc++.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libstdc++.so.6 -------------------------------------------------------------------------------- /lib/libthai.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libthai.so.0 -------------------------------------------------------------------------------- /lib/libxcb-render.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libxcb-render.so.0 -------------------------------------------------------------------------------- /lib/libxcb-shm.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libxcb-shm.so.0 -------------------------------------------------------------------------------- /lib/libxcb.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libxcb.so.1 -------------------------------------------------------------------------------- /lib/libxml2.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libxml2.so.2 -------------------------------------------------------------------------------- /lib/libz.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charoitel/lambda-layer-canvas-nodejs/3a2157addadf0dbd46cf83ca9a36f4aa96c51ac1/lib/libz.so.1 -------------------------------------------------------------------------------- /nodejs/test/canvas-font.js: -------------------------------------------------------------------------------- 1 | let { registerFont, createCanvas } = require('canvas'); 2 | var assert = require('assert'); 3 | 4 | describe('Font', function() { 5 | describe('#registerFont', function() { 6 | it('should register defined Font by name', function() { 7 | registerFont('/usr/share/fonts/dejavu-sans-fonts/DejaVuSans.ttf', { family: 'DejaVu Sans' }); 8 | }); 9 | }), 10 | describe('#fillText', function() { 11 | it('should write defined Text in canvas', function() { 12 | registerFont('/usr/share/fonts/dejavu-sans-fonts/DejaVuSans-Bold.ttf', { family: 'DejaVu Sans Bold' }); 13 | let canvas = createCanvas(300, 300); 14 | let ctx1 = canvas.getContext('2d'); 15 | ctx1.font = '30px'; 16 | ctx1.fillText('Default', 5, 25); 17 | let ctx2 = canvas.getContext('2d'); 18 | ctx2.font = '30px "DejaVu Sans"'; 19 | ctx2.fillText('DejaVu Sans', 5, 65); 20 | let ctx3 = canvas.getContext('2d'); 21 | ctx3.font = '30px "DejaVu Sans Bold"'; 22 | ctx3.fillText('DejaVu Sans Bold', 5, 95); 23 | // console.log(canvas.toDataURL()); 24 | assert.strictEqual(canvas.toDataURL(), 'data:image/png;base64,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'); 25 | }) 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /nodejs/test/canvas-svg.js: -------------------------------------------------------------------------------- 1 | let { registerFont, createCanvas } = require('canvas'); 2 | var assert = require('assert'); 3 | 4 | describe('SVG', function () { 5 | describe('#fillTextInSVG', function () { 6 | it('should write defined Text in canvas', function () { 7 | registerFont('/usr/share/fonts/dejavu-sans-fonts/DejaVuSans-Bold.ttf', { family: 'DejaVu Sans Bold' }); 8 | let canvas = createCanvas(300, 300, 'svg'); 9 | let ctx1 = canvas.getContext('2d'); 10 | ctx1.font = '30px'; 11 | ctx1.fillText('Default', 5, 25); 12 | let ctx2 = canvas.getContext('2d'); 13 | ctx2.font = '30px "DejaVu Sans"'; 14 | ctx2.fillText('DejaVu Sans', 5, 65); 15 | let ctx3 = canvas.getContext('2d'); 16 | ctx3.font = '30px "DejaVu Sans Bold"'; 17 | ctx3.fillText('DejaVu Sans Bold', 5, 95); 18 | // console.log(canvas.toDataURL()); 19 | assert.strictEqual(canvas.toDataURL(), "data:image/png;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiPgo8cGF0aCBmaWxsLXJ1bGU9Im5vbnplcm8iIGZpbGw9InJnYigwJSwgMCUsIDAlKSIgZmlsbC1vcGFjaXR5PSIxIiBkPSJNIDEwLjkwNjI1IDUuNTYyNSBMIDEwLjkwNjI1IDIyLjU2MjUgTCAxNC40ODQzNzUgMjIuNTYyNSBDIDE3LjQ5MjE4OCAyMi41NjI1IDE5LjY5NTMxMiAyMS44ODI4MTIgMjEuMDkzNzUgMjAuNTE1NjI1IEMgMjIuNSAxOS4xNTIzNDQgMjMuMjAzMTI1IDE2Ljk5NjA5NCAyMy4yMDMxMjUgMTQuMDQ2ODc1IEMgMjMuMjAzMTI1IDExLjEwOTM3NSAyMi41IDguOTY0ODQ0IDIxLjA5Mzc1IDcuNjA5Mzc1IEMgMTkuNjk1MzEyIDYuMjQ2MDk0IDE3LjQ5MjE4OCA1LjU2MjUgMTQuNDg0Mzc1IDUuNTYyNSBaIE0gNy45Mzc1IDMuMTI1IEwgMTQuMDMxMjUgMy4xMjUgQyAxOC4yNTc4MTIgMy4xMjUgMjEuMzYzMjgxIDQuMDExNzE5IDIzLjM0Mzc1IDUuNzgxMjUgQyAyNS4zMzIwMzEgNy41NDI5NjkgMjYuMzI4MTI1IDEwLjI5Njg3NSAyNi4zMjgxMjUgMTQuMDQ2ODc1IEMgMjYuMzI4MTI1IDE3LjgyMDMxMiAyNS4zMzIwMzEgMjAuNTg5ODQ0IDIzLjM0Mzc1IDIyLjM1OTM3NSBDIDIxLjM1MTU2MiAyNC4xMjEwOTQgMTguMjUgMjUgMTQuMDMxMjUgMjUgTCA3LjkzNzUgMjUgWiBNIDQ0Ljk2MDkzOCAxNi4xMjUgTCA0NC45NjA5MzggMTcuNDM3NSBMIDMyLjU3MDMxMiAxNy40Mzc1IEMgMzIuNjgzNTk0IDE5LjI5Mjk2OSAzMy4yNDIxODggMjAuNzEwOTM4IDM0LjI0MjE4OCAyMS42ODc1IEMgMzUuMjQyMTg4IDIyLjY1NjI1IDM2LjYzNjcxOSAyMy4xNDA2MjUgMzguNDI5Njg4IDIzLjE0MDYyNSBDIDM5LjQ2MDkzOCAyMy4xNDA2MjUgNDAuNDYwOTM4IDIzLjAxNTYyNSA0MS40Mjk2ODggMjIuNzY1NjI1IEMgNDIuNDA2MjUgMjIuNTA3ODEyIDQzLjM3NSAyMi4xMjEwOTQgNDQuMzM1OTM4IDIxLjYwOTM3NSBMIDQ0LjMzNTkzOCAyNC4xNzE4NzUgQyA0My4zNjcxODggMjQuNTc4MTI1IDQyLjM3MTA5NCAyNC44ODY3MTkgNDEuMzUxNTYyIDI1LjA5Mzc1IEMgNDAuMzM5ODQ0IDI1LjMxMjUgMzkuMzEyNSAyNS40MjE4NzUgMzguMjczNDM4IDI1LjQyMTg3NSBDIDM1LjY0ODQzOCAyNS40MjE4NzUgMzMuNTcwMzEyIDI0LjY2NDA2MiAzMi4wMzkwNjIgMjMuMTQwNjI1IEMgMzAuNTE1NjI1IDIxLjYyMTA5NCAyOS43NTc4MTIgMTkuNTU4NTk0IDI5Ljc1NzgxMiAxNi45NTMxMjUgQyAyOS43NTc4MTIgMTQuMjY1NjI1IDMwLjQ4MDQ2OSAxMi4xMzY3MTkgMzEuOTI5Njg4IDEwLjU2MjUgQyAzMy4zNzUgOC45OTIxODggMzUuMzM1OTM4IDguMjAzMTI1IDM3LjgwNDY4OCA4LjIwMzEyNSBDIDQwLjAxMTcxOSA4LjIwMzEyNSA0MS43NTc4MTIgOC45MTQwNjIgNDMuMDM5MDYyIDEwLjMyODEyNSBDIDQ0LjMyMDMxMiAxMS43NDYwOTQgNDQuOTYwOTM4IDEzLjY3OTY4OCA0NC45NjA5MzggMTYuMTI1IFogTSA0Mi4yNzM0MzggMTUuMzI4MTI1IEMgNDIuMjUgMTMuODU5Mzc1IDQxLjgzNTkzOCAxMi42ODc1IDQxLjAyMzQzOCAxMS44MTI1IEMgNDAuMjE4NzUgMTAuOTI5Njg4IDM5LjE1NjI1IDEwLjQ4NDM3NSAzNy44MzU5MzggMTAuNDg0Mzc1IEMgMzYuMzI0MjE5IDEwLjQ4NDM3NSAzNS4xMTcxODggMTAuOTE0MDYyIDM0LjIxMDkzOCAxMS43NjU2MjUgQyAzMy4zMTI1IDEyLjYwOTM3NSAzMi43OTY4NzUgMTMuODA0Njg4IDMyLjY2NDA2MiAxNS4zNDM3NSBaIE0gNTcuNjk5MjE5IDIuMjAzMTI1IEwgNTcuNjk5MjE5IDQuNDUzMTI1IEwgNTUuMTIxMDk0IDQuNDUzMTI1IEMgNTQuMTUyMzQ0IDQuNDUzMTI1IDUzLjQ4MDQ2OSA0LjY1MjM0NCA1My4xMDU0NjkgNS4wNDY4NzUgQyA1Mi43MzA0NjkgNS40MzM1OTQgNTIuNTQyOTY5IDYuMTMyODEyIDUyLjU0Mjk2OSA3LjE0MDYyNSBMIDUyLjU0Mjk2OSA4LjU5Mzc1IEwgNTYuOTgwNDY5IDguNTkzNzUgTCA1Ni45ODA0NjkgMTAuNjg3NSBMIDUyLjU0Mjk2OSAxMC42ODc1IEwgNTIuNTQyOTY5IDI1IEwgNDkuODI0MjE5IDI1IEwgNDkuODI0MjE5IDEwLjY4NzUgTCA0Ny4yNDYwOTQgMTAuNjg3NSBMIDQ3LjI0NjA5NCA4LjU5Mzc1IEwgNDkuODI0MjE5IDguNTkzNzUgTCA0OS44MjQyMTkgNy40NTMxMjUgQyA0OS44MjQyMTkgNS42MzI4MTIgNTAuMjQ2MDk0IDQuMzA0Njg4IDUxLjA4OTg0NCAzLjQ2ODc1IEMgNTEuOTQxNDA2IDIuNjI1IDUzLjI5Mjk2OSAyLjIwMzEyNSA1NS4xMzY3MTkgMi4yMDMxMjUgWiBNIDY3LjM5ODQzOCAxNi43NSBDIDY1LjIxODc1IDE2Ljc1IDYzLjcxMDkzOCAxNyA2Mi44NjcxODggMTcuNSBDIDYyLjAzMTI1IDE4IDYxLjYxNzE4OCAxOC44NTE1NjIgNjEuNjE3MTg4IDIwLjA0Njg3NSBDIDYxLjYxNzE4OCAyMS4wMDc4MTIgNjEuOTI5Njg4IDIxLjc2NTYyNSA2Mi41NTQ2ODggMjIuMzI4MTI1IEMgNjMuMTg3NSAyMi44OTA2MjUgNjQuMDQ2ODc1IDIzLjE3MTg3NSA2NS4xMzI4MTIgMjMuMTcxODc1IEMgNjYuNjIxMDk0IDIzLjE3MTg3NSA2Ny44MjAzMTIgMjIuNjQwNjI1IDY4LjcyNjU2MiAyMS41NzgxMjUgQyA2OS42MzI4MTIgMjAuNTE1NjI1IDcwLjA4NTkzOCAxOS4xMDkzNzUgNzAuMDg1OTM4IDE3LjM1OTM3NSBMIDcwLjA4NTkzOCAxNi43NSBaIE0gNzIuNzczNDM4IDE1LjY0MDYyNSBMIDcyLjc3MzQzOCAyNSBMIDcwLjA4NTkzOCAyNSBMIDcwLjA4NTkzOCAyMi41MTU2MjUgQyA2OS40Njg3NSAyMy41MDc4MTIgNjguNjk5MjE5IDI0LjI0MjE4OCA2Ny43NzM0MzggMjQuNzE4NzUgQyA2Ni44NTU0NjkgMjUuMTg3NSA2NS43MzQzNzUgMjUuNDIxODc1IDY0LjQxNDA2MiAyNS40MjE4NzUgQyA2Mi43MzQzNzUgMjUuNDIxODc1IDYxLjM5ODQzOCAyNC45NTMxMjUgNjAuMzk4NDM4IDI0LjAxNTYyNSBDIDU5LjQwNjI1IDIzLjA3MDMxMiA1OC45MTQwNjIgMjEuODA0Njg4IDU4LjkxNDA2MiAyMC4yMTg3NSBDIDU4LjkxNDA2MiAxOC4zNzUgNTkuNTMxMjUgMTYuOTg0Mzc1IDYwLjc3MzQzOCAxNi4wNDY4NzUgQyA2Mi4wMTE3MTkgMTUuMTA5Mzc1IDYzLjg1NTQ2OSAxNC42NDA2MjUgNjYuMzA0Njg4IDE0LjY0MDYyNSBMIDcwLjA4NTkzOCAxNC42NDA2MjUgTCA3MC4wODU5MzggMTQuMzc1IEMgNzAuMDg1OTM4IDEzLjEzNjcxOSA2OS42NzE4NzUgMTIuMTc5Njg4IDY4Ljg1MTU2MiAxMS41IEMgNjguMDM5MDYyIDEwLjgyNDIxOSA2Ni44OTg0MzggMTAuNDg0Mzc1IDY1LjQyOTY4OCAxMC40ODQzNzUgQyA2NC40OTIxODggMTAuNDg0Mzc1IDYzLjU3NDIxOSAxMC42MDE1NjIgNjIuNjc5Njg4IDEwLjgyODEyNSBDIDYxLjc5Mjk2OSAxMS4wNDY4NzUgNjAuOTM3NSAxMS4zODI4MTIgNjAuMTE3MTg4IDExLjgyODEyNSBMIDYwLjExNzE4OCA5LjM0Mzc1IEMgNjEuMTA1NDY5IDguOTYwOTM4IDYyLjA2MjUgOC42NzE4NzUgNjIuOTkyMTg4IDguNDg0Mzc1IEMgNjMuOTE3OTY5IDguMjk2ODc1IDY0LjgyMDMxMiA4LjIwMzEyNSA2NS42OTUzMTIgOC4yMDMxMjUgQyA2OC4wNzAzMTIgOC4yMDMxMjUgNjkuODM5ODQ0IDguODIwMzEyIDcxLjAwNzgxMiAxMC4wNDY4NzUgQyA3Mi4xODM1OTQgMTEuMjc3MzQ0IDcyLjc3MzQzOCAxMy4xNDA2MjUgNzIuNzczNDM4IDE1LjY0MDYyNSBaIE0gNzguMDUwNzgxIDE4LjUzMTI1IEwgNzguMDUwNzgxIDguNTkzNzUgTCA4MC43NTM5MDYgOC41OTM3NSBMIDgwLjc1MzkwNiAxOC40MjE4NzUgQyA4MC43NTM5MDYgMTkuOTc2NTYyIDgxLjA1NDY4OCAyMS4xNDA2MjUgODEuNjYwMTU2IDIxLjkyMTg3NSBDIDgyLjI2MTcxOSAyMi42OTUzMTIgODMuMTY3OTY5IDIzLjA3ODEyNSA4NC4zNzg5MDYgMjMuMDc4MTI1IEMgODUuODM1OTM4IDIzLjA3ODEyNSA4Ni45ODgyODEgMjIuNjE3MTg4IDg3LjgzMjAzMSAyMS42ODc1IEMgODguNjc1NzgxIDIwLjc2MTcxOSA4OS4wOTc2NTYgMTkuNDk2MDk0IDg5LjA5NzY1NiAxNy44OTA2MjUgTCA4OS4wOTc2NTYgOC41OTM3NSBMIDkxLjgwMDc4MSA4LjU5Mzc1IEwgOTEuODAwNzgxIDI1IEwgODkuMDk3NjU2IDI1IEwgODkuMDk3NjU2IDIyLjQ4NDM3NSBDIDg4LjQ0MTQwNiAyMy40NzY1NjIgODcuNjc5Njg4IDI0LjIxNDg0NCA4Ni44MTY0MDYgMjQuNzAzMTI1IEMgODUuOTQ5MjE5IDI1LjE3OTY4OCA4NC45NDkyMTkgMjUuNDIxODc1IDgzLjgxNjQwNiAyNS40MjE4NzUgQyA4MS45Mjk2ODggMjUuNDIxODc1IDgwLjQ5NjA5NCAyNC44Mzk4NDQgNzkuNTE5NTMxIDIzLjY3MTg3NSBDIDc4LjUzOTA2MiAyMi40OTYwOTQgNzguMDUwNzgxIDIwLjc4MTI1IDc4LjA1MDc4MSAxOC41MzEyNSBaIE0gODQuODMyMDMxIDguMjAzMTI1IFogTSA5Ny4zNDM3NSAyLjIwMzEyNSBMIDEwMC4wMzEyNSAyLjIwMzEyNSBMIDEwMC4wMzEyNSAyNSBMIDk3LjM0Mzc1IDI1IFogTSAxMDguMzUxNTYyIDMuOTM3NSBMIDEwOC4zNTE1NjIgOC41OTM3NSBMIDExMy44OTg0MzggOC41OTM3NSBMIDExMy44OTg0MzggMTAuNjg3NSBMIDEwOC4zNTE1NjIgMTAuNjg3NSBMIDEwOC4zNTE1NjIgMTkuNTkzNzUgQyAxMDguMzUxNTYyIDIwLjkyOTY4OCAxMDguNTMxMjUgMjEuNzg5MDYyIDEwOC44OTg0MzggMjIuMTcxODc1IEMgMTA5LjI2MTcxOSAyMi41NTg1OTQgMTEwLjAwNzgxMiAyMi43NSAxMTEuMTMyODEyIDIyLjc1IEwgMTEzLjg5ODQzOCAyMi43NSBMIDExMy44OTg0MzggMjUgTCAxMTEuMTMyODEyIDI1IEMgMTA5LjA0Njg3NSAyNSAxMDcuNjA5Mzc1IDI0LjYxNzE4OCAxMDYuODIwMzEyIDIzLjg0Mzc1IEMgMTA2LjAyNzM0NCAyMy4wNjI1IDEwNS42MzI4MTIgMjEuNjQ4NDM4IDEwNS42MzI4MTIgMTkuNTkzNzUgTCAxMDUuNjMyODEyIDEwLjY4NzUgTCAxMDMuNjY0MDYyIDEwLjY4NzUgTCAxMDMuNjY0MDYyIDguNTkzNzUgTCAxMDUuNjMyODEyIDguNTkzNzUgTCAxMDUuNjMyODEyIDMuOTM3NSBaIE0gNSAtMi44NDc2NTYgIi8+CjxwYXRoIGZpbGwtcnVsZT0ibm9uemVybyIgZmlsbD0icmdiKDAlLCAwJSwgMCUpIiBmaWxsLW9wYWNpdHk9IjEiIGQ9Ik0gMTAuOTA2MjUgNDUuNTYyNSBMIDEwLjkwNjI1IDYyLjU2MjUgTCAxNC40ODQzNzUgNjIuNTYyNSBDIDE3LjQ5MjE4OCA2Mi41NjI1IDE5LjY5NTMxMiA2MS44ODI4MTIgMjEuMDkzNzUgNjAuNTE1NjI1IEMgMjIuNSA1OS4xNTIzNDQgMjMuMjAzMTI1IDU2Ljk5NjA5NCAyMy4yMDMxMjUgNTQuMDQ2ODc1IEMgMjMuMjAzMTI1IDUxLjEwOTM3NSAyMi41IDQ4Ljk2NDg0NCAyMS4wOTM3NSA0Ny42MDkzNzUgQyAxOS42OTUzMTIgNDYuMjQ2MDk0IDE3LjQ5MjE4OCA0NS41NjI1IDE0LjQ4NDM3NSA0NS41NjI1IFogTSA3LjkzNzUgNDMuMTI1IEwgMTQuMDMxMjUgNDMuMTI1IEMgMTguMjU3ODEyIDQzLjEyNSAyMS4zNjMyODEgNDQuMDExNzE5IDIzLjM0Mzc1IDQ1Ljc4MTI1IEMgMjUuMzMyMDMxIDQ3LjU0Mjk2OSAyNi4zMjgxMjUgNTAuMjk2ODc1IDI2LjMyODEyNSA1NC4wNDY4NzUgQyAyNi4zMjgxMjUgNTcuODIwMzEyIDI1LjMzMjAzMSA2MC41ODk4NDQgMjMuMzQzNzUgNjIuMzU5Mzc1IEMgMjEuMzUxNTYyIDY0LjEyMTA5NCAxOC4yNSA2NSAxNC4wMzEyNSA2NSBMIDcuOTM3NSA2NSBaIE0gNDQuOTYwOTM4IDU2LjEyNSBMIDQ0Ljk2MDkzOCA1Ny40Mzc1IEwgMzIuNTcwMzEyIDU3LjQzNzUgQyAzMi42ODM1OTQgNTkuMjkyOTY5IDMzLjI0MjE4OCA2MC43MTA5MzggMzQuMjQyMTg4IDYxLjY4NzUgQyAzNS4yNDIxODggNjIuNjU2MjUgMzYuNjM2NzE5IDYzLjE0MDYyNSAzOC40Mjk2ODggNjMuMTQwNjI1IEMgMzkuNDYwOTM4IDYzLjE0MDYyNSA0MC40NjA5MzggNjMuMDE1NjI1IDQxLjQyOTY4OCA2Mi43NjU2MjUgQyA0Mi40MDYyNSA2Mi41MDc4MTIgNDMuMzc1IDYyLjEyMTA5NCA0NC4zMzU5MzggNjEuNjA5Mzc1IEwgNDQuMzM1OTM4IDY0LjE3MTg3NSBDIDQzLjM2NzE4OCA2NC41NzgxMjUgNDIuMzcxMDk0IDY0Ljg4NjcxOSA0MS4zNTE1NjIgNjUuMDkzNzUgQyA0MC4zMzk4NDQgNjUuMzEyNSAzOS4zMTI1IDY1LjQyMTg3NSAzOC4yNzM0MzggNjUuNDIxODc1IEMgMzUuNjQ4NDM4IDY1LjQyMTg3NSAzMy41NzAzMTIgNjQuNjY0MDYyIDMyLjAzOTA2MiA2My4xNDA2MjUgQyAzMC41MTU2MjUgNjEuNjIxMDk0IDI5Ljc1NzgxMiA1OS41NTg1OTQgMjkuNzU3ODEyIDU2Ljk1MzEyNSBDIDI5Ljc1NzgxMiA1NC4yNjU2MjUgMzAuNDgwNDY5IDUyLjEzNjcxOSAzMS45Mjk2ODggNTAuNTYyNSBDIDMzLjM3NSA0OC45OTIxODggMzUuMzM1OTM4IDQ4LjIwMzEyNSAzNy44MDQ2ODggNDguMjAzMTI1IEMgNDAuMDExNzE5IDQ4LjIwMzEyNSA0MS43NTc4MTIgNDguOTE0MDYyIDQzLjAzOTA2MiA1MC4zMjgxMjUgQyA0NC4zMjAzMTIgNTEuNzQ2MDk0IDQ0Ljk2MDkzOCA1My42Nzk2ODggNDQuOTYwOTM4IDU2LjEyNSBaIE0gNDIuMjczNDM4IDU1LjMyODEyNSBDIDQyLjI1IDUzLjg1OTM3NSA0MS44MzU5MzggNTIuNjg3NSA0MS4wMjM0MzggNTEuODEyNSBDIDQwLjIxODc1IDUwLjkyOTY4OCAzOS4xNTYyNSA1MC40ODQzNzUgMzcuODM1OTM4IDUwLjQ4NDM3NSBDIDM2LjMyNDIxOSA1MC40ODQzNzUgMzUuMTE3MTg4IDUwLjkxNDA2MiAzNC4yMTA5MzggNTEuNzY1NjI1IEMgMzMuMzEyNSA1Mi42MDkzNzUgMzIuNzk2ODc1IDUzLjgwNDY4OCAzMi42NjQwNjIgNTUuMzQzNzUgWiBNIDQ5LjM4NjcxOSA0OC41OTM3NSBMIDUyLjA3NDIxOSA0OC41OTM3NSBMIDUyLjA3NDIxOSA2NS4yOTY4NzUgQyA1Mi4wNzQyMTkgNjcuMzc4OTA2IDUxLjY3NTc4MSA2OC44OTA2MjUgNTAuODg2NzE5IDY5LjgyODEyNSBDIDUwLjA5Mzc1IDcwLjc2NTYyNSA0OC44MTI1IDcxLjIzNDM3NSA0Ny4wNDI5NjkgNzEuMjM0Mzc1IEwgNDYuMDExNzE5IDcxLjIzNDM3NSBMIDQ2LjAxMTcxOSA2OC45NTMxMjUgTCA0Ni43MzA0NjkgNjguOTUzMTI1IEMgNDcuNzYxNzE5IDY4Ljk1MzEyNSA0OC40NTcwMzEgNjguNzEwOTM4IDQ4LjgyNDIxOSA2OC4yMzQzNzUgQyA0OS4xOTkyMTkgNjcuNzY1NjI1IDQ5LjM4NjcxOSA2Ni43ODUxNTYgNDkuMzg2NzE5IDY1LjI5Njg3NSBaIE0gNDkuMzg2NzE5IDQyLjIwMzEyNSBMIDUyLjA3NDIxOSA0Mi4yMDMxMjUgTCA1Mi4wNzQyMTkgNDUuNjI1IEwgNDkuMzg2NzE5IDQ1LjYyNSBaIE0gNjUuMTcxODc1IDU2Ljc1IEMgNjIuOTkyMTg4IDU2Ljc1IDYxLjQ4NDM3NSA1NyA2MC42NDA2MjUgNTcuNSBDIDU5LjgwNDY4OCA1OCA1OS4zOTA2MjUgNTguODUxNTYyIDU5LjM5MDYyNSA2MC4wNDY4NzUgQyA1OS4zOTA2MjUgNjEuMDA3ODEyIDU5LjcwMzEyNSA2MS43NjU2MjUgNjAuMzI4MTI1IDYyLjMyODEyNSBDIDYwLjk2MDkzOCA2Mi44OTA2MjUgNjEuODIwMzEyIDYzLjE3MTg3NSA2Mi45MDYyNSA2My4xNzE4NzUgQyA2NC4zOTQ1MzEgNjMuMTcxODc1IDY1LjU5Mzc1IDYyLjY0MDYyNSA2Ni41IDYxLjU3ODEyNSBDIDY3LjQwNjI1IDYwLjUxNTYyNSA2Ny44NTkzNzUgNTkuMTA5Mzc1IDY3Ljg1OTM3NSA1Ny4zNTkzNzUgTCA2Ny44NTkzNzUgNTYuNzUgWiBNIDcwLjU0Njg3NSA1NS42NDA2MjUgTCA3MC41NDY4NzUgNjUgTCA2Ny44NTkzNzUgNjUgTCA2Ny44NTkzNzUgNjIuNTE1NjI1IEMgNjcuMjQyMTg4IDYzLjUwNzgxMiA2Ni40NzI2NTYgNjQuMjQyMTg4IDY1LjU0Njg3NSA2NC43MTg3NSBDIDY0LjYyODkwNiA2NS4xODc1IDYzLjUwNzgxMiA2NS40MjE4NzUgNjIuMTg3NSA2NS40MjE4NzUgQyA2MC41MDc4MTIgNjUuNDIxODc1IDU5LjE3MTg3NSA2NC45NTMxMjUgNTguMTcxODc1IDY0LjAxNTYyNSBDIDU3LjE3OTY4OCA2My4wNzAzMTIgNTYuNjg3NSA2MS44MDQ2ODggNTYuNjg3NSA2MC4yMTg3NSBDIDU2LjY4NzUgNTguMzc1IDU3LjMwNDY4OCA1Ni45ODQzNzUgNTguNTQ2ODc1IDU2LjA0Njg3NSBDIDU5Ljc4NTE1NiA1NS4xMDkzNzUgNjEuNjI4OTA2IDU0LjY0MDYyNSA2NC4wNzgxMjUgNTQuNjQwNjI1IEwgNjcuODU5Mzc1IDU0LjY0MDYyNSBMIDY3Ljg1OTM3NSA1NC4zNzUgQyA2Ny44NTkzNzUgNTMuMTM2NzE5IDY3LjQ0NTMxMiA1Mi4xNzk2ODggNjYuNjI1IDUxLjUgQyA2NS44MTI1IDUwLjgyNDIxOSA2NC42NzE4NzUgNTAuNDg0Mzc1IDYzLjIwMzEyNSA1MC40ODQzNzUgQyA2Mi4yNjU2MjUgNTAuNDg0Mzc1IDYxLjM0NzY1NiA1MC42MDE1NjIgNjAuNDUzMTI1IDUwLjgyODEyNSBDIDU5LjU2NjQwNiA1MS4wNDY4NzUgNTguNzEwOTM4IDUxLjM4MjgxMiA1Ny44OTA2MjUgNTEuODI4MTI1IEwgNTcuODkwNjI1IDQ5LjM0Mzc1IEMgNTguODc4OTA2IDQ4Ljk2MDkzOCA1OS44MzU5MzggNDguNjcxODc1IDYwLjc2NTYyNSA0OC40ODQzNzUgQyA2MS42OTE0MDYgNDguMjk2ODc1IDYyLjU5Mzc1IDQ4LjIwMzEyNSA2My40Njg3NSA0OC4yMDMxMjUgQyA2NS44NDM3NSA0OC4yMDMxMjUgNjcuNjEzMjgxIDQ4LjgyMDMxMiA2OC43ODEyNSA1MC4wNDY4NzUgQyA2OS45NTcwMzEgNTEuMjc3MzQ0IDcwLjU0Njg3NSA1My4xNDA2MjUgNzAuNTQ2ODc1IDU1LjY0MDYyNSBaIE0gODEuODU1NDY5IDY1IEwgNzMuNTExNzE5IDQzLjEyNSBMIDc2LjYwNTQ2OSA0My4xMjUgTCA4My41MjczNDQgNjEuNTQ2ODc1IEwgOTAuNDgwNDY5IDQzLjEyNSBMIDkzLjU1ODU5NCA0My4xMjUgTCA4NS4yMTQ4NDQgNjUgWiBNIDk0LjMwODU5NCA1OC41MzEyNSBMIDk0LjMwODU5NCA0OC41OTM3NSBMIDk3LjAxMTcxOSA0OC41OTM3NSBMIDk3LjAxMTcxOSA1OC40MjE4NzUgQyA5Ny4wMTE3MTkgNTkuOTc2NTYyIDk3LjMxMjUgNjEuMTQwNjI1IDk3LjkxNzk2OSA2MS45MjE4NzUgQyA5OC41MTk1MzEgNjIuNjk1MzEyIDk5LjQyNTc4MSA2My4wNzgxMjUgMTAwLjYzNjcxOSA2My4wNzgxMjUgQyAxMDIuMDkzNzUgNjMuMDc4MTI1IDEwMy4yNDYwOTQgNjIuNjE3MTg4IDEwNC4wODk4NDQgNjEuNjg3NSBDIDEwNC45MzM1OTQgNjAuNzYxNzE5IDEwNS4zNTU0NjkgNTkuNDk2MDk0IDEwNS4zNTU0NjkgNTcuODkwNjI1IEwgMTA1LjM1NTQ2OSA0OC41OTM3NSBMIDEwOC4wNTg1OTQgNDguNTkzNzUgTCAxMDguMDU4NTk0IDY1IEwgMTA1LjM1NTQ2OSA2NSBMIDEwNS4zNTU0NjkgNjIuNDg0Mzc1IEMgMTA0LjY5OTIxOSA2My40NzY1NjIgMTAzLjkzNzUgNjQuMjE0ODQ0IDEwMy4wNzQyMTkgNjQuNzAzMTI1IEMgMTAyLjIwNzAzMSA2NS4xNzk2ODggMTAxLjIwNzAzMSA2NS40MjE4NzUgMTAwLjA3NDIxOSA2NS40MjE4NzUgQyA5OC4xODc1IDY1LjQyMTg3NSA5Ni43NTM5MDYgNjQuODM5ODQ0IDk1Ljc3NzM0NCA2My42NzE4NzUgQyA5NC43OTY4NzUgNjIuNDk2MDk0IDk0LjMwODU5NCA2MC43ODEyNSA5NC4zMDg1OTQgNTguNTMxMjUgWiBNIDEwMS4wODk4NDQgNDguMjAzMTI1IFogTSAxMzYuMzc1IDQzLjg0Mzc1IEwgMTM2LjM3NSA0Ni43MzQzNzUgQyAxMzUuMjUgNDYuMTk1MzEyIDEzNC4xODc1IDQ1Ljc5Mjk2OSAxMzMuMTg3NSA0NS41MzEyNSBDIDEzMi4xODc1IDQ1LjI3MzQzOCAxMzEuMjIyNjU2IDQ1LjE0MDYyNSAxMzAuMjk2ODc1IDQ1LjE0MDYyNSBDIDEyOC42OTE0MDYgNDUuMTQwNjI1IDEyNy40NTMxMjUgNDUuNDUzMTI1IDEyNi41NzgxMjUgNDYuMDc4MTI1IEMgMTI1LjcwMzEyNSA0Ni43MDMxMjUgMTI1LjI2NTYyNSA0Ny41ODk4NDQgMTI1LjI2NTYyNSA0OC43MzQzNzUgQyAxMjUuMjY1NjI1IDQ5LjcwMzEyNSAxMjUuNTUwNzgxIDUwLjQzNzUgMTI2LjEyNSA1MC45Mzc1IEMgMTI2LjcwNzAzMSA1MS40Mjk2ODggMTI3LjgxMjUgNTEuODI0MjE5IDEyOS40Mzc1IDUyLjEyNSBMIDEzMS4yMTg3NSA1Mi40ODQzNzUgQyAxMzMuNDI1NzgxIDUyLjkxNDA2MiAxMzUuMDU0Njg4IDUzLjY1NjI1IDEzNi4xMDkzNzUgNTQuNzE4NzUgQyAxMzcuMTYwMTU2IDU1Ljc3MzQzOCAxMzcuNjg3NSA1Ny4xODc1IDEzNy42ODc1IDU4Ljk2ODc1IEMgMTM3LjY4NzUgNjEuMDg1OTM4IDEzNi45NzI2NTYgNjIuNjg3NSAxMzUuNTQ2ODc1IDYzLjc4MTI1IEMgMTM0LjEyODkwNiA2NC44NzUgMTMyLjA1MDc4MSA2NS40MjE4NzUgMTI5LjMxMjUgNjUuNDIxODc1IEMgMTI4LjI2OTUzMSA2NS40MjE4NzUgMTI3LjE2NDA2MiA2NS4zMDA3ODEgMTI2IDY1LjA2MjUgQyAxMjQuODMyMDMxIDY0LjgzNTkzOCAxMjMuNjI1IDY0LjQ5MjE4OCAxMjIuMzc1IDY0LjAzMTI1IEwgMTIyLjM3NSA2MC45ODQzNzUgQyAxMjMuNTgyMDMxIDYxLjY2NDA2MiAxMjQuNzU3ODEyIDYyLjE3MTg3NSAxMjUuOTA2MjUgNjIuNTE1NjI1IEMgMTI3LjA2MjUgNjIuODUxNTYyIDEyOC4xOTUzMTIgNjMuMDE1NjI1IDEyOS4zMTI1IDYzLjAxNTYyNSBDIDEzMSA2My4wMTU2MjUgMTMyLjMwMDc4MSA2Mi42ODc1IDEzMy4yMTg3NSA2Mi4wMzEyNSBDIDEzNC4xMzI4MTIgNjEuMzY3MTg4IDEzNC41OTM3NSA2MC40MTc5NjkgMTM0LjU5Mzc1IDU5LjE4NzUgQyAxMzQuNTkzNzUgNTguMTE3MTg4IDEzNC4yNjU2MjUgNTcuMjc3MzQ0IDEzMy42MDkzNzUgNTYuNjcxODc1IEMgMTMyLjk1MzEyNSA1Ni4wNTg1OTQgMTMxLjg2NzE4OCA1NS42MDE1NjIgMTMwLjM1OTM3NSA1NS4yOTY4NzUgTCAxMjguNTYyNSA1NC45NTMxMjUgQyAxMjYuMzUxNTYyIDU0LjUxNTYyNSAxMjQuNzUzOTA2IDUzLjgyODEyNSAxMjMuNzY1NjI1IDUyLjg5MDYyNSBDIDEyMi43ODUxNTYgNTEuOTUzMTI1IDEyMi4yOTY4NzUgNTAuNjQ4NDM4IDEyMi4yOTY4NzUgNDguOTY4NzUgQyAxMjIuMjk2ODc1IDQ3LjA0Mjk2OSAxMjIuOTcyNjU2IDQ1LjUyMzQzOCAxMjQuMzI4MTI1IDQ0LjQwNjI1IEMgMTI1LjY5MTQwNiA0My4yOTI5NjkgMTI3LjU3MDMxMiA0Mi43MzQzNzUgMTI5Ljk2ODc1IDQyLjczNDM3NSBDIDEzMC45ODgyODEgNDIuNzM0Mzc1IDEzMi4wMzEyNSA0Mi44MjgxMjUgMTMzLjA5Mzc1IDQzLjAxNTYyNSBDIDEzNC4xNjQwNjIgNDMuMjAzMTI1IDEzNS4yNTc4MTIgNDMuNDgwNDY5IDEzNi4zNzUgNDMuODQzNzUgWiBNIDE0OS42MzY3MTkgNTYuNzUgQyAxNDcuNDU3MDMxIDU2Ljc1IDE0NS45NDkyMTkgNTcgMTQ1LjEwNTQ2OSA1Ny41IEMgMTQ0LjI2OTUzMSA1OCAxNDMuODU1NDY5IDU4Ljg1MTU2MiAxNDMuODU1NDY5IDYwLjA0Njg3NSBDIDE0My44NTU0NjkgNjEuMDA3ODEyIDE0NC4xNjc5NjkgNjEuNzY1NjI1IDE0NC43OTI5NjkgNjIuMzI4MTI1IEMgMTQ1LjQyNTc4MSA2Mi44OTA2MjUgMTQ2LjI4NTE1NiA2My4xNzE4NzUgMTQ3LjM3MTA5NCA2My4xNzE4NzUgQyAxNDguODU5Mzc1IDYzLjE3MTg3NSAxNTAuMDU4NTk0IDYyLjY0MDYyNSAxNTAuOTY0ODQ0IDYxLjU3ODEyNSBDIDE1MS44NzEwOTQgNjAuNTE1NjI1IDE1Mi4zMjQyMTkgNTkuMTA5Mzc1IDE1Mi4zMjQyMTkgNTcuMzU5Mzc1IEwgMTUyLjMyNDIxOSA1Ni43NSBaIE0gMTU1LjAxMTcxOSA1NS42NDA2MjUgTCAxNTUuMDExNzE5IDY1IEwgMTUyLjMyNDIxOSA2NSBMIDE1Mi4zMjQyMTkgNjIuNTE1NjI1IEMgMTUxLjcwNzAzMSA2My41MDc4MTIgMTUwLjkzNzUgNjQuMjQyMTg4IDE1MC4wMTE3MTkgNjQuNzE4NzUgQyAxNDkuMDkzNzUgNjUuMTg3NSAxNDcuOTcyNjU2IDY1LjQyMTg3NSAxNDYuNjUyMzQ0IDY1LjQyMTg3NSBDIDE0NC45NzI2NTYgNjUuNDIxODc1IDE0My42MzY3MTkgNjQuOTUzMTI1IDE0Mi42MzY3MTkgNjQuMDE1NjI1IEMgMTQxLjY0NDUzMSA2My4wNzAzMTIgMTQxLjE1MjM0NCA2MS44MDQ2ODggMTQxLjE1MjM0NCA2MC4yMTg3NSBDIDE0MS4xNTIzNDQgNTguMzc1IDE0MS43Njk1MzEgNTYuOTg0Mzc1IDE0My4wMTE3MTkgNTYuMDQ2ODc1IEMgMTQ0LjI1IDU1LjEwOTM3NSAxNDYuMDkzNzUgNTQuNjQwNjI1IDE0OC41NDI5NjkgNTQuNjQwNjI1IEwgMTUyLjMyNDIxOSA1NC42NDA2MjUgTCAxNTIuMzI0MjE5IDU0LjM3NSBDIDE1Mi4zMjQyMTkgNTMuMTM2NzE5IDE1MS45MTAxNTYgNTIuMTc5Njg4IDE1MS4wODk4NDQgNTEuNSBDIDE1MC4yNzczNDQgNTAuODI0MjE5IDE0OS4xMzY3MTkgNTAuNDg0Mzc1IDE0Ny42Njc5NjkgNTAuNDg0Mzc1IEMgMTQ2LjczMDQ2OSA1MC40ODQzNzUgMTQ1LjgxMjUgNTAuNjAxNTYyIDE0NC45MTc5NjkgNTAuODI4MTI1IEMgMTQ0LjAzMTI1IDUxLjA0Njg3NSAxNDMuMTc1NzgxIDUxLjM4MjgxMiAxNDIuMzU1NDY5IDUxLjgyODEyNSBMIDE0Mi4zNTU0NjkgNDkuMzQzNzUgQyAxNDMuMzQzNzUgNDguOTYwOTM4IDE0NC4zMDA3ODEgNDguNjcxODc1IDE0NS4yMzA0NjkgNDguNDg0Mzc1IEMgMTQ2LjE1NjI1IDQ4LjI5Njg3NSAxNDcuMDU4NTk0IDQ4LjIwMzEyNSAxNDcuOTMzNTk0IDQ4LjIwMzEyNSBDIDE1MC4zMDg1OTQgNDguMjAzMTI1IDE1Mi4wNzgxMjUgNDguODIwMzEyIDE1My4yNDYwOTQgNTAuMDQ2ODc1IEMgMTU0LjQyMTg3NSA1MS4yNzczNDQgMTU1LjAxMTcxOSA1My4xNDA2MjUgMTU1LjAxMTcxOSA1NS42NDA2MjUgWiBNIDE3NC4yMDcwMzEgNTUuMDkzNzUgTCAxNzQuMjA3MDMxIDY1IEwgMTcxLjUwMzkwNiA2NSBMIDE3MS41MDM5MDYgNTUuMTg3NSBDIDE3MS41MDM5MDYgNTMuNjM2NzE5IDE3MS4xOTkyMTkgNTIuNDc2NTYyIDE3MC41OTc2NTYgNTEuNzAzMTI1IEMgMTY5Ljk5MjE4OCA1MC45MzM1OTQgMTY5LjA4NTkzOCA1MC41NDY4NzUgMTY3Ljg3ODkwNiA1MC41NDY4NzUgQyAxNjYuNDE3OTY5IDUwLjU0Njg3NSAxNjUuMjY5NTMxIDUxLjAxMTcxOSAxNjQuNDI1NzgxIDUxLjkzNzUgQyAxNjMuNTg5ODQ0IDUyLjg2NzE4OCAxNjMuMTc1NzgxIDU0LjEzMjgxMiAxNjMuMTc1NzgxIDU1LjczNDM3NSBMIDE2My4xNzU3ODEgNjUgTCAxNjAuNDU3MDMxIDY1IEwgMTYwLjQ1NzAzMSA0OC41OTM3NSBMIDE2My4xNzU3ODEgNDguNTkzNzUgTCAxNjMuMTc1NzgxIDUxLjE0MDYyNSBDIDE2My44MjAzMTIgNTAuMTUyMzQ0IDE2NC41ODIwMzEgNDkuNDE3OTY5IDE2NS40NTcwMzEgNDguOTM3NSBDIDE2Ni4zMzIwMzEgNDguNDQ5MjE5IDE2Ny4zMzU5MzggNDguMjAzMTI1IDE2OC40NzI2NTYgNDguMjAzMTI1IEMgMTcwLjM1NTQ2OSA0OC4yMDMxMjUgMTcxLjc4NTE1NiA0OC43ODkwNjIgMTcyLjc1MzkwNiA0OS45NTMxMjUgQyAxNzMuNzIyNjU2IDUxLjEyMTA5NCAxNzQuMjA3MDMxIDUyLjgzNTkzOCAxNzQuMjA3MDMxIDU1LjA5Mzc1IFogTSAxOTAuMDM1MTU2IDQ5LjA3ODEyNSBMIDE5MC4wMzUxNTYgNTEuNjI1IEMgMTg5LjI3MzQzOCA1MS4yNDIxODggMTg4LjQ4MDQ2OSA1MC45NDkyMTkgMTg3LjY2MDE1NiA1MC43NSBDIDE4Ni44NDc2NTYgNTAuNTU0Njg4IDE4NS45OTYwOTQgNTAuNDUzMTI1IDE4NS4xMTMyODEgNTAuNDUzMTI1IEMgMTgzLjc3NzM0NCA1MC40NTMxMjUgMTgyLjc3MzQzOCA1MC42NjQwNjIgMTgyLjA5NzY1NiA1MS4wNzgxMjUgQyAxODEuNDI5Njg4IDUxLjQ4NDM3NSAxODEuMDk3NjU2IDUyLjEwMTU2MiAxODEuMDk3NjU2IDUyLjkyMTg3NSBDIDE4MS4wOTc2NTYgNTMuNTQ2ODc1IDE4MS4zMzU5MzggNTQuMDM5MDYyIDE4MS44MTY0MDYgNTQuMzkwNjI1IEMgMTgyLjI5Mjk2OSA1NC43NDYwOTQgMTgzLjI1NzgxMiA1NS4wODU5MzggMTg0LjcwNzAzMSA1NS40MDYyNSBMIDE4NS42Mjg5MDYgNTUuNjA5Mzc1IEMgMTg3LjU0Mjk2OSA1Ni4wMTU2MjUgMTg4LjkwMjM0NCA1Ni41OTM3NSAxODkuNzA3MDMxIDU3LjM0Mzc1IEMgMTkwLjUxOTUzMSA1OC4wOTM3NSAxOTAuOTI1NzgxIDU5LjEzNjcxOSAxOTAuOTI1NzgxIDYwLjQ2ODc1IEMgMTkwLjkyNTc4MSA2MiAxOTAuMzIwMzEyIDYzLjIxMDkzOCAxODkuMTEzMjgxIDY0LjA5Mzc1IEMgMTg3LjkwMjM0NCA2NC45ODA0NjkgMTg2LjI0NjA5NCA2NS40MjE4NzUgMTg0LjE0NDUzMSA2NS40MjE4NzUgQyAxODMuMjU3ODEyIDY1LjQyMTg3NSAxODIuMzM1OTM4IDY1LjMzMjAzMSAxODEuMzc4OTA2IDY1LjE1NjI1IEMgMTgwLjQyOTY4OCA2NC45OTIxODggMTc5LjQyOTY4OCA2NC43NDIxODggMTc4LjM3ODkwNiA2NC40MDYyNSBMIDE3OC4zNzg5MDYgNjEuNjA5Mzc1IEMgMTc5LjM3ODkwNiA2Mi4xMzI4MTIgMTgwLjM1NTQ2OSA2Mi41MjM0MzggMTgxLjMxNjQwNiA2Mi43ODEyNSBDIDE4Mi4yODUxNTYgNjMuMDQyOTY5IDE4My4yNDIxODggNjMuMTcxODc1IDE4NC4xOTE0MDYgNjMuMTcxODc1IEMgMTg1LjQ2MDkzOCA2My4xNzE4NzUgMTg2LjQzMzU5NCA2Mi45NTMxMjUgMTg3LjExMzI4MSA2Mi41MTU2MjUgQyAxODcuODAwNzgxIDYyLjA3ODEyNSAxODguMTQ0NTMxIDYxLjQ2NDg0NCAxODguMTQ0NTMxIDYwLjY3MTg3NSBDIDE4OC4xNDQ1MzEgNTkuOTQ1MzEyIDE4Ny44OTg0MzggNTkuMzg2NzE5IDE4Ny40MTAxNTYgNTkgQyAxODYuOTE3OTY5IDU4LjYwNTQ2OSAxODUuODM1OTM4IDU4LjIyNjU2MiAxODQuMTYwMTU2IDU3Ljg1OTM3NSBMIDE4My4yMjI2NTYgNTcuNjQwNjI1IEMgMTgxLjU1NDY4OCA1Ny4yOTY4NzUgMTgwLjM1MTU2MiA1Ni43NjE3MTkgMTc5LjYxMzI4MSA1Ni4wMzEyNSBDIDE3OC44NzEwOTQgNTUuMzA0Njg4IDE3OC41MDM5MDYgNTQuMzA0Njg4IDE3OC41MDM5MDYgNTMuMDMxMjUgQyAxNzguNTAzOTA2IDUxLjQ5MjE4OCAxNzkuMDUwNzgxIDUwLjMwNDY4OCAxODAuMTQ0NTMxIDQ5LjQ2ODc1IEMgMTgxLjIzODI4MSA0OC42MjUgMTgyLjc4OTA2MiA0OC4yMDMxMjUgMTg0LjgwMDc4MSA0OC4yMDMxMjUgQyAxODUuNzg5MDYyIDQ4LjIwMzEyNSAxODYuNzIyNjU2IDQ4LjI3NzM0NCAxODcuNTk3NjU2IDQ4LjQyMTg3NSBDIDE4OC40ODA0NjkgNDguNTcwMzEyIDE4OS4yOTI5NjkgNDguNzg5MDYyIDE5MC4wMzUxNTYgNDkuMDc4MTI1IFogTSA1IDM3LjE1MjM0NCAiLz4KPHBhdGggZmlsbC1ydWxlPSJub256ZXJvIiBmaWxsPSJyZ2IoMCUsIDAlLCAwJSkiIGZpbGwtb3BhY2l0eT0iMSIgZD0iTSAxMy4zOTA2MjUgNzcuMzkwNjI1IEwgMTMuMzkwNjI1IDkwLjczNDM3NSBMIDE1LjQyMTg3NSA5MC43MzQzNzUgQyAxNy43MjI2NTYgOTAuNzM0Mzc1IDE5LjQ3NjU2MiA5MC4xNjc5NjkgMjAuNjg3NSA4OS4wMzEyNSBDIDIxLjkwNjI1IDg3Ljg4NjcxOSAyMi41MTU2MjUgODYuMjI2NTYyIDIyLjUxNTYyNSA4NC4wNDY4NzUgQyAyMi41MTU2MjUgODEuODgyODEyIDIxLjkxMDE1NiA4MC4yMzA0NjkgMjAuNzAzMTI1IDc5LjA5Mzc1IEMgMTkuNDkyMTg4IDc3Ljk2MDkzOCAxNy43MzQzNzUgNzcuMzkwNjI1IDE1LjQyMTg3NSA3Ny4zOTA2MjUgWiBNIDcuNzUgNzMuMTI1IEwgMTMuNzAzMTI1IDczLjEyNSBDIDE3LjAyMzQzOCA3My4xMjUgMTkuNSA3My4zNjcxODggMjEuMTI1IDczLjg0Mzc1IEMgMjIuNzUgNzQuMzEyNSAyNC4xNDA2MjUgNzUuMTE3MTg4IDI1LjI5Njg3NSA3Ni4yNSBDIDI2LjMyODEyNSA3Ny4yNDIxODggMjcuMDg1OTM4IDc4LjM4MjgxMiAyNy41NzgxMjUgNzkuNjcxODc1IEMgMjguMDc4MTI1IDgwLjk1MzEyNSAyOC4zMjgxMjUgODIuNDE0MDYyIDI4LjMyODEyNSA4NC4wNDY4NzUgQyAyOC4zMjgxMjUgODUuNjk1MzEyIDI4LjA3ODEyNSA4Ny4xNjc5NjkgMjcuNTc4MTI1IDg4LjQ2ODc1IEMgMjcuMDg1OTM4IDg5Ljc2MTcxOSAyNi4zMjgxMjUgOTAuODk4NDM4IDI1LjI5Njg3NSA5MS44NzUgQyAyNC4xMjg5MDYgOTMuMDExNzE5IDIyLjcyMjY1NiA5My44MjAzMTIgMjEuMDc4MTI1IDk0LjI5Njg3NSBDIDE5LjQ0MTQwNiA5NC43NjU2MjUgMTYuOTg0Mzc1IDk1IDEzLjcwMzEyNSA5NSBMIDcuNzUgOTUgWiBNIDQ4Ljc5Mjk2OSA4Ni43NSBMIDQ4Ljc5Mjk2OSA4OC4yNSBMIDM2LjU0Mjk2OSA4OC4yNSBDIDM2LjY2Nzk2OSA4OS40ODA0NjkgMzcuMTA5Mzc1IDkwLjQwMjM0NCAzNy44NzEwOTQgOTEuMDE1NjI1IEMgMzguNjI4OTA2IDkxLjYzMjgxMiAzOS42OTE0MDYgOTEuOTM3NSA0MS4wNTg1OTQgOTEuOTM3NSBDIDQyLjE2MDE1NiA5MS45Mzc1IDQzLjI5Mjk2OSA5MS43NzczNDQgNDQuNDQ5MjE5IDkxLjQ1MzEyNSBDIDQ1LjYxMzI4MSA5MS4xMjEwOTQgNDYuODA4NTk0IDkwLjYyMTA5NCA0OC4wMjczNDQgODkuOTUzMTI1IEwgNDguMDI3MzQ0IDk0IEMgNDYuNzg1MTU2IDk0LjQ2ODc1IDQ1LjU0Njg3NSA5NC44MjQyMTkgNDQuMzA4NTk0IDk1LjA2MjUgQyA0My4wNjY0MDYgOTUuMzAwNzgxIDQxLjgyNDIxOSA5NS40MjE4NzUgNDAuNTc0MjE5IDk1LjQyMTg3NSBDIDM3LjYwNTQ2OSA5NS40MjE4NzUgMzUuMjk2ODc1IDk0LjY2Nzk2OSAzMy42NTIzNDQgOTMuMTU2MjUgQyAzMi4wMTU2MjUgOTEuNjQ4NDM4IDMxLjE5OTIxOSA4OS41MzEyNSAzMS4xOTkyMTkgODYuODEyNSBDIDMxLjE5OTIxOSA4NC4xMzY3MTkgMzIuMDAzOTA2IDgyLjAzMTI1IDMzLjYyMTA5NCA4MC41IEMgMzUuMjM0Mzc1IDc4Ljk2ODc1IDM3LjQ1NzAzMSA3OC4yMDMxMjUgNDAuMjkyOTY5IDc4LjIwMzEyNSBDIDQyLjg2MzI4MSA3OC4yMDMxMjUgNDQuOTIxODc1IDc4Ljk4MDQ2OSA0Ni40NjQ4NDQgODAuNTMxMjUgQyA0OC4wMTU2MjUgODIuMDg1OTM4IDQ4Ljc5Mjk2OSA4NC4xNTYyNSA0OC43OTI5NjkgODYuNzUgWiBNIDQzLjQwMjM0NCA4NS4wMTU2MjUgQyA0My40MDIzNDQgODQuMDE1NjI1IDQzLjEwOTM3NSA4My4yMTQ4NDQgNDIuNTI3MzQ0IDgyLjYwOTM3NSBDIDQxLjk1MzEyNSA4MS45OTYwOTQgNDEuMTk5MjE5IDgxLjY4NzUgNDAuMjYxNzE5IDgxLjY4NzUgQyAzOS4yMzgyODEgODEuNjg3NSAzOC40MTAxNTYgODEuOTc2NTYyIDM3Ljc3NzM0NCA4Mi41NDY4NzUgQyAzNy4xNDA2MjUgODMuMTA5Mzc1IDM2Ljc0NjA5NCA4My45MzM1OTQgMzYuNTg5ODQ0IDg1LjAxNTYyNSBaIE0gNTIuNzY1NjI1IDc4LjU5Mzc1IEwgNTguMDE1NjI1IDc4LjU5Mzc1IEwgNTguMDE1NjI1IDk0LjcwMzEyNSBDIDU4LjAxNTYyNSA5Ni44OTg0MzggNTcuNDg0Mzc1IDk4LjU3ODEyNSA1Ni40MjE4NzUgOTkuNzM0Mzc1IEMgNTUuMzY3MTg4IDEwMC44OTA2MjUgNTMuODQzNzUgMTAxLjQ2ODc1IDUxLjg0Mzc1IDEwMS40Njg3NSBMIDQ5LjI1IDEwMS40Njg3NSBMIDQ5LjI1IDk4LjAzMTI1IEwgNTAuMTU2MjUgOTguMDMxMjUgQyA1MS4xNTYyNSA5OC4wMzEyNSA1MS44MzU5MzggOTcuODA0Njg4IDUyLjIwMzEyNSA5Ny4zNTkzNzUgQyA1Mi41NzgxMjUgOTYuOTEwMTU2IDUyLjc2NTYyNSA5Ni4wMjM0MzggNTIuNzY1NjI1IDk0LjcwMzEyNSBaIE0gNTIuNzY1NjI1IDcyLjIwMzEyNSBMIDU4LjAxNTYyNSA3Mi4yMDMxMjUgTCA1OC4wMTU2MjUgNzYuNDg0Mzc1IEwgNTIuNzY1NjI1IDc2LjQ4NDM3NSBaIE0gNzAuNDA2MjUgODcuNjA5Mzc1IEMgNjkuMzEyNSA4Ny42MDkzNzUgNjguNDg4MjgxIDg3Ljc5Njg3NSA2Ny45Mzc1IDg4LjE3MTg3NSBDIDY3LjM4MjgxMiA4OC41NDY4NzUgNjcuMTA5Mzc1IDg5LjA5Mzc1IDY3LjEwOTM3NSA4OS44MTI1IEMgNjcuMTA5Mzc1IDkwLjQ4MDQ2OSA2Ny4zMjgxMjUgOTEgNjcuNzY1NjI1IDkxLjM3NSBDIDY4LjIxMDkzOCA5MS43NSA2OC44MzIwMzEgOTEuOTM3NSA2OS42MjUgOTEuOTM3NSBDIDcwLjYxMzI4MSA5MS45Mzc1IDcxLjQ0MTQwNiA5MS41ODU5MzggNzIuMTA5Mzc1IDkwLjg3NSBDIDcyLjc4NTE1NiA5MC4xNjc5NjkgNzMuMTI1IDg5LjI4MTI1IDczLjEyNSA4OC4yMTg3NSBMIDczLjEyNSA4Ny42MDkzNzUgWiBNIDc4LjQyMTg3NSA4NS42NDA2MjUgTCA3OC40MjE4NzUgOTUgTCA3My4xMjUgOTUgTCA3My4xMjUgOTIuNTYyNSBDIDcyLjQyNTc4MSA5My41NjI1IDcxLjYzMjgxMiA5NC4yOTI5NjkgNzAuNzUgOTQuNzUgQyA2OS44NzUgOTUuMTk1MzEyIDY4LjgwNDY4OCA5NS40MjE4NzUgNjcuNTQ2ODc1IDk1LjQyMTg3NSBDIDY1Ljg0NzY1NiA5NS40MjE4NzUgNjQuNDY4NzUgOTQuOTI5Njg4IDYzLjQwNjI1IDkzLjkzNzUgQyA2Mi4zNTE1NjIgOTIuOTQ5MjE5IDYxLjgyODEyNSA5MS42NjQwNjIgNjEuODI4MTI1IDkwLjA3ODEyNSBDIDYxLjgyODEyNSA4OC4xNTIzNDQgNjIuNDg4MjgxIDg2Ljc0MjE4OCA2My44MTI1IDg1Ljg0Mzc1IEMgNjUuMTMyODEyIDg0Ljk0OTIxOSA2Ny4yMDcwMzEgODQuNSA3MC4wMzEyNSA4NC41IEwgNzMuMTI1IDg0LjUgTCA3My4xMjUgODQuMDkzNzUgQyA3My4xMjUgODMuMjYxNzE5IDcyLjc5Njg3NSA4Mi42NTIzNDQgNzIuMTQwNjI1IDgyLjI2NTYyNSBDIDcxLjQ5MjE4OCA4MS44ODI4MTIgNzAuNDc2NTYyIDgxLjY4NzUgNjkuMDkzNzUgODEuNjg3NSBDIDY3Ljk2ODc1IDgxLjY4NzUgNjYuOTIxODc1IDgxLjgwNDY4OCA2NS45NTMxMjUgODIuMDMxMjUgQyA2NC45ODQzNzUgODIuMjUgNjQuMDgyMDMxIDgyLjU4NTkzOCA2My4yNSA4My4wMzEyNSBMIDYzLjI1IDc5LjAzMTI1IEMgNjQuMzc1IDc4Ljc2MTcxOSA2NS41MDM5MDYgNzguNTU4NTk0IDY2LjY0MDYyNSA3OC40MjE4NzUgQyA2Ny43NzM0MzggNzguMjc3MzQ0IDY4LjkwNjI1IDc4LjIwMzEyNSA3MC4wMzEyNSA3OC4yMDMxMjUgQyA3MyA3OC4yMDMxMjUgNzUuMTQwNjI1IDc4Ljc4OTA2MiA3Ni40NTMxMjUgNzkuOTUzMTI1IEMgNzcuNzY1NjI1IDgxLjEyMTA5NCA3OC40MjE4NzUgODMuMDE1NjI1IDc4LjQyMTg3NSA4NS42NDA2MjUgWiBNIDgwLjkxNzk2OSA3My4xMjUgTCA4Ni41ODk4NDQgNzMuMTI1IEwgOTIuMzg2NzE5IDg5LjI2NTYyNSBMIDk4LjE4MzU5NCA3My4xMjUgTCAxMDMuODU1NDY5IDczLjEyNSBMIDk1Ljc0NjA5NCA5NSBMIDg5LjAyNzM0NCA5NSBaIE0gMTA1LjI2OTUzMSA4OC42MDkzNzUgTCAxMDUuMjY5NTMxIDc4LjU5Mzc1IEwgMTEwLjU1MDc4MSA3OC41OTM3NSBMIDExMC41NTA3ODEgODAuMjM0Mzc1IEMgMTEwLjU1MDc4MSA4MS4xMjEwOTQgMTEwLjU0Mjk2OSA4Mi4yMzQzNzUgMTEwLjUzNTE1NiA4My41NzgxMjUgQyAxMTAuNTIzNDM4IDg0LjkyMTg3NSAxMTAuNTE5NTMxIDg1LjgyMDMxMiAxMTAuNTE5NTMxIDg2LjI2NTYyNSBDIDExMC41MTk1MzEgODcuNTg5ODQ0IDExMC41NTA3ODEgODguNTQyOTY5IDExMC42MTMyODEgODkuMTI1IEMgMTEwLjY4MzU5NCA4OS42OTkyMTkgMTEwLjgwNDY4OCA5MC4xMjEwOTQgMTEwLjk3MjY1NiA5MC4zOTA2MjUgQyAxMTEuMTc5Njg4IDkwLjcyNjU2MiAxMTEuNDU3MDMxIDkwLjk4NDM3NSAxMTEuODAwNzgxIDkxLjE3MTg3NSBDIDExMi4xNTIzNDQgOTEuMzU5Mzc1IDExMi41NTQ2ODggOTEuNDUzMTI1IDExMy4wMDM5MDYgOTEuNDUzMTI1IEMgMTE0LjA5NzY1NiA5MS40NTMxMjUgMTE0Ljk1NzAzMSA5MS4wMzkwNjIgMTE1LjU4MjAzMSA5MC4yMDMxMjUgQyAxMTYuMjA3MDMxIDg5LjM1OTM3NSAxMTYuNTE5NTMxIDg4LjE4NzUgMTE2LjUxOTUzMSA4Ni42ODc1IEwgMTE2LjUxOTUzMSA3OC41OTM3NSBMIDEyMS43Njk1MzEgNzguNTkzNzUgTCAxMjEuNzY5NTMxIDk1IEwgMTE2LjUxOTUzMSA5NSBMIDExNi41MTk1MzEgOTIuNjI1IEMgMTE1LjcyNjU2MiA5My41ODU5MzggMTE0Ljg4NjcxOSA5NC4yOTI5NjkgMTE0LjAwMzkwNiA5NC43NSBDIDExMy4xMTcxODggOTUuMTk1MzEyIDExMi4xNDQ1MzEgOTUuNDIxODc1IDExMS4wODIwMzEgOTUuNDIxODc1IEMgMTA5LjE4MzU5NCA5NS40MjE4NzUgMTA3Ljc0MjE4OCA5NC44NDM3NSAxMDYuNzUzOTA2IDkzLjY4NzUgQyAxMDUuNzYxNzE5IDkyLjUyMzQzOCAxMDUuMjY5NTMxIDkwLjgyODEyNSAxMDUuMjY5NTMxIDg4LjYwOTM3NSBaIE0gMTUyLjY5NTMxMiA3My44MTI1IEwgMTUyLjY5NTMxMiA3OC40NTMxMjUgQyAxNTEuNDk2MDk0IDc3LjkxNDA2MiAxNTAuMzI0MjE5IDc3LjUwNzgxMiAxNDkuMTc5Njg4IDc3LjIzNDM3NSBDIDE0OC4wNDI5NjkgNzYuOTY0ODQ0IDE0Ni45NjQ4NDQgNzYuODI4MTI1IDE0NS45NDUzMTIgNzYuODI4MTI1IEMgMTQ0LjYwMTU2MiA3Ni44MjgxMjUgMTQzLjYwNTQ2OSA3Ny4wMTU2MjUgMTQyLjk2MDkzOCA3Ny4zOTA2MjUgQyAxNDIuMzEyNSA3Ny43NTc4MTIgMTQxLjk5MjE4OCA3OC4zMjgxMjUgMTQxLjk5MjE4OCA3OS4xMDkzNzUgQyAxNDEuOTkyMTg4IDc5LjY5NTMxMiAxNDIuMjAzMTI1IDgwLjE1MjM0NCAxNDIuNjMyODEyIDgwLjQ4NDM3NSBDIDE0My4wNzAzMTIgODAuODA4NTk0IDE0My44NTkzNzUgODEuMDg1OTM4IDE0NS4wMDc4MTIgODEuMzEyNSBMIDE0Ny40MTQwNjIgODEuNzk2ODc1IEMgMTQ5LjgzOTg0NCA4Mi4yODkwNjIgMTUxLjU2MjUgODMuMDMxMjUgMTUyLjU4NTkzOCA4NC4wMzEyNSBDIDE1My42MTcxODggODUuMDIzNDM4IDE1NC4xMzI4MTIgODYuNDM3NSAxNTQuMTMyODEyIDg4LjI4MTI1IEMgMTU0LjEzMjgxMiA5MC42ODc1IDE1My40MTc5NjkgOTIuNDgwNDY5IDE1MS45OTIxODggOTMuNjU2MjUgQyAxNTAuNTYyNSA5NC44MzU5MzggMTQ4LjM3NSA5NS40MjE4NzUgMTQ1LjQyOTY4OCA5NS40MjE4NzUgQyAxNDQuMDQyOTY5IDk1LjQyMTg3NSAxNDIuNjUyMzQ0IDk1LjI4OTA2MiAxNDEuMjU3ODEyIDk1LjAzMTI1IEMgMTM5Ljg1OTM3NSA5NC43NzM0MzggMTM4LjQ2NDg0NCA5NC4zODI4MTIgMTM3LjA3MDMxMiA5My44NTkzNzUgTCAxMzcuMDcwMzEyIDg5LjA5Mzc1IEMgMTM4LjQ2NDg0NCA4OS44MzU5MzggMTM5LjgxMjUgOTAuMzk4NDM4IDE0MS4xMTcxODggOTAuNzgxMjUgQyAxNDIuNDE3OTY5IDkxLjE1NjI1IDE0My42Nzk2ODggOTEuMzQzNzUgMTQ0Ljg5ODQzOCA5MS4zNDM3NSBDIDE0Ni4xMjUgOTEuMzQzNzUgMTQ3LjA2MjUgOTEuMTQwNjI1IDE0Ny43MTA5MzggOTAuNzM0Mzc1IEMgMTQ4LjM2NzE4OCA5MC4zMjAzMTIgMTQ4LjY5NTMxMiA4OS43MzA0NjkgMTQ4LjY5NTMxMiA4OC45Njg3NSBDIDE0OC42OTUzMTIgODguMjgxMjUgMTQ4LjQ2ODc1IDg3Ljc1NzgxMiAxNDguMDIzNDM4IDg3LjM5MDYyNSBDIDE0Ny41ODU5MzggODcuMDE1NjI1IDE0Ni43MDMxMjUgODYuNjgzNTk0IDE0NS4zODI4MTIgODYuMzkwNjI1IEwgMTQzLjE5NTMxMiA4NS45MDYyNSBDIDE0MS4wMDc4MTIgODUuNDM3NSAxMzkuNDA2MjUgODQuNjk1MzEyIDEzOC4zOTg0MzggODMuNjcxODc1IEMgMTM3LjM4NjcxOSA4Mi42NDA2MjUgMTM2Ljg4MjgxMiA4MS4yNTc4MTIgMTM2Ljg4MjgxMiA3OS41MTU2MjUgQyAxMzYuODgyODEyIDc3LjMzOTg0NCAxMzcuNTg1OTM4IDc1LjY2Nzk2OSAxMzguOTkyMTg4IDc0LjUgQyAxNDAuMzk4NDM4IDczLjMyNDIxOSAxNDIuNDE3OTY5IDcyLjczNDM3NSAxNDUuMDU0Njg4IDcyLjczNDM3NSBDIDE0Ni4yNSA3Mi43MzQzNzUgMTQ3LjQ4NDM3NSA3Mi44MjgxMjUgMTQ4Ljc1NzgxMiA3My4wMTU2MjUgQyAxNTAuMDI3MzQ0IDczLjE5NTMxMiAxNTEuMzM5ODQ0IDczLjQ2MDkzOCAxNTIuNjk1MzEyIDczLjgxMjUgWiBNIDE2Ni4yMDcwMzEgODcuNjA5Mzc1IEMgMTY1LjExMzI4MSA4Ny42MDkzNzUgMTY0LjI4OTA2MiA4Ny43OTY4NzUgMTYzLjczODI4MSA4OC4xNzE4NzUgQyAxNjMuMTgzNTk0IDg4LjU0Njg3NSAxNjIuOTEwMTU2IDg5LjA5Mzc1IDE2Mi45MTAxNTYgODkuODEyNSBDIDE2Mi45MTAxNTYgOTAuNDgwNDY5IDE2My4xMjg5MDYgOTEgMTYzLjU2NjQwNiA5MS4zNzUgQyAxNjQuMDExNzE5IDkxLjc1IDE2NC42MzI4MTIgOTEuOTM3NSAxNjUuNDI1NzgxIDkxLjkzNzUgQyAxNjYuNDE0MDYyIDkxLjkzNzUgMTY3LjI0MjE4OCA5MS41ODU5MzggMTY3LjkxMDE1NiA5MC44NzUgQyAxNjguNTg1OTM4IDkwLjE2Nzk2OSAxNjguOTI1NzgxIDg5LjI4MTI1IDE2OC45MjU3ODEgODguMjE4NzUgTCAxNjguOTI1NzgxIDg3LjYwOTM3NSBaIE0gMTc0LjIyMjY1NiA4NS42NDA2MjUgTCAxNzQuMjIyNjU2IDk1IEwgMTY4LjkyNTc4MSA5NSBMIDE2OC45MjU3ODEgOTIuNTYyNSBDIDE2OC4yMjY1NjIgOTMuNTYyNSAxNjcuNDMzNTk0IDk0LjI5Mjk2OSAxNjYuNTUwNzgxIDk0Ljc1IEMgMTY1LjY3NTc4MSA5NS4xOTUzMTIgMTY0LjYwNTQ2OSA5NS40MjE4NzUgMTYzLjM0NzY1NiA5NS40MjE4NzUgQyAxNjEuNjQ4NDM4IDk1LjQyMTg3NSAxNjAuMjY5NTMxIDk0LjkyOTY4OCAxNTkuMjA3MDMxIDkzLjkzNzUgQyAxNTguMTUyMzQ0IDkyLjk0OTIxOSAxNTcuNjI4OTA2IDkxLjY2NDA2MiAxNTcuNjI4OTA2IDkwLjA3ODEyNSBDIDE1Ny42Mjg5MDYgODguMTUyMzQ0IDE1OC4yODkwNjIgODYuNzQyMTg4IDE1OS42MTMyODEgODUuODQzNzUgQyAxNjAuOTMzNTk0IDg0Ljk0OTIxOSAxNjMuMDA3ODEyIDg0LjUgMTY1LjgzMjAzMSA4NC41IEwgMTY4LjkyNTc4MSA4NC41IEwgMTY4LjkyNTc4MSA4NC4wOTM3NSBDIDE2OC45MjU3ODEgODMuMjYxNzE5IDE2OC41OTc2NTYgODIuNjUyMzQ0IDE2Ny45NDE0MDYgODIuMjY1NjI1IEMgMTY3LjI5Mjk2OSA4MS44ODI4MTIgMTY2LjI3NzM0NCA4MS42ODc1IDE2NC44OTQ1MzEgODEuNjg3NSBDIDE2My43Njk1MzEgODEuNjg3NSAxNjIuNzIyNjU2IDgxLjgwNDY4OCAxNjEuNzUzOTA2IDgyLjAzMTI1IEMgMTYwLjc4NTE1NiA4Mi4yNSAxNTkuODgyODEyIDgyLjU4NTkzOCAxNTkuMDUwNzgxIDgzLjAzMTI1IEwgMTU5LjA1MDc4MSA3OS4wMzEyNSBDIDE2MC4xNzU3ODEgNzguNzYxNzE5IDE2MS4zMDQ2ODggNzguNTU4NTk0IDE2Mi40NDE0MDYgNzguNDIxODc1IEMgMTYzLjU3NDIxOSA3OC4yNzczNDQgMTY0LjcwNzAzMSA3OC4yMDMxMjUgMTY1LjgzMjAzMSA3OC4yMDMxMjUgQyAxNjguODAwNzgxIDc4LjIwMzEyNSAxNzAuOTQxNDA2IDc4Ljc4OTA2MiAxNzIuMjUzOTA2IDc5Ljk1MzEyNSBDIDE3My41NjY0MDYgODEuMTIxMDk0IDE3NC4yMjI2NTYgODMuMDE1NjI1IDE3NC4yMjI2NTYgODUuNjQwNjI1IFogTSAxOTUuNTkzNzUgODUuMDE1NjI1IEwgMTk1LjU5Mzc1IDk1IEwgMTkwLjMxMjUgOTUgTCAxOTAuMzEyNSA4Ny4zNTkzNzUgQyAxOTAuMzEyNSA4NS45NDUzMTIgMTkwLjI4MTI1IDg0Ljk2ODc1IDE5MC4yMTg3NSA4NC40Mzc1IEMgMTkwLjE1NjI1IDgzLjg5ODQzOCAxOTAuMDQ2ODc1IDgzLjQ5NjA5NCAxODkuODkwNjI1IDgzLjIzNDM3NSBDIDE4OS42OTE0MDYgODIuODkwNjI1IDE4OS40MTQwNjIgODIuNjI1IDE4OS4wNjI1IDgyLjQzNzUgQyAxODguNzA3MDMxIDgyLjI1IDE4OC4zMDQ2ODggODIuMTU2MjUgMTg3Ljg1OTM3NSA4Mi4xNTYyNSBDIDE4Ni43NjU2MjUgODIuMTU2MjUgMTg1LjkwNjI1IDgyLjU3ODEyNSAxODUuMjgxMjUgODMuNDIxODc1IEMgMTg0LjY1NjI1IDg0LjI2NTYyNSAxODQuMzQzNzUgODUuNDMzNTk0IDE4NC4zNDM3NSA4Ni45MjE4NzUgTCAxODQuMzQzNzUgOTUgTCAxNzkuMDkzNzUgOTUgTCAxNzkuMDkzNzUgNzguNTkzNzUgTCAxODQuMzQzNzUgNzguNTkzNzUgTCAxODQuMzQzNzUgODEgQyAxODUuMTMyODEyIDgwLjA0Mjk2OSAxODUuOTcyNjU2IDc5LjMzOTg0NCAxODYuODU5Mzc1IDc4Ljg5MDYyNSBDIDE4Ny43NDIxODggNzguNDMzNTk0IDE4OC43MjY1NjIgNzguMjAzMTI1IDE4OS44MTI1IDc4LjIwMzEyNSBDIDE5MS42OTUzMTIgNzguMjAzMTI1IDE5My4xMjg5MDYgNzguNzg5MDYyIDE5NC4xMDkzNzUgNzkuOTUzMTI1IEMgMTk1LjA5NzY1NiA4MS4xMDkzNzUgMTk1LjU5Mzc1IDgyLjc5Njg3NSAxOTUuNTkzNzUgODUuMDE1NjI1IFogTSAyMTMuMjc3MzQ0IDc5LjEwOTM3NSBMIDIxMy4yNzczNDQgODMuMDkzNzUgQyAyMTIuMTUyMzQ0IDgyLjYyNSAyMTEuMDYyNSA4Mi4yNzczNDQgMjEwLjAxMTcxOSA4Mi4wNDY4NzUgQyAyMDguOTY4NzUgODEuODA4NTk0IDIwNy45ODQzNzUgODEuNjg3NSAyMDcuMDU4NTk0IDgxLjY4NzUgQyAyMDYuMDU4NTk0IDgxLjY4NzUgMjA1LjMxNjQwNiA4MS44MTI1IDIwNC44Mzk4NDQgODIuMDYyNSBDIDIwNC4zNTkzNzUgODIuMzEyNSAyMDQuMTIxMDk0IDgyLjY5NTMxMiAyMDQuMTIxMDk0IDgzLjIwMzEyNSBDIDIwNC4xMjEwOTQgODMuNjMyODEyIDIwNC4zMDA3ODEgODMuOTYwOTM4IDIwNC42Njc5NjkgODQuMTg3NSBDIDIwNS4wMzEyNSA4NC40MDYyNSAyMDUuNjg3NSA4NC41NzAzMTIgMjA2LjYzNjcxOSA4NC42NzE4NzUgTCAyMDcuNTU4NTk0IDg0Ljc5Njg3NSBDIDIxMC4yNDYwOTQgODUuMTQwNjI1IDIxMi4wNTA3ODEgODUuNzAzMTI1IDIxMi45ODA0NjkgODYuNDg0Mzc1IEMgMjEzLjkwNjI1IDg3LjI2NTYyNSAyMTQuMzcxMDk0IDg4LjQ5NjA5NCAyMTQuMzcxMDk0IDkwLjE3MTg3NSBDIDIxNC4zNzEwOTQgOTEuOTE0MDYyIDIxMy43MjI2NTYgOTMuMjI2NTYyIDIxMi40MzM1OTQgOTQuMTA5Mzc1IEMgMjExLjE0MDYyNSA5NC45ODQzNzUgMjA5LjIxODc1IDk1LjQyMTg3NSAyMDYuNjY3OTY5IDk1LjQyMTg3NSBDIDIwNS41ODIwMzEgOTUuNDIxODc1IDIwNC40NjQ4NDQgOTUuMzMyMDMxIDIwMy4zMDg1OTQgOTUuMTU2MjUgQyAyMDIuMTUyMzQ0IDk0Ljk5MjE4OCAyMDAuOTU3MDMxIDk0Ljc0MjE4OCAxOTkuNzMwNDY5IDk0LjQwNjI1IEwgMTk5LjczMDQ2OSA5MC40MjE4NzUgQyAyMDAuNzgxMjUgOTAuOTIxODc1IDIwMS44NTU0NjkgOTEuMzA0Njg4IDIwMi45NDkyMTkgOTEuNTYyNSBDIDIwNC4wNTA3ODEgOTEuODEyNSAyMDUuMTY3OTY5IDkxLjkzNzUgMjA2LjI5Mjk2OSA5MS45Mzc1IEMgMjA3LjMyNDIxOSA5MS45Mzc1IDIwOC4wOTM3NSA5MS43OTY4NzUgMjA4LjYwNTQ2OSA5MS41MTU2MjUgQyAyMDkuMTI1IDkxLjIzNDM3NSAyMDkuMzg2NzE5IDkwLjgxMjUgMjA5LjM4NjcxOSA5MC4yNSBDIDIwOS4zODY3MTkgODkuNzgxMjUgMjA5LjIwNzAzMSA4OS40MzM1OTQgMjA4Ljg1NTQ2OSA4OS4yMDMxMjUgQyAyMDguNSA4OC45NzY1NjIgMjA3Ljc5Mjk2OSA4OC43OTY4NzUgMjA2LjczMDQ2OSA4OC42NzE4NzUgTCAyMDUuNzkyOTY5IDg4LjU0Njg3NSBDIDIwMy40NTcwMzEgODguMjU3ODEyIDIwMS44MjQyMTkgODcuNzE0ODQ0IDIwMC44ODY3MTkgODYuOTIxODc1IEMgMTk5Ljk0OTIxOSA4Ni4xMzI4MTIgMTk5LjQ4MDQ2OSA4NC45MzM1OTQgMTk5LjQ4MDQ2OSA4My4zMjgxMjUgQyAxOTkuNDgwNDY5IDgxLjU4OTg0NCAyMDAuMDc0MjE5IDgwLjMwNDY4OCAyMDEuMjYxNzE5IDc5LjQ2ODc1IEMgMjAyLjQ1NzAzMSA3OC42MjUgMjA0LjI4NTE1NiA3OC4yMDMxMjUgMjA2Ljc0NjA5NCA3OC4yMDMxMjUgQyAyMDcuNzE0ODQ0IDc4LjIwMzEyNSAyMDguNzMwNDY5IDc4LjI3NzM0NCAyMDkuNzkyOTY5IDc4LjQyMTg3NSBDIDIxMC44NjMyODEgNzguNTcwMzEyIDIxMi4wMjczNDQgNzguNzk2ODc1IDIxMy4yNzczNDQgNzkuMTA5Mzc1IFogTSAyMzcuNzUgODEuNTkzNzUgQyAyMzguNjMyODEyIDgxLjU5Mzc1IDIzOS4zMDQ2ODggODEuNDAyMzQ0IDIzOS43NjU2MjUgODEuMDE1NjI1IEMgMjQwLjIyMjY1NiA4MC42MjEwOTQgMjQwLjQ1MzEyNSA4MC4wNDI5NjkgMjQwLjQ1MzEyNSA3OS4yODEyNSBDIDI0MC40NTMxMjUgNzguNTMxMjUgMjQwLjIyMjY1NiA3Ny45NjA5MzggMjM5Ljc2NTYyNSA3Ny41NjI1IEMgMjM5LjMwNDY4OCA3Ny4xNjc5NjkgMjM4LjYzMjgxMiA3Ni45Njg3NSAyMzcuNzUgNzYuOTY4NzUgTCAyMzQuNjI1IDc2Ljk2ODc1IEwgMjM0LjYyNSA4MS41OTM3NSBaIE0gMjM3LjkzNzUgOTEuMTU2MjUgQyAyMzkuMDcwMzEyIDkxLjE1NjI1IDIzOS45MjU3ODEgOTAuOTE3OTY5IDI0MC41IDkwLjQzNzUgQyAyNDEuMDcwMzEyIDg5Ljk2MDkzOCAyNDEuMzU5Mzc1IDg5LjI0MjE4OCAyNDEuMzU5Mzc1IDg4LjI4MTI1IEMgMjQxLjM1OTM3NSA4Ny4zMzU5MzggMjQxLjA3MDMxMiA4Ni42MjUgMjQwLjUgODYuMTU2MjUgQyAyMzkuOTM3NSA4NS42Nzk2ODggMjM5LjA4MjAzMSA4NS40Mzc1IDIzNy45Mzc1IDg1LjQzNzUgTCAyMzQuNjI1IDg1LjQzNzUgTCAyMzQuNjI1IDkxLjE1NjI1IFogTSAyNDMuMTg3NSA4My4yOTY4NzUgQyAyNDQuMzk0NTMxIDgzLjY1MjM0NCAyNDUuMzI4MTI1IDg0LjMwNDY4OCAyNDUuOTg0Mzc1IDg1LjI1IEMgMjQ2LjY0ODQzOCA4Ni4xOTkyMTkgMjQ2Ljk4NDM3NSA4Ny4zNTkzNzUgMjQ2Ljk4NDM3NSA4OC43MzQzNzUgQyAyNDYuOTg0Mzc1IDkwLjgzOTg0NCAyNDYuMjY5NTMxIDkyLjQxNDA2MiAyNDQuODQzNzUgOTMuNDUzMTI1IEMgMjQzLjQyNTc4MSA5NC40ODQzNzUgMjQxLjI1NzgxMiA5NSAyMzguMzQzNzUgOTUgTCAyMjguOTg0Mzc1IDk1IEwgMjI4Ljk4NDM3NSA3My4xMjUgTCAyMzcuNDUzMTI1IDczLjEyNSBDIDI0MC40OTIxODggNzMuMTI1IDI0Mi42OTE0MDYgNzMuNTg5ODQ0IDI0NC4wNDY4NzUgNzQuNTE1NjI1IEMgMjQ1LjQxMDE1NiA3NS40MzM1OTQgMjQ2LjA5Mzc1IDc2LjkwMjM0NCAyNDYuMDkzNzUgNzguOTIxODc1IEMgMjQ2LjA5Mzc1IDc5Ljk4NDM3NSAyNDUuODQzNzUgODAuODkwNjI1IDI0NS4zNDM3NSA4MS42NDA2MjUgQyAyNDQuODUxNTYyIDgyLjM4MjgxMiAyNDQuMTMyODEyIDgyLjkzMzU5NCAyNDMuMTg3NSA4My4yOTY4NzUgWiBNIDI1OS40Mjk2ODggODEuOTUzMTI1IEMgMjU4LjI2MTcxOSA4MS45NTMxMjUgMjU3LjM3MTA5NCA4Mi4zNzEwOTQgMjU2Ljc1NzgxMiA4My4yMDMxMjUgQyAyNTYuMTUyMzQ0IDg0LjAzOTA2MiAyNTUuODUxNTYyIDg1LjI0MjE4OCAyNTUuODUxNTYyIDg2LjgxMjUgQyAyNTUuODUxNTYyIDg4LjM4NjcxOSAyNTYuMTUyMzQ0IDg5LjU4OTg0NCAyNTYuNzU3ODEyIDkwLjQyMTg3NSBDIDI1Ny4zNzEwOTQgOTEuMjU3ODEyIDI1OC4yNjE3MTkgOTEuNjcxODc1IDI1OS40Mjk2ODggOTEuNjcxODc1IEMgMjYwLjU3NDIxOSA5MS42NzE4NzUgMjYxLjQ0OTIxOSA5MS4yNTc4MTIgMjYyLjA1NDY4OCA5MC40MjE4NzUgQyAyNjIuNjU2MjUgODkuNTg5ODQ0IDI2Mi45NjA5MzggODguMzg2NzE5IDI2Mi45NjA5MzggODYuODEyNSBDIDI2Mi45NjA5MzggODUuMjQyMTg4IDI2Mi42NTYyNSA4NC4wMzkwNjIgMjYyLjA1NDY4OCA4My4yMDMxMjUgQyAyNjEuNDQ5MjE5IDgyLjM3MTA5NCAyNjAuNTc0MjE5IDgxLjk1MzEyNSAyNTkuNDI5Njg4IDgxLjk1MzEyNSBaIE0gMjU5LjQyOTY4OCA3OC4yMDMxMjUgQyAyNjIuMjUgNzguMjAzMTI1IDI2NC40NTMxMjUgNzguOTY0ODQ0IDI2Ni4wMzkwNjIgODAuNDg0Mzc1IEMgMjY3LjYzMjgxMiA4Mi4wMDc4MTIgMjY4LjQyOTY4OCA4NC4xMTcxODggMjY4LjQyOTY4OCA4Ni44MTI1IEMgMjY4LjQyOTY4OCA4OS41MTE3MTkgMjY3LjYzMjgxMiA5MS42MjEwOTQgMjY2LjAzOTA2MiA5My4xNDA2MjUgQyAyNjQuNDUzMTI1IDk0LjY2NDA2MiAyNjIuMjUgOTUuNDIxODc1IDI1OS40Mjk2ODggOTUuNDIxODc1IEMgMjU2LjU5Mzc1IDk1LjQyMTg3NSAyNTQuMzgyODEyIDk0LjY2NDA2MiAyNTIuNzg5MDYyIDkzLjE0MDYyNSBDIDI1MS4xOTUzMTIgOTEuNjIxMDk0IDI1MC4zOTg0MzggODkuNTExNzE5IDI1MC4zOTg0MzggODYuODEyNSBDIDI1MC4zOTg0MzggODQuMTE3MTg4IDI1MS4xOTUzMTIgODIuMDA3ODEyIDI1Mi43ODkwNjIgODAuNDg0Mzc1IEMgMjU0LjM4MjgxMiA3OC45NjQ4NDQgMjU2LjU5Mzc1IDc4LjIwMzEyNSAyNTkuNDI5Njg4IDc4LjIwMzEyNSBaIE0gMjcyLjIyNjU2MiA3Mi4yMDMxMjUgTCAyNzcuNDc2NTYyIDcyLjIwMzEyNSBMIDI3Ny40NzY1NjIgOTUgTCAyNzIuMjI2NTYyIDk1IFogTSAyOTMuNjgzNTk0IDgxIEwgMjkzLjY4MzU5NCA3Mi4yMDMxMjUgTCAyOTguOTQ5MjE5IDcyLjIwMzEyNSBMIDI5OC45NDkyMTkgOTUgTCAyOTMuNjgzNTk0IDk1IEwgMjkzLjY4MzU5NCA5Mi42MjUgQyAyOTIuOTUzMTI1IDkzLjU5Mzc1IDI5Mi4xNTIzNDQgOTQuMzA0Njg4IDI5MS4yNzczNDQgOTQuNzUgQyAyOTAuNDEwMTU2IDk1LjE5NTMxMiAyODkuNDEwMTU2IDk1LjQyMTg3NSAyODguMjc3MzQ0IDk1LjQyMTg3NSBDIDI4Ni4yNTM5MDYgOTUuNDIxODc1IDI4NC41OTM3NSA5NC42MjEwOTQgMjgzLjI5Mjk2OSA5My4wMTU2MjUgQyAyODEuOTg4MjgxIDkxLjQxNDA2MiAyODEuMzM5ODQ0IDg5LjM0Mzc1IDI4MS4zMzk4NDQgODYuODEyNSBDIDI4MS4zMzk4NDQgODQuMjgxMjUgMjgxLjk4ODI4MSA4Mi4yMTQ4NDQgMjgzLjI5Mjk2OSA4MC42MDkzNzUgQyAyODQuNTkzNzUgNzkuMDA3ODEyIDI4Ni4yNTM5MDYgNzguMjAzMTI1IDI4OC4yNzczNDQgNzguMjAzMTI1IEMgMjg5LjQwMjM0NCA3OC4yMDMxMjUgMjkwLjQwMjM0NCA3OC40MzM1OTQgMjkxLjI3NzM0NCA3OC44OTA2MjUgQyAyOTIuMTUyMzQ0IDc5LjMzOTg0NCAyOTIuOTUzMTI1IDgwLjA0Mjk2OSAyOTMuNjgzNTk0IDgxIFogTSAyOTAuMjE0ODQ0IDkxLjYwOTM3NSBDIDI5MS4zMzk4NDQgOTEuNjA5Mzc1IDI5Mi4xOTkyMTkgOTEuMjAzMTI1IDI5Mi43OTI5NjkgOTAuMzkwNjI1IEMgMjkzLjM4NjcxOSA4OS41NzAzMTIgMjkzLjY4MzU5NCA4OC4zNzUgMjkzLjY4MzU5NCA4Ni44MTI1IEMgMjkzLjY4MzU5NCA4NS4yNSAyOTMuMzg2NzE5IDg0LjA1ODU5NCAyOTIuNzkyOTY5IDgzLjIzNDM3NSBDIDI5Mi4xOTkyMTkgODIuNDE0MDYyIDI5MS4zMzk4NDQgODIgMjkwLjIxNDg0NCA4MiBDIDI4OS4xMDkzNzUgODIgMjg4LjI2MTcxOSA4Mi40MTQwNjIgMjg3LjY2Nzk2OSA4My4yMzQzNzUgQyAyODcuMDc0MjE5IDg0LjA1ODU5NCAyODYuNzc3MzQ0IDg1LjI1IDI4Ni43NzczNDQgODYuODEyNSBDIDI4Ni43NzczNDQgODguMzc1IDI4Ny4wNzQyMTkgODkuNTcwMzEyIDI4Ny42Njc5NjkgOTAuMzkwNjI1IEMgMjg4LjI2MTcxOSA5MS4yMDMxMjUgMjg5LjEwOTM3NSA5MS42MDkzNzUgMjkwLjIxNDg0NCA5MS42MDkzNzUgWiBNIDUgNjcuMTUyMzQ0ICIvPgo8L3N2Zz4K"); 20 | }) 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /nodejs/test/chart-line.js: -------------------------------------------------------------------------------- 1 | let { registerFont, createCanvas } = require('canvas'); 2 | let { CategoryScale, Chart, LinearScale, LineController, LineElement, PointElement } = require('chart.js'); 3 | var assert = require('assert'); 4 | 5 | describe('Chart', function () { 6 | describe('#drawLineGraph', function () { 7 | it('should draw a line graph', function () { 8 | Chart.register([ 9 | CategoryScale, 10 | LineController, 11 | LineElement, 12 | LinearScale, 13 | PointElement 14 | ]); 15 | 16 | const canvas = createCanvas(400, 300); 17 | const chart = new Chart( 18 | canvas, // TypeScript needs "as any" here 19 | { 20 | type: 'line', 21 | data: { 22 | labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], 23 | datasets: [{ 24 | label: '# of Votes', 25 | data: [12, 19, 3, 5, 2, 3], 26 | borderColor: 'red' 27 | }] 28 | } 29 | } 30 | ); 31 | const dataURL = canvas.toDataURL(); 32 | // console.log(dataURL); 33 | chart.destroy(); 34 | }); 35 | }) 36 | }); -------------------------------------------------------------------------------- /nodejs/test/fabric-rectangle.js: -------------------------------------------------------------------------------- 1 | let fabric = require('fabric/node'); 2 | var assert = require('assert'); 3 | 4 | describe('Fabric', function() { 5 | describe('#drawRectangle', function() { 6 | it('should draw a red rectangle', function() { 7 | const canvas = new fabric.Canvas(null, { width: 100, height: 100 }); 8 | const rect = new fabric.Rect({ width: 20, height: 50, fill: '#ff0000' }); 9 | const text = new fabric.Text('fabric.js', { fill: 'blue', fontSize: 24 }); 10 | canvas.add(rect, text); 11 | canvas.renderAll(); 12 | // console.log(canvas.toDataURL()); 13 | assert.strictEqual(canvas.toDataURL(), 'data:image/png;base64,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'); 14 | }); 15 | }) 16 | }); -------------------------------------------------------------------------------- /nodejs/test/konva-circle.js: -------------------------------------------------------------------------------- 1 | let Konva = require('konva'); 2 | var assert = require('assert'); 3 | const semver = require('semver'); 4 | 5 | describe('Konva', function () { 6 | describe('#drawCircle', function () { 7 | it('should draw a red circle', function () { 8 | const stage = new Konva.Stage({ 9 | width: 500, 10 | height: 500 11 | }); 12 | // then create layer 13 | var layer = new Konva.Layer(); 14 | 15 | // create our shape 16 | var circle = new Konva.Circle({ 17 | x: stage.width() / 2, 18 | y: stage.height() / 2, 19 | radius: 70, 20 | fill: 'red', 21 | stroke: 'black', 22 | strokeWidth: 4 23 | }); 24 | 25 | // add the shape to the layer 26 | layer.add(circle); 27 | 28 | // add the layer to the stage 29 | stage.add(layer); 30 | 31 | // draw the image 32 | layer.draw(); 33 | 34 | if (semver.lt(process.version, '20.0.0')) { 35 | assert.strictEqual(stage.toDataURL({pixelRatio: 1}), 'data:image/png;base64,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'); 36 | } else { 37 | assert.strictEqual(stage.toDataURL({pixelRatio: 1}), 'data:image/png;base64,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'); 38 | } 39 | }); 40 | }) 41 | }); -------------------------------------------------------------------------------- /package-sam.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion : '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Resources: 4 | NodeCanvasLayer: 5 | Type: AWS::Serverless::LayerVersion 6 | Properties: 7 | LayerName: canvas-nodejs 8 | Description: canvas@ 9 | ContentUri: s3:///canvas-nodejs_v.zip 10 | CompatibleRuntimes: 11 | - nodejs 12 | RetentionPolicy: Retain 13 | LicenseInfo: MIT 14 | 15 | Outputs: 16 | LayerVersion: 17 | Description: Layer ARN Reference 18 | Value: !Ref NodeCanvasLayer 19 | --------------------------------------------------------------------------------