diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e8f682b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,90 @@ +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +/logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# Nuxt generate +dist + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +# IDE / Editor +.idea + +# Service worker +sw.* + +# macOS +.DS_Store + +# Vim swap files +*.swp diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f96c7ed --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM node:18 AS build-stage + +WORKDIR /app + +COPY package*.json ./ + +RUN npm ci + +COPY . . + +ENV NODE_OPTIONS=--openssl-legacy-provider +RUN npm run generate + +FROM nginx:1.27.0-alpine-slim AS production-stage + +COPY --from=build-stage /app/dist /usr/share/nginx/html + +COPY nginx/default.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md index 34b5e97..9606165 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ It has following benefits 4. As the link contains data whomever you share link with can get data too 5. Also note that the data is put with hash in url so server can not read the data -[Here is a link to sample diff view](https://diffviewer.vercel.app/v1/diff#H4sIAAAAAAAAA819XXPbxpbtX0n55b7EKAEkJeo8WbIdJbGVuCxPUmdOTk01QZCEBQIMAIqWp-a_Dyn3WhvoDQIt2Z66T7bYjQ0SvbC_P_772TxdLJ7941__Ovnx2b_--6_8hx_-epbO_3r2jx-e_fvHfz0Pf3wWHv6z_3c0jg7_2-_78cu2RVpW9X_lZp0ctv_1DBe8TYvcXvPLOsnmxl72Fy7MTOd1H1aFvewmMWtcVWK52C2LYm533Lo0k7VJsza9rCbBtPKmePICy_HG5IldXRefU7shsx9loBfggjyp7VpRLt0vuEzyeVK2v-Fv-H4Xy8Tuz7H2fJbmxi7PE_er37vk081_mfm8TKpKbrHfF43OA7s1xLUTuza1C5NghKUTu3Ta_GnAwIm95LBxHIRAw_lfz_7K_-fHH1rgieyFZxM_zLwp06ou9kj8ctmVvSop7Qel-sFHQHSNR_reXoC_Y_v3CjsNQJpkWeJS74DT7RqkluVTaIcE1h51ywzI2p9avUorF0vlFrSLtReU7PZ3za_2AMo9kIDYew2zr4TYYWM0BhJw6PgxhNx5EI3sIjafBhHQNg3Ox7yZxhKIgEJ4Djj6gAo_8Ob2Xp3yEQy9XNlrrmNTbQxO22B9vuNj7AWMpVLhAGOsgP4Q9YiQmW0_f14kCZjVpswKcBhCBijk0a_x8ngxo8t0aff_hLePGMJ91yZz10qXtgsTggD8Buc4DabgDkE4JlTAudyfF2LzKT7ZI8iFXBd-xnbP-bkfbH7e5uRDSdF8LQ7vrvv754X7AI6g6hKC43ob37pUTDVvP9rQvqMDTGk1A9Xlek82cUmMXjTh1Tiuit_fgELtfqnRi73YAxta4eukWM5wIYBnAucDIrEEtHp52QX-GGA4Z5bYKIRsOydKopMgmgBhpzjxxjIQMz7lV-lmOQfIgS1NBiBzvQU-3iV4jGSkxld2vbI0Ll0KaRWDYywWSVm7j5cn4QOZNZnIrDyQO36z4fuMyaA2ZYoPa3y2KKEzAY_xCqyN8Mvu7VpRmhr7g73U62VWP-FRpeqFXBPQX9hW4_aDvIoIo9I7IofCJ_YDaDhKvQqwAn53JizM4W3Uu84c4j2YjHDx6QAm_-Bz-GlrL8mwhmdeFwoxDjaBSXPnPucfrqFXlNCEeapprLhiBxLv7PULu3d-9F5rn1tNCMaEP88ubfgu2pVsrxm4vGFZ4AvFn_vY1NXD_xfZ9nAu_er3-WkLHhBvTbhM3a8BrSgcnzWXQqu4N689jYLzIcg04RWOPE24Kzyn3wq8MzOsUZ0URjTE2P60V7wvRB2-x2Idr0w5dyl1wGW5uz_sdVgQ-RbQc7gHOO6p8Kdqi8e4S29TyKEvGtVhA_Tt1ASe1psoTDRXDpsA6gM-fPkNZBFYR9gywB4MrqldOjtzl8IR-UqH5o3rIh8VG5tH5yd-QPkAVfZ1hmdGRfZTnSiGe8xqS7PKErqxl9SiG-Fkh-20AyphSlEMkXkk0LDIByul8xic2dkLQmN_i3vq0naZMrEG9c3MXYIR-AmnckyqXRE4h8v-JoLsdVvyNaJrGFoh1WQwFCrbPG3oQiOX04BNUCuHDi0AO3OXPPQpugycbzQAMrCPa_ewshlOBRonlVNvW8-UBRXz-Pe1S4ceoGrlUuxgUTu7ea1MPqOAg7t63HIqbMyA58yAjpSiMFmm4I4wMIj0LAma9wmtBYD3JPyCTh-2R6fVVYfPyi59kY_qh5kSioc3ZwzHgC8lHfFLsTZRQpTsMpyQlYbRaR_vC3Gj8SkuGcDlexzUS_dFxXPIlCYDnuDLGS_yOd75N0miyO1MWVMkVi7NDoSWRghqM7RFLrkjLz1_0QWaBwM0WSewlrdz6O-AyMb-XSa0N2uHUof31BOI7wraDhd2v4cB2WBDFJJnMBjFH4GlCdhbGLpfOBK1SuFvRK444U_pgR4FeDSgoF1TuqYVHnLZeg9DK4E9sPUB8F0p13i6nuHZZoVS8xq4glw8KHEZ1G2iowSdg15AJoZrPmIFC_cF-Dj5FrjVbLsOmj_zi-oPnnVAq_qWXZi5wiv7WwHHaMsaTZxHKEJ5K8LX2zM6GQfU5iPhQ5SqtBSDsULQl_2HK6d9zi1CCMzL7qUD3o-VXZsyxqN-c58lQ2Yhrvs1yYG6axNfuU8tjenqVA9Nq25gR2tc_lGom3jpQXwGPrUBf8WPwg-iQP47gJsjUX4OYCoPkvnW_d7dMvGAJj4JF9cUe1qBPSr36IKYKCeW6y2YCLvCcYOhaWMBHN3FYB_ISJ6uW08J-Z8F3plL95ng7HIVyjtmI5j4wl7zKx4jpUps0jkoVsXGJ57zeW1iiLrZR4q6TpJCMSYXW6WQ8pttmdwVLW39ACJcMuzMSgA4IidLhhHSfNObej7PnCsjKtww69zAHrV5NzgoRCikyKt8-FHLkmjQHQDOxTyBfnxj1mv6EYdAcrNKynsq0FdFlhUbftvjWAC75-G3yCybZOYEwKKOuQEBvearBk1decPhZgq2CvuP9zNQMA1xlQemQn-UoIY2v8bNCU4tavGgB6Hk8pFJEI19XAxEEbnXABR-Sqlm7201exH1A_gGwKarYwi55lnHfwBOOL8foMALxwbZ5UrLwg4AQQXGWVOEmeatHg6fN--9WUKYpatlEEPX21Z1mZjmTQ44qu_cr9iJI7v9QVjZC2ib6chwty70GPUnBKIYc3FfkTMoOVHUdrQ3nVFgIWf0wbciiU2x1ws83Gt07qkUvWoksrRMpa6HcMz1mcaIA78jeuHr8hFT8517VCS4OUpwIUksYFHpZxhVSs1hCHNQUjVMrkvg-Ik2F7AwFXeU5kSieODwzpQZxtyUUe_pQ2mKTjx1lyvg_TW9OcZ9qmT6g4LpJahdM-QiZo9NVGoqtxQ-Xp7xuDR7IgCBOmjIB_EU4dWm431JxJQJ5NOmEP8ov9gslzCd8nRuadX76zwN3bn5UJggo1N_jieiACVKZZ7QmjqjChSRfbjGk-sGbYO2wYA8fJ1H2dlQFp3dDn84fTR3kAVZUtUtCzb0N_3f8PG-Jn_Jqf2st3mtQmBdGXa3UNKq5rcMrSP0ONEV0bat8JXh_VklS6jS-KWzxAAfzERRL5FdSHHxIASv8EbqpBYG-LyhF7p2lPCn6KibHX-r1DylpQVgWr4IfLgzbzzx9LTf2AteuU93BvZFVdyNw_nGAH8p3YdNJkOlLsFhmtyH_VVwu8_TpxFPJTUPrM9BYCWxLDI9yeFrsT0e2eqR2v13SrsaMW9OpVQBVLT-gvAUu7k5YqZDy-IMrcE5gEHshXrnZpgOxReLNeTE7_WK7za8Or7s7qXdf5FqX89sMJlvv6swwD19mzrdTih9JKDM2nxm3qjDrGGzHM_gsxZi6JvDR9U-FI8LntU3zf0kY2JOAn8EmE4YBmBSJw2fecD1JvMLh3NfvrBZbJ5i-1AOKFOst-6PpKnV-tUPgtUXV-8OT2TnPHAJT0I6mrnOs-lKGN2Ay5qZS2t_m6SL3q34ozZ2tTbFzAyq9FbtMuX9cHYCnTlUkGj2Q6uhd9tlDgKMaMSg3Mk5H0fPYTMbYiiL_IJPPIVmvp1TFAwd4pXJ8WDfHoPEcpn2nSDl5JKKStZHI-OpgaORQp3ScQirDnJkUKOBf_QxttmDWjuo8J61NJLmeYvuwnRubcozmDHxcRFRZtDOP3Lu0OBazv4HzgYWWyUZhLwZ9B2aEm4c5Q-CcrpJXBHUB4sl3167OXbplgszTHpNtFTb8o76CytSICFn2i67ZSrUIHiuIQ7etZxsBwC3cizDL-rxkIQAWSa-nVGHZWaKMtNcBw8jZSdqpxsEYWmKXzFBxLjuxDPV6Q1-_WXz8XwxVQG3tFIx-KM1BgwXvStNrfKQGDLyEhyxUJttvMjlUlqQLilX9sqKC6GZm47eCNgD1YW79BGyyM_D_eRIPk5amJBKcqILGysRmB2QQ-23lWDSRf20z8_YVokOPNOz3uCmNqVA6H2hspbT2DdG9rMDUbGOd9bVc-Blda8sI69Zmf1VdqNkWRYIsc4MUFZLCtL95hCUtzuKFx-BDIbpM-_0SqR4H5LjXDivWc6A3GEx74A8f-M9dCNnDZ1FQQDYOA8m2k15Gj0NO7wdfdQTTx_1P-Gsw5EXPAsypYWB3BnUhRAjeM2nxwdrVLYQX1olDDrgxBC9vSZ50h02ZFvzgiCY0f4WIK5NCdPpoKInLmVI3UfrVuBV3jxKRdynzoKwKjopR5SMrnU0wWYtO2FYQXh2ZruRS0F--obyLyAklG6kcsKS9Gio6Jg78lCpt13g3X11v2YmEE_RA2MARDx3CdBlcqD09wvWoaStH3G41CxbWUwP_BfWGPP7oCcqE_L27xfzpJozUS9g3A9v46Nz23yVeckBiQKwrZMWWhrYCLR7SMoNIMDCIDwN-W17uBYDN76xlbcJjOafSpP76kyvcL7X8VWRzZXWn9dlQp1kqEL8cIrrmIedSba3w3L6yZdSdDIz9EGvWJwZd_hyvBAAsRd2OqhLr7A_X_ZWVtjDl3GjEWQ0pzT1JE8NnzBgAkYVRF4aEdB34hn7gOh_udKHwGTXKvXN8b40GWJjyKAg82Je_6LozXPEuS-ZyL0AidmevAEdoVJBUVoViIYwFpLkrahHS29ZLHZFeavSYwezSTyTt79lotrhldf9BRhoP2uD6wGIdDUAOE6SUns3cGNXxr3l4Uy1nHjWh_8JQ_ut2ZbKOzrHs4h9cXYxKw2LTS6TvP7sVSe-Y1Ga3c1Sqwa5FrVatKCH2hSTsgq44fd7IuPBy3fxzSsrw4YHUeSPynwNTxnGdQNmEC89WhDRN_ZxKLN0auzbqeI9ZcDPplwbZUkNRCAQzpVXDppHjue9I0ugw9fLYCthd62qr7vJVmWPJJ9aOUeHJaQ5bnTim02aDb0z-eHHE8i16qF8M9yaNjxQQMeRVMSNVHSVzSnOgqk4soWhAY4-gILz0htQ13t7GJB648bzc28NOllvcMiXjA5IQxKecrFeD6nS-123syJnUgrP3OUjwhk21creYv_xXaNcCZBE9GUpEY1NQliCnZBnPWficCvQH1pNoMmn-fCUyFyw0KUfhu3yuwWe1N94HbCSQiF7BB4jFpBM2yGSL7q3Ep7nFJ4KuNJCJfCqKqFmH4WeLs73xfZO5JcDxY_e-hZM5bd7PYZMhb5wUzO-0QPAWaZSoljb1ktz94JuAfuRpPxvaZgGtNykkimt8FNxKqIlJo1KE6-KgKe5Cx64DfNFdFlbhIOkAMRXPXO-utuEQJwMdIiOhio2yU9DcVY8Mo-bYq9mgv1KOt0M4OktNt4zvWmNQ6W5hvguY7a9uhYEGr5M9rRbfJL4_qzYwlGQpXfeOf9Px4fbIMf1EHXUrgnraRFpXHyu_ObhBG6AaOTVnYleA19u8wqsBq26jLguXW4_xHLeF7CP3uDFxlIp-XJrL30csCTjIW3ln-ykfQ_Dj15HKvSHLk52MS-UVzvBJ4Po-T_L88BGJmqHU10H2cTS81ByfCINqnNqWrq_k_3gtPVB6JfqRlHHGONw0MVe8kfhPq_MV-m6YaMwUyoXDdsWDFW-PShD1QpqzJ1KbQShUhpbfAbG7guVQQA5VaUqDChSVYfqHqmrNzrv5OSUycEvhY-HWRntPAIFYkwhJxK9WulMLRlIRIb9LQlGuJVnlO4ldYcPzRfuAS_QGBOIDpZr-HZIeZOky1XG0P7LovTwX4I4423QSunyblA9PDDpbWly8DTFhbIFf6lr5cdr7_zuLpPuiShhaq12NeED1afCDeWqYrmxm4bWkb_m5UCQRgMDEbsrI5WrMKSKbEgHwiXMzniT78_UXkTd9b5K-_BCPZkhs9sBKmEIBrNMa2ykIbSRutyZ-_jE-E9VD6j-_NcjedgukaMwYdy9W7SEYlMRLrrev5USG3Y4mKg_8za98GDpE4vjBvjMZTGDZL9QrUHwImbuQzmW2lbMZ-BFl5lhf0CqvWxY6xMvgfpLdQYnd6Dcytl_kFqzImNHB-JKWlpiTdU3UX7FeL2Jh4YV1l-Yfe1TQTvhu6uriqaaDYgswlEqbiMwYkrBYGfKpsZ05hs_s_tVOCNfVlQ71IngndXdtrqavj2Iid2cIYH_d5HX2yJXGnlXXQh4h9075_c70AtH4C0wwmtyFmYu8UvHzt60vfVwQqMXCf2a1HWXLOvnuaWeDUa--IMe3I7DKgwNbe3HZtHRmYKQcJG2n6cBJpVi3Ysg-rE9Q2z_TFbbOR_I5X1pcl9X9htTQmdUKc_0VzIU79M26f5WSM5U6vNxmuGY_R7cKiLVkhmsM4iVWzNZFPuDrYPcr4fItaX09YVr7bYNBxCNWypOCKdflzDTXWwCCKuTIAynfa1wqQ4NoOSd3f-r-yPrMv3MNFVmOwym2CK96Pd4VSelYlBVRfauHd8duNlAUn7UlIiVrhupu4TSPPLQE55t1vKOBnEg7V1o9p2blUbjiVKMqZaekL_QrmZ33CayGqCQJu94ZcLeMD-30wifeoY-fjZ8WV6qSP-S_Tz8I_14NT8USpVMKhZz-6SrrdZJQgwpoQRKGdXTUFpN4rKNuSdbkhy32ttF-C0sbfEFSgFsoGNiODlBS9jIp3bb9fWCgDrREAjYkAEQUA7_lG-xK93z3BcRV2mWpTmxpBJjmf8BPs6QlMSzunBC4bFs32D2lBuEZ5BjaWvX81BcCTWgRGOugKFVGqgzXgX8Hd1E7CePNMwnEklVkmwvgtqewobEatddt2Tb2HUA9WINFt9o5OlyvsAvfXlova_wZnLfZu5ItEYypJTal6nk1xRM4znaNqIrixFYinUfdT_qYaNh5KqASnSXMutIsvsPTeOZ6MiJJoOsSdqo2UskbeaL5mzXOcXk5Mcn9A85hpszZ6HR_4opQ9oJQFtcehuRIpDkE-KXNF3fDH-g5dqwZbIR7yFLM3wVcPTkRrUaeQ0Og-ZUxRZGq0ynqnSJPZYcK7eyH_Hw_AWUMqbNZi0S4PhNVpYR1EYpXOCXO3Z5OwrPoQECYp5DPVIdaaYsPuOSSEkabaocaUpMnA-pSqGYeOOzIWeQveBPk9ELxwcT37Irui9wqAL96Z4ueE69Vucsx-wBoBkAtNuZWjUiYVxvC4lO-4yCJ5RGkYviE76wSjnZsedNvUW1vrcm_m1z26KRFDiHLU_zgRHp0jVgbwrxOSEfCoSn9Jr7LLv1dBi9kjZEN6uEisf9EGI-lFs6lK5arR9apm6ep3lR1z6-oXldslcXPwPCvO8Qzhr2GoDwiT2Ri2WbQPPx7zESsJ3FR9Ud7rtpTUpFOh0HbPc6CUKmdKhOIpIPexqE53Rz-4QnGOaIRr6TuEyMZ35dUFwNAuV1BkX3JjEckCV-Sbt4p_T2nsFJ65Z-83CaKjYKwsvSkHYoTRrDbT4PA5zUoknv4aUP7NCHYwjwcQUqH1yjE97REARPW_t3VLU9qziCM5_GQypJ1jv7C8_plwrvGYcq-IoY9mo3G2WCz2bPL4udVz-9cpfMZrMCVSLpuoMcVY55R1hzbec9tNCz_-WJdwgBV1189ZQHefMnqj1Cux6riQMZj2ZXZMiRq700gOfTk2VCCeQrPjjm4Xd9qGDQCPHw1dxmvtFvKLQXey1HtdmZp-uEuRRDzTwPUGUYkYFNXO1JPEzY7jym6wmMJmaWjtSkACFlQlfRcLm9vebbtT8DJ5HoeKs2Puxq2qCS5WmrK6OLNT9nPulgE-Zr-KaD_ZPVXfjFUnRsV-rUuxbjEtReusSOdntW0FbsoSt0McON1vHX3ylciPVkP2KwFQtZsjR10rCGAEz3bn5D13wknCu86BvU89VcDPJSbY-f0F-sK3-Ye2hXeic3MPOQmB0Ka5RpxXbnr9cmp_4mPR04BcETcGSRP7uvMuuI9g-5z6WI_ZvaufWql1S4PJ5vmDF1ce2dW3iJB_OIVgwP7OfU9fNFk46anvFZcK7PW9K7fJKSmdgaEVZDAXP8qJdFOW8dduNVUxXNg0yGk2PcF7pe0TYv7zl5uDftNOMox1gZu0fIhdJH0cQYG4R8CilbKJPDhNnD17dbFoV3x1cEIR7XnO5RJTtuy_HzgJor2wa5zIN-vrAj7n7GBNSRjxtZEp0jT3XoveTovJTMT5WlM-TPu6Fc4BU4F5Zn4dznLT3kwe71YCUsgLF7q29yx1D6JVZJUhmwyp2yZR49ERvSCO-VxtYjqp5bPRPCrlowKEYT7aSRQhxly50y7uATFpXI23SAWb2XpJeVlOVV9K0Ohtc_4FRf2yvojHM53ArUy3nf1CClyiSPoRhKG8RtJbk3dhXYVD0UWEtNNxWffI1iZ8-5HP1xCjuiKsTgquY7jN-JmVU-jIw19Sc68Z3jPBqNzglU8CudacaZVIByL9JkIJFvPKxkl_dX2yxmbd1gn5jXfEHxWsvcDPsBwbxYpIl72D3221z5eOiAftKtQmmRiEOtVDsYlr2xHTGYGrwIBE5t2EjELtHO_CYj1FI6yRuhtJOnFG2MpmzZ6na4HokjYhyctqeUPvwSIo85sz4aOGv4pwPAg5sIjYYlGrZO6poZAXnqq4pdsWD0pu7of0Y6ZZ-43C1JZV71kwmlhWO9S-sNG0-uK93WVYZU-bItaldK72KPQqqBtFm2UqDqCxFypclhfoe96rShtoPvEBgcKCp91MmtKE69PATMsB17ciu4TFTQPWfInNmDHj1BgBclyqqKqW0dA5K7RmrPDO1FpWqR2M40yIXS1HFRpvvzXiSUrZuZKmXWzYbtXk-1yu5upRI9scKeXVlPJO3MnQHawASNcx3OcPUySTmKmMbah6BTKTTzTK5_jdf7rYmVDPAeRAUYrralbiRV35tqxREKuY-WzlEIWfwYkqH0cDxMX4-pa8913NWuoLtjR7XGgILuM_Ra1GrpkqcAMZ5QKJ2cD6YejgI2c-lFApOnzzx5CTrd_0LrrZI4wVD9H6SXaZ7U4aAyNZ58SW3Bq5O93QtFbPc1NwrZqnF9L9lOrIbP2FomcJduZya_DRrGm5dW81TH0STav-9SikE2QTColvSthYZ2cx5EkY_Fz6R9b9GDUZlvk-ZJPDDiNedTZUZlSDjAQT5HKY1ixezB2XrghBXndu_sEXRD6aFY3d5v8OUNU2Y9x1R_2z4Z7QbTTTmDEzoNVAR9TMX1rGEy0Wnkk8xFTmX3jpy7DumxeOneF-rBg-nWTN0cDJ6yVithFwKmotu_mQHsFtnwvj45hruda4bP9rcsH3-T8G9tXa22exW-5Pjyez6Qed5SbLr0Gr-ghbCc7zM8g2BiOurelFI-IjqtR9retx9I088gCr0kGTiT3UtPtx8e_7nFeV7cJcoxicQK7-zpaxOj1Ez1VWC2wCpVz7MrUKaHaAFcqq1CB-lQGi1Wq2LzHOVCQCx-dhUAqtL_jCXuvakeD0k-fhJr6qaLNljTCaDdquMKG9HYxjSMMYe8-jQ5oN8xHGqk-IbMv2TKX6p7-h0r8IIg_6NgMwkJjBXMJNPcvXHurEG_ZXO6uw5yHdTCSk2KrhK2jxH4lMU64cRx02Fte9ZzPWVqQuMNVVPEVEBCAgztZMCmuiNzNN2rmRIfRV4MRNzNnhlfv-5_GRuQQSwwPlAa41ujfpXU7GLxs6kqr7DXxyXVTPABVbPXpBVK88NdWtJmjo373Dj50OUHgIfX0Mxvn6bhlwkWoi15c4dSgImI0I29Hm8o1gseYm3qmdr-xl7wS8U8qIIqYknV2Leu4hqs54ZKkwxcWqV55aaQ92LrtlVAH3a0qm7RlNqsPJQeiAvmLOP0aScls6JgA3HNfzy9fU-d2kIjZnLiVo1Cmz0_Dgv7QRS4nzR9wGxHP8R5mqyMhYaePcIQS_igC3Mh1U0lr94gF7LX7HWX1xy2K_V31ZrDYbSd3-WcWe7vYy-AOFmr9NM4uUsz0gulA-Jqu0zm6oeZdp1XKNEKj9Kbr4-QkhUxjB51dN9tdIJu-2WaPAowIkn6gIPe1ge8iUPIrTUcymu323818d9b90HAe_LkAD32v8UFwpXod_lsl_bG03ypNCwd3vpY1SZ_jKWVw2kX7tp9WZuScq_mFRwhsp3R28M8eAIOP8W7k88FG2x2BVHt0lfVeanEIZm_wd4_wtHI45THACte08UkScRX1N2s8NJd5GytRVl30Iupr3jiCqzqBn6jxlwo9mY49FGxy7VHcxbGHWAZ-9IOPzVEXsXZ9lJTgdX1xuQy04zcxmPAFDDeLr8J_fv8HISKDlaye4KCD6dNquxq4ElGX0qkYgA9XVe7zTuGVG7z9zbZmyc4h3c0Y3pbsjT0Hp7mYpGUbpFUr75t9yLZWeYeLFrlEQ9IYVUeKIf3uu5mfn9w7OBU8CnOs1GJE6Re9thAsOpxKfcnzKAYBVFHq3EwAcibk0Z33lPUMDdYUy9LoUbGsRmeEc0_3FNFsCdL2IFCjSr56Cu-0MXjfVHtySl-cJeyAX2vRd94_-2uO3zE7ER9hxbZ8DPhM640Y0rEZ_e58NaIegs0HhXalBE6qmGqjRSEqBBtaUoyqbIns_XcJ7MVfIpuaE8g_YLX7l3DiOGb7YmT6yKP2YLwapWWJqN_pUfybJYqYrluUmqSiaQFYb1KTA2JANYjijVL_diDvmls-RZ6EhL8ZmwhcQhn2tWnDg87HO84UvKI9TW6TBiPQXA13TMZmVHnU77D6AfLiIds9HTNORIXLXNh_8FtZfK5ekOOIOSPZC4OHjVgSYYQJvVQFOsAy5Umcdf8dl80zFshS6pRSBjdN8bidowv3G3MMukwsogHuxT4VYI-1lZXMUydNcNWPWPNdM4ZB1epgbSz7MJZn7oClkV9xdO8-kCOfGOy1rjRw-pWT2c_lm3D5Czl618ZaNVApmpO2Jehyr0s6a2qr7lHJA0KqeQqr1EK1BzpVnDyzd2Q36CdaqiynnW6KTgZduj6Hk4onKrGdYPFqQ_MS1JDPM0uYuelqVdsapgkjxZvCL6_ZIcD6pRr0zrjUOJKSW_CIMsA4vhxRKORzF-VIp2PqbGVHk1DbsORUv__9AUXJ1HbHDtw0qm0BZLKZWb7KSbHzGiveQRnnPvrq2PDckJdljhWOOyqaD3z8EedP3nUMVTkzHZ4by_CY10ODhR7EHAMIaxKo5jEnrqbvxGNJTwGtsbwiPC1dMPGMt9IlfYyvEBJdRp0eQ6jZSdKf1LNLZyI-0krVZDZg72woZCllB0yzcwy34JHX5b-lae_LxYpz_R9sZvBL3nUL9ZlY9m9M1Wx3KR-nHYk_QzNZiMQi0en1EB8eoXZ6x6Z0RWye26kZwC4kwdhV3XE0iVD2CVi2-w0-Env6YPQiJQGTv_n7Rp51m90nzC88VlR176weA1FQGUvg2Gv16bLD9bVpYnKu90cDxCLpDvhuoDHOma_L8m-B-tS81E4kKOiMCrKpZfOcqSv96PYCSt7G9EpPctUOsWPg5HCDD2-Ux9FhQmJ7MIxJGdwKB_YLKMcVElYlmrWG2HifOqpV_r5fMa80HiITnQmXl57kVsOu1GwiG-pXPszD56-C6WHLBsXEb7uX8oT2k84qOBcOXkj5yKqI9Pjgybc6cxukvogZhqq0Mgza-s1GMrDHOTm0w_RM8uDw7zEO3qRr1vZfQ9v9j0TgXxa8CTgVq2uHodv40U6miL1ODEl_YGZuDDr51LFTBazdNna03N6mh2bvk9qIAPoltaYSKJuwiyxQEz7hpNoryjbDWePARd5nKcNf5UUJVtruIpu5Tvq5potHaEa8vyZ46FqbzqABQ1XYvxudd9xutG55Jrq5MY4LXRjMXbJwA_esjrrqU0EHf5Alwqn87nglSCDtIXCIUYshmAa2TRgCpc3LMKG9TTU_IIuLPd5q742FWJF3lNOkSb_Z1LVG-Xfx1m0-0EOAIbT_HaJa04_4g6R6ZtnUuUJ2wkCbEfxcZn61jW40kCPiQjdHk-BdiJH2i1IxhENhrobutN0yE_8itWPb3nix7PKj0FAMjp_dWnQU1vOBxWbw_aPVGDp7NLzIW7FAUwlR7oDwoKBd5fWtEqhaPbEwGeSOuyVji4R7maWzomwskdU2UlTd6aGsv2oAovUPLhYcRvpkEZA5aSXu0jqqqe75UOxyyVGYK_BKSTKlXssZFns6He4uV_j9PCSeqnFYBOrirnnOE18DQkTyCxagih-scEyU2t0ZWbaJBX6FmQ-fvxju6tF2OzVjpWeaAFtH12qwErv0KvUjrV90cgTEW_Sz5wV8aswlkEIlMUWitqfRjnui1aoqEtz60oI3TSIftwp06Rg3P0I8Uh6De5lxr3ShfWESEtgnjK9wiNRpsVFvjZK-XD-ysnGygO7MGFKX2uE9vNQPDSBrVegAtOUcq7DrxdDDGFOPBNm3m5jYSrrtXdK-nX8S4YzfeWeDd_qzUY6nfbBJ1vHKcmt9PzOLnpRIp44pjUcDq_C9TIc6TsFj3ptcfdHPGbkmuRiSXkvZzoGoeY1dMOGukVKFOnFXhDJdk8QXZs8Z0b6RbXynvMJbv1TK504FPWSiTCm1CLumHu3oY0sHkM4WkjsiAGo_F61nShYS-eZiP59umOzONdulFLN8OzMzfyMGpkRWBpPA_qKz31MIeym19cPHn-yZaRi6xAZqbf0wrN8aSoVIy45U-0wOsSnafYOvro49qYXLaU9AIwa1pfTqeRRiBnESttqouen_ff1GLbHtsbTYKLqWOhklbiO_aAthFqarcQYfDphcxAjoGT_Hpjaictfrsw2Bzt-vWaHvsHG2H-u0upWdNli-1n587rmlO_Y8Q8-NTo1hFqDWCStAGOzDkyMg-2yd2GgzQK_GZ0UIIez_nYi5HB2o0iaoEvgRyVq4pQoZyQNHOepam_pmaFI8oEJrfUTz1DRL_HKgAvfpKr1BhuJeRfdvj1MFALU_lCx-QJGjHYMaxO6ukvK3OABqzjPi6q5cnjZYWlJvSdxyKNn_VNZbODIUimALxaMXOdJS7EJG-3EZZiRlybzfSQUaDRak9DmPtqaTSpnwKno1AuDFgTDHwdHmIcNw4y39gwe_GxYYHuwve1Fg3zpXbLHLZTRV2k1K4ud-6C6Qo-b5nX1vHVhJA3_wlPYqcuiWMoUBvHkBzN1MH1RRHr0T74qH3zC6Xc6GZzpv9KsGNxA8RRdiqlygEe9fIbuYm_HislX9wzxZN4z8f4TLzAcvnxnZnYc0YPisCsKnw41NU15M_OlF0kHPrC11kjPlroBRtIeANv8IMuSuE7vmpD6LvWVoTtmioMe-H7zE7KHyP3E1TMk0Ci91wI_DYYmdujJGi7LdC_-cSY3Zpg1HgstgsROnc5tKu3v_bIXZgBBVfmSi6TbXj4zAQjsFFjIXGRyp5-r5R0UIfDStlrjqdWIV2QvA8KAw8gAF9tjjwzkgJMgPD-xXfUGJIQrIOCbHchouqDel3OwqXp3fYPMaAdymWRxd_glFPN2hgW3apvMG4Kkz2hmBMhNVPgeXyCSvnyssZ0nrCM2uZSOuzeHcQWU1N-PM9H0AbIaFZMMCOoCyc7WJGKcNQXexN3iE4tkr4HQd-jDRcbctEtTsiq23UPJA5bv6daxFzBgxFrHwfl3Ycf0zjIZphdJH757GWirpo9Lq73Yy-hCbdhPCb1FHmY22MqUw8XUeCKl-ETMm5q69d1qpsj5mSRe9UKBvYh9W6y9LeZ0v79uNW54zmd2kP6Jr-LzpxFwvf5Us3i518O7M4wmthpE7v9ukIiKZvq2Xc9NZfDQperRflBIrVzu2yb422Xj8oChhZwEKhCgu7-66VNEkpt72WiozvmvPhiRhtm-OvCqYAHXb8oxInVCWlIfS8BLGK1-v53r-dz5it3IfVSbeib08tKTYCQN-Yp5XuB6pmAaaSWbp5z5uJoXLRYTitOYwg0Mxysk-fR0X-JkehowetRw81Ja2SVVCxVKXZJt-zhoPpHm2BM6KANA-q208KGHo_LlLL_ZCzD2w1Ap4BjNlKVB7SasAwCas6HI-km0o785uor1WnPJv0g7k6SAKPfJ3FOjoa0l7PjRCXl4Zt_IgagnDCngjUZH25SwtZIFbFOdDgbHOoSN8bBOpfkwENn8_caU5rnKgmSAylf1uQBkJEheExfV5_jz_e0xih0ApD6sumJjxfMmUdnQivYH-smuz2ZxQAWIR4XjBsdSvZi_n2vIgUhj2KLq8ifwkSokhwdPJwGQoVwBD3D697N__3v_EFfVWzNLsmf_2IugRVEmP_zHZn4o3d4_Clm6WOwlGVb-538B0bFXSqzhAAA) +[Here is a link to sample diff view](https://diffviewer.vercel.app/v2/diff#H4sIAAAAAAAAA61dXZPUuJL9KwQv-3LHUZLr8z6pu2GAaXqGoIkh5u5sbMi2ylaXbRX-6KL6xv3vq5SrGWDIYy_FA_PBKaASSamTmSdT_35aFu3Tfz797z_rJ0_-Tf948uTPpzb78-k_n4h_PP7_1jZt97-1rgz9_J9PX1tX__n0E1zqL9B3hWvcIXcu--wzptK2HPCy-_SBmUr3ujZlVJvusw_nps5MM3z6V1f_lNhaN8fPPmD3_6uzrDFtO3xILBZRPIvW80jIzZ9P6WP_-cc3TJKsSdeNbTu33dIfyxl241yh628btasCKJQ3Ky9N1PTn2CPnm0hsIhkvIzkD9sTYHs3bclXo7GA4Y9IBlSrpHx62xmRR6irGoEv7-H_88qzjSJBJC7IHLdCcNehlX28bkznepMvS6DbTpfm2UUXyiMeqcg-2LHXkmpyx6mLUqJVfn1kkF_GISQvWpJu-afSRN-iZX8PUleW37amyEzxX-8bW3bax_iuXR7BUP_tf_sVfz99sEv4AiUiuIhGvgE1L1qbfdVkik8yTG1vb1H3bpvvMVAFeKLPXUe7uGUtehP_elr3N0L4T62gWiaWMNjGwZsVa80InieWteX_s_ElpGD-XH07wUu3bPjIZ5xImnCBvwnztF8Wvz2YNTFmzprwr9McOejdbtp3RjDFddYJXKvM_eaxc5y8BsNeGFfrQG-wZlt5rb6K5d9yrObBrw9r13pSJNcDR6caVtmacwiE9wWu117n_d279BjaRPe86ms-iVVgwuQRGiRlr1VvTJwbcsRe1_-MOuukK_W3DGv3XJzaqK0xlts5_ww5ctW9ceRz35Svvyxdz8hExWjHB04cbbVtIIBpbJUfG63UB1KrSR5eW5CzO3oTeGu8l5jLCq8WThxvdpMBN_GLqurFpwVh0d4ITZdMPwJhpW8-78NUiCqu0kcgcnjv8yzW6AI5Cpxdtqm3GGPRQ6VQPH0hVYZP-nBtJ0B0bb8gmKQSyh6cOF5kpgYe4LUxz5ByEbgc0U9suBRfSBB8uZ2tPFebRxpsyh0eHpww_W1NmLVyb3633ad82ZutX5p5go2yRn8npPP9ZLSOxHuMKgicLz_wVAhbmvU137bctyQ6EbZU3AZgxzaF5P72mu5WMQTRBAJ7Q6BTdQZ7mUdDDbbI8_fSBXDXm3jRJrUfu19GTI-fLiPg2cQa423jO8NrcIz99XRpbt1Vfdw9MpLf76xOF6lvduUwjgjqN1kkhKc7z15CMltA0njbc6qQB4dF7f1OWhrmD2sOA2sdgj3ZhsTvjLMVxtPTnaOljCYmctuQZwztXVeAOunJVwoV7XRrAO6Ur_RA2XdRz1kwLXxci2syIImyQy5Y8RbimswDiiDf0hx0MFxvt9o_4ThX7c-_UpbfGu24fF8WIe0ueIFyUFvmHF7pmN5vOA1iq0nuEyrTAmPGYdR5ojljMRpip5MnBC6trcHBudbP1X5Txc-2AVqrtm3vjg4h6Z5A_uBkhB0vvBDzXFqt1tEGOQPLk4NpvEsS0rwofFTTM4uzSAa1VYvPSJcaz6-huf9Z1tFhEfo2Ivy3RtSp5knDb6cbbBDbcS308sHFrWwyoU52tj3tIsMf528wfG7EMQfiIQTxP-MNfQ8icy1LvTMms0TEZ0L3KnP_ZutLNznRnHSPvDfzlKhaUpIPHiGcMF2SCsSAeDxm8fmt2jF_YPeIfVGbazNxHaX3WxltJymRFdBktkFGILxxA6sf_3XeNYShQmZ3gRpkkcAT-DpoW1Ul_ijytE_MohmvEc4SfLfJ0l7osdPVta7ZJAFvVGk_kDIgbpgV1dIDm8xAICRg6xDxBeG_rDNyoF54PVZZhCAc9oN0p-eP_AVdo3C3EfmmWnqB6gwRanpjnCG8NcAlXugH8oElPcK_SCqXmpm01Ch02xN3ikSA1BjkE1-ToHro21d57ZjYbvHvE7ymTZdq9aVr3k4_k69xE2wbaN0q4Kd8TU0bBGypRjBTzxOGt6-8tSmnl_qQw4V6jA3hQOv3Q28Z0hW3pV57lxSmEkLNF5P0ePlM8eaAqCm_R62OdOeZEpWUAPyqduP7M20iEhFz4F3LcMc8YnnlSh3zdW5ebhjMlawb0OKVaNMnfrXzYKmbhTIklPE88Z_AkqEaViNuCzXW3LWEPPhwySel4PjfNOSyjlfcMwm8zZAjPFK5sY8sS1L2ujc0LNn5IdydYzBT5gtL__ujcTMzbe4PoQppvIlT7inmu8EI3dscbdaO7Y2sZ7pNXAyqE6vemrs-rrYiFv1QXxE5H_ADPFC5dAosQL1yWuLL7tjVJPqBCKorwvj8cWqypliKpmLJEVeM5TxJe-y3SZijp80wfMi4c8iSOQBGrru86l9qu03wpZeLxkaFsTEZJ5N3mPFH4wxR99sXX-PoE6cZvoyNTSjnuTrCYTyykjIWtVGYVK0qRCIEyCnOeLrzRXWMfLOKnrm0dw0_3SQDFgjJY_pvpDOUVJqQa_fHxjG4ZR2t0guY8O3jp_wTvp4BDMKblbqCiCqBYqrYkun22d_MbTvi7Zx1toFiBJwY3xkdnLVidF96n2zqnIIEhdPlfnxAr1brcoULKpBCPtAp-34WMMArF5zxTuMgazxXAbfTSNY1N2IKrLh5xsVb7wnUu6VMcj09cs3hFNWS_bqSbgZ6CJw0vKbpBvs_1LScvyQIoNspzhpxKyuel6sTSe3Pv--J5tEYB0pxnDpcm3YGU8DNX66JnzEmyARVabd3H2hzOcxAxuTry5P5UreCZ4hnDM5vuwOK8a3qg_sm6EyySz7P2CRcYTUyZLEIRQlA2aAP3HM8drnWKMt3Py4rVnBnCRKpEX2ciysxZB2guhuXxxHuFLqUFUC24DIRD702S_HTpWNVZc_AfSAgX2SSqOuEQUdlYrkJea40CiQXPHt4VJtF9CejDM5d53sYqZ7ITLIyqvUP_fn7n_XZIm-CE1oInDX98mfP9W0Kr6Vxl-m-bcUxOsNgqv0xAOjfRXxNVFX7PzUhPAg3iWcMbksCRkg-4hUIzbHXfeUjkwV-fVwsnmeYi5LMELN8teMLw2vrvjTLclPNgDk6ZDKgo_h_5kYnSmA3VkOlaXaGIYsEThrcjodFtZQ7-VDAuoR1QYVXrKZ7WgHRPzArHC-J1lMlaIoe94EnCW5cWBu85k-mCSz12ARR3qm87z7yrqDtP5OiNCbLNGSWzkEWgGNFksFz0vE3ddmu_-Iv9nNOZR1zsVGbuPUHsvLM4NwtEvk7Eoe46Q1HFgqcM721Zma6DkXljbMsYdsgHVJSqO9gOl8ImSlKpFLYI9WQJb1meMNwQM4N1Cd22TAW2SgZUVGrQC4-k6yYeKjH35hAX8mbNkQdc8uTheWNQPsh2R9Ji3X_bLlM94qIOcujUdA7lhSau1tp7dgpuiT-gPbjk-cOtbQ0KKt57_8YJttpDAIVTaenZb6LrHfCAE24qT1Yl6VLXsY8CkT08iXhnqwo59EvD5FG6xGixV-3uuB-_mMZWhnKq_iitiNsh8rDkycP7BtVb3rsmY5Oqh8OAig8qO9ZZ3QI6NEUZSNaQsnukfLTk-cMf_Ug6NX1tuIacY6XT0qOiUW3h9j_tG5D0nhQYrUmBOgv9EXNoEM8brnUDtWeUE0-Z_PBuN6CiVd60xrPWzOqzAglPvRcLUm7CvMmSJw2_-N8K1StfeM7GBUZ3eQBFpw6e2yF3PZZ49PEdeQCi3VC4sOS5wjXlb4Ah3lGTKIbN1e2qTx8Qvdr64DdxbnfW4khBQgxJFbARZ8AzheeVQXrAF_7_2Tjc5AMq7lXR52aQmaB8ycQIiWg3yQLX_naFeeIlTxaeef4MVuu1qRntpndv9YM4qLTw59CZmpojzlol760H1aZEHmHFE4Tbom_oVEMhXbO1HVNnafMBFR_9tmtJ9LjX9TnqM0-7Z94hRLAuseKZwS_abwF_naM-vWeaehI5x5ANqDg-5rRGii2jfGdG7VKz0HgoYMJkhboh7i0IZd94mGEIfkE8Jh7UvC009nQTcj8nbSDdrDAqX_EU4ZVDVXFPxFOOIdgqgHJGJSPdlT4kOlNItxAhH0zkDTHRFZA6jjC3301mdmyWYXd_gqVQRx__ukPQmZy1Rp6GSgrzNvNojS7WFc8TfKxd9TVKazWm-Cp_9wUpPcFSqvo4prCd6LgFEbn1wFCRVTxd8F_aQPFZ31QkIGTihiR5xGUc8lvt3p0djw_5rRlptlbQLJ48PDP1EbgGT1FrmzHOwV9IAZVzVfn1snvY6jpBCy2jsFCSunLQ7briWcONzuu-4g36bbu1JbdIlRtQuVB6vy_R7TqtGrH2QSqJoYkNwdPE04WXfbVtLDhNz1OXfNucwnhILif0Vk8UnXnOLdehbARzj2ueMTxD_a6XVF9lNU3JgMqV2lLk3Zy7OKdtFq2iNWILa54tPM9Qe4duyiNnjEkHVK5VadvuJ09Vvec-1yJPuCnMo2sJKQLXPFF4YVyDkt433s0y5by8IkxuVGb88lhHtb3jeXdRUNyH62iJYog1zxYumsy2dyAtrI8l0_iuO8KkVn07UmudkuQRoYpHS4M72tY8V3jmGlSVfEc8nNOiZt2AykQddeEcSYXZfMIIyabsm2cHYraMFoj2rAFDcAfcS-QOpmFUGN0-gDJVe1NH1n337pIxmRFyIsgKnhFc24cHRN7eNK7PSnfPHJjd_hGXmfJb7OianUFebWRdfFgqFhGFCnhZeC7wukctUTfpq_LecBmRskptgKU5Na1peGimJa0o17uMVmOp-TXiA3WNFumivPdxDaf40QMqxwqs47HCasiMSkpcI0vAWAXdZMCQn03DiQAPW8JkrvYJSouOG0EqpTVtsQWyYcNf_1ee2NdQXPG-sO2O42fpYUBloVJdRTrl-x0mqkXWpDUnz7xCN8yG5wCv0kInDtCz10Rb0sbtv22SLR9xadU2QxNWRteHyiKbGTVCSUQ2N_z9P6K2emNSdtxSsQ-gvFPUNHt2US7oXjxtphYo2N-w4W__d7oujiBk-5c1JKFg7pmHAZU7v9ea3NFcH5N29v5c_Qt1fFKQPcP6lw3PBC4bm1tYQ73y1z1bwk_SAZWlqhOUhB8jAoHVDKJzlM3ZAO1iTzNRwBK91sfEcck2XQ6orNSHXtdd6n_tmQkq4mendDykBRueFlz4fYLKWG_Nl8rnzw1qCJO1J2k--ORLpaMMjTo8qXzlbxx0b24AF3CZu_9yKtTXnlp_1ab7ORs4BFC6QXrpfyc0OGFKYxCpFYkNUPIdOjc0b8lVukUNTyTPNDXbQ9glj7jcK5fVbkeV-9ruLD9cbloouho6a0i8CMODDSgr-L9xEI7-qruCDa3rAMoPk2O3abcrCZvj0NAloPxXzHjG8KvD9K3uXPuQPhyZumOtP31ANv5Y-a_8kV-saXfTLIy-mfmz9bhUf9b_8_QfTxt2bmMM2gZeVabMUPu-0dQfzbCHdkBnP2R-XmhmXS-iUGqAQxtB9vfFVzz0b31rQarFJRGaEyyU_2akmTs7J7IKWmBK9MB5BAJwvNvdEcZFut3rhuNFbfWIS7VvSNh4DgOP1yHFM5cR7NyfA0dBOZ4c2UPqf86x59WAxkr739UzvtqmZ9fxN9Fy41krHCXFb7g3pkM5xSYU5DrO9-2TTx-Yq2CQa3Rnz1Sfel8eyzCJScbIn0swYuHnvuxw29e9YXedjyQCulCd21OKMUofznJ61Ge8CV0q0QIO_QIN1b-6JjENkG2_JY7NBLF1E8ClOvj7dpCPnJ3P9oyCgnLvIiRuMwQauTJHzrvjfZ1pA7hSmQ_-EvfxBwgZveteDRwJhrMSMPIbAwfn3aS_Vbbl5uZV3gSPrj3rs_Vu2HZnGkW0aLEODYd4QM4cSH2u-vIeFR6ujbnnckDk7jy4UW3XZ9aFMUZnamO8A6cAg_LacKwHGF9040MFVI28KrS_a5gwo0oHVKs7XSZ9dfasZ6qqztdhvCYk53MwfuX6CIf-3Oj0RcP1DewqneYeTSYJTcd6djcRKdL9SYIlOwEyw5e6Bso_Ep65PeMVkrsBTdW-b8y9K_tz-o9JxrgYpjHJOZyUBbq8bjUWKbzwjplLb7V5ALO_OrzOHSIjaBQBuTkSLkGWOgfjFcIM2h5VutInV7rPWQVgWqXpgJvxtoFJp2gzD-NKBF1HMAiMQdj-aodntDmuWdLuCduq3D5UPvQ_j_-Q1CI0f45UIuWMP0PPK-LCiKe6mh2YZaoA5mrvSHLhA9pzpRabQT4bjwn_JBhKe2tKf-nDEUbPD7ZmLqKW-m7agtRLYbCZj2VPU3--u2Dk18gvEfYMMegkeqYrq4HTftWYUtfMGmV2QO2kRZpQnJBRSBaPZO5isOd-8xFniTr4LywbSDhN2J3K6_5M6XnIqpJsREAvgMre_uooUVr10mh2Do5OArhTnXaJRp5g4sMJ0YbibzFS-RIgp3DRZw3wBK9NnnMaOb9pCCyVbpGkedK6-EsnTKSl4T7fuTIvGuo9QfmeK703JWdNng5opR5slVi0OFOzI8slPdIBx2gK0GB86Vk-kpb6YLrj7tBkP6D1lDGnE-Rj3pUtJDk12OEggdjqrfN_hE0Bebv035hbnSYJoFN3zlU_QG9FTYTzTbSgFBacuQQaCS9dbbdwFPJzm7GCuMQEcK-SvqX5Ce3BGHSMpuWFKY9AqUZPs-EgBQko9pXu0FiIY_WVLP1z6pYN6AeVFjbVuesam_RQSz9lZtFsfcqOjE3IAhfQz42uISn1XDv7aoN-MU08zU8faEbmiY8FDlIOnQ5UqoQzQmc837kqaOQKDB10s3VcmJrmA9qqwh1osOb24JodIglj3fpDPTn8gP2rAgwfeK395VqjA3Vp6u6BrYwlA9r5iOi8NIJ3d-S-F9Ec0YQ5uFZf6qZC9O1W1_mBc3ZFO6C9Mh91hcWyE1pRZiHwIcGPgDEdMOfa1jXwCd4TFq6qODVWcoJ_bMdQMIiO0UiqBzw84rfTHWwY8ofC1jkTNSTlCT4onaSU6Yn0WbXKxZouJNLOwpkXAiUUOtMWsOhfJZlhCyrlCf6oSqzGmFZ7DWOlwrQYCu_g-ylgzoquQdb02rPxih2yshvQozqYpPYE5NyXvUi7EGZoLmGgCvKlv6O6ww2NsmYScfdVAB_U0flfZeHgrwm2-CVZUYPnSD47BozunTU0zhPwbccVV7vUQ2KmMpOZtDov6bsJN6kIsR1y1wJQuReUswJKs-va5gVzl-a7AAqhctsVfcILZ8eSBnKYPbLB0zPnYBLbRWVL4KbDbHC2kVgnj7iQ6mDb9PsTvcPQvziihVnBtDVoC3pBKnE0w-fZf13UXe9qbgB_pgdYxMrUuc7yHzB5bb2mafUregcGLxLP3S6PnopCqYzmnk9KEsLEXO11lxZn9ziFJyTjYfwsns0IUm-_6Nrcgyvnt7ToTFO6mnFsd-7TB8RC2bozKPE2KVwIoTc1D2J-DWT0V2P0-p1jI7u0I0ws_SId9_pcYzzF8aszo8w1nHcMjKFp2xq_KaCbmgbGcfO2k0dcrPwKtZ3OG43eIpp2lsK-W9NLI3AGfwzmvF8FAQi6gtyuZacFpwMq1urenxXXILnFtIwcSRNmNIpfxjgjBybe6KbzBBk4iNdUHSk5EleVJ5imM9qkNDRN_ABfIpqgEpxHcZiLNdJtF4MJje912RWoVvxed5Xrc8b3HQ4nWGhVGdP16KmbKYosak-ZUWV1AaM8QOZuSVAF4iJ6Pqa2teu4N2La_K9PiMSHe2E825kzuMXycUARsTtYJAJlPO80UBro1pAP4BpwqvYEi1Rt_c-PPm46Oq8xTHomceAcVSAkmLHyqrWZA7vvRu85PYmtCBOZquDTphO1JOQfNhGlVKEtaOP9Vpp6h4op_qSxfRFOD6gwqk0tJVyoXpSe3zJNod58eBkCvm86B9HezbHp4PNRV56pc7suJYxGNk5ze1Or4uuhV2Iz9sIpeEjqeaXrHj7M-JKmGRrmAjbFgIqcItnqvFkR5Bt84LehwAk_6APyj56YG1jPuyGxKjtFJq1OsCjUod86lLAbrU_607Qgefd6ZBYykgRSTzHSr9_W7pCxioV2QIVVhxjUJka7PmbhuTIfBeJHJkGb8VvXwifLnmf02hWT0WrMgIo7ldKbdGUJvN00QjSj1E-IMuZQpw443rO-TC1irzc6ZycwZVUAxe5HzdQMHm42DxEG9HIx6Jegt0DR2Jjbjqp3THyRtQMqypH7aHxS9WIRukAXY52tAryicOWSBFhyoDYB9twMqKhG-icnRX2LQY5OOWE44kKiybQ6hQ8tFX1D87yY9q8yfcRFrbLKPZxdp6QiZXinbB1jcXAMZkm9Km0LjHqvbcdrSezhBAunqqOPttJzu_RCH5jYEEf9zi332tgSTgWl6N0w-boyGVCxV9qh6HxiEDtbhn23wp27c-DgvM_Gc7EuTeW_dJYzvKdJHnHxQbVFT85hCwfGjHoG0gXPSKwJo1iQ5Lq4NyV02temsIyD0zvCRKP87wkih2kyjNAu4GO9BZRhgFLrtUW07XeXGzYTtLsfUNGO3z6TXs5dh5CVUsQSDpYTIBt07UzdaPSU10vdtuwY_iKAolMpiuqmvXxFs2b9D_LZME_HJ0uGoA60UtJNytE22wZQ9KqvUbJ70rNKsyAoCb2hcNisABnvd0MXJWLVOn1-b0vu-c-u8u454OLekwPUGTrGRamiH1Koiwhm8AXoePhliFogr-50jXzbXfvpA-Kgij4Zm8M2jZaKaE7hD92t37nzLmrboSGat4UGz2Dp9gSLj6GPN4fjSSbMlgsjDOldbTitbA7G_71B0dwzw3Xu7jMPieMPGQ0cuPU66OrhEEMBJlD_7vd13dk71Cbu79u6KzTrt--bvz4hHv6S0J0tWCDiI8Ye0o1nvHVvvvJmXycc_b2py4zJNu7zEyxnU2bRTuz0mocpH5JWDfIfULUszc7fKRlIzr3U9G4Sd5iKAZXiM7Ujm0SdsA_XsxAW0dvA39tzc6tLC2bl3dLIKE6N3gZQShXuJ3DLTmDbQYKxidaUCoYVPtDWeqW74ognL1y5vunYNxPS9ATLWN1ZPdJ8PKkqFtE0zdnI6zAx8BMvTelgWPSW5IvftqdoCJNz1epygmMYDfIoQ0KqdBIMw0UCr3n5mAelTd-6Q9JzU4ySZkDlQhVpvJydnV4MISsps9DiCDC8NTTR4TEsVaW_-iaf09T0EZdLlTba5m3omfzu3Bw9I7cJRTC4QihqfecaVKnU1b5lK7BdeoLlSplyr-EBGhNnSEnyxkC9oc9GDcfhwXZIVS_qynETDXc6gHKtjG66glpaQWg06UlGKqksR17ugd25tm1RKa_hRoFWuYfkRvlf36NHC6cNMKIyFwmEY9hoAx56uGxg39B703Z7T2wYR3A4wVI_qpnO89NxPOgwlqNMG-XkUB7hF9Ow_TblXQBlMqqXmcbg6NQsQhc4FP9IQOBe6qNBid-jP-bsy5_tgNKARpgunabOnIUZMnEYawqLxGioO1qaMMaIcdB3YYxRIzNFg5m22x8w1ow6i2mOkRh5h2MO3lh7qf21gSRnZr933FyzIhtQSX2rcN7cWPA9dHAEDw2fuRIz0KnWFkib8LMtHfO-kN4SJreqPqLywpShX9RMPLzCM3L-way5K9fATOKVDuMeLKcDTNNPH5C5ovxKeA0zrb_3ulnTuyIkP4fT8-YzPjp4XlWomfjW9Q_MYHDTEiaLUbHphGdKZXiqXc5nEXylNJ7xvvmWRv-jxfndNDVjSntPmLR-SajJodJUOTHIr00QA8fhOQcSA8NwJwZPjtEIXdQAZVviywxPywZU3v3Ah1eXwyhNEUaZwR3He-qLEj9jVZYHxz2ZpJMTLHefZhyf0-1JFIdmfC0ieIAE6vf-mvv_rexIAgXm7mnbAZWlOhQusjVHPCfeo8Ta4jAfdAP3HJps2Cd4edJCVwk7uZlW6PETspr2LOGUlZoJiniCqnEBE3KoyUbjN5QuMq7WkGgPyVqRFd_tq8PsFGrDhUl5ELY9rywclvD8I1vfNoYw6VSt23EN3GjP6mx4e5l-wCgHuIFfzVfvaHydJugzvy2Yc1M3Ayr39PR8W2QOBdQT6AFlrWneCD2YjYWKc94kf_1DbUjXWd0xk-jT6gTLD94km5nwFA8IRUf7HlahYiJirOCJgT23utE_wQYBEtJyW649BFA2KklS2PU97e6ZbcKFul5EnwbRDiMZy6J9TW7n6T-f_kZDc2tdPnnn9_swrfERuirobetsQP7zf73yDBOBowAA) ## TODO/Upcoming features @@ -77,3 +77,29 @@ $ npm run start # generate static project $ npm run generate ``` + +## Self Host +This guide provides detailed instructions on how to self-host the offline-diff-viewer application using Docker and Docker Compose. Self-hosting allows you to run the application on your own server, providing you with full control over its environment and configuration. + +### Building and Running the Docker Container +1. Build the Docker Image +```bash +$ docker build -t offline-diff-viewer . +``` +2. Run the Docker Container via docker run command +```bash +$ docker run -d \ + --name offline-diff-viewer \ + -p 3000:80 \ + --security-opt no-new-privileges:true \ + -v /var/log/nginx:/var/log/nginx \ + --restart unless-stopped \ + -e NODE_ENV=production \ + -e NODE_OPTIONS=--openssl-legacy-provider \ + offline-diff-viewer +``` + +### Running the Container with Docker Compose +```bash +$ docker compose up -d --build +``` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5b40a46 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +services: + offline-diff-viewer: + build: + context: . + dockerfile: Dockerfile + container_name: offline-diff-viewer + ports: + - "3000:80" + security_opt: + - no-new-privileges:true + volumes: + - /var/log/nginx + restart: unless-stopped + environment: + - NODE_ENV=production + - NODE_OPTIONS=--openssl-legacy-provider diff --git a/nginx/default.conf b/nginx/default.conf new file mode 100644 index 0000000..8a2c62f --- /dev/null +++ b/nginx/default.conf @@ -0,0 +1,15 @@ +server { + listen 80; + server_name offline-diff-viewer.local; + + location / { + charset utf-8; + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +}