| <!doctype html> |
| <html lang="en" dir="ltr" class="blog-wrapper blog-post-page plugin-blog plugin-id-default" data-has-hydrated="false"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="generator" content="Docusaurus v3.1.1"> |
| <title data-rh="true">The Packaging Process for Answer Plugins | Answer</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://answer.apache.org/blog/why-the-answer-plugin-system-was-designed-this-way"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" property="og:locale:alternate" content="zh_CN"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docusaurus_tag" content="default"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docsearch:docusaurus_tag" content="default"><meta data-rh="true" name="keywords" content="Free, Open-source, Q&A Platform, Knowledge Sharing Platform, Community Forum, Knowledge Base, Developer Hub, Support Center"><meta data-rh="true" property="og:site_name" content="Answer"><meta data-rh="true" property="og:type" content="article"><meta data-rh="true" property="og:title" content="The Packaging Process for Answer Plugins | Answer"><meta data-rh="true" name="description" content="Let's discuss the design and implementation of the plugin system for Answer, and know why we design this way."><meta data-rh="true" property="og:description" content="Let's discuss the design and implementation of the plugin system for Answer, and know why we design this way."><meta data-rh="true" property="og:image" content="https://answer.apache.org/assets/images/2023-07-22-cover@4x-adfc331ff0caa372bd48d7c798155678.png"><meta data-rh="true" name="twitter:image" content="https://answer.apache.org/assets/images/2023-07-22-cover@4x-adfc331ff0caa372bd48d7c798155678.png"><meta data-rh="true" property="article:published_time" content="2023-07-22T00:00:00.000Z"><meta data-rh="true" property="article:author" content="https://github.com/LinkinStars"><link data-rh="true" rel="icon" href="/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://answer.apache.org/blog/why-the-answer-plugin-system-was-designed-this-way"><link data-rh="true" rel="alternate" href="https://answer.apache.org/blog/why-the-answer-plugin-system-was-designed-this-way" hreflang="en"><link data-rh="true" rel="alternate" href="https://answer.apache.org/zh-CN/blog/why-the-answer-plugin-system-was-designed-this-way" hreflang="zh-CN"><link data-rh="true" rel="alternate" href="https://answer.apache.org/blog/why-the-answer-plugin-system-was-designed-this-way" hreflang="x-default"><script data-rh="true">var _paq=window._paq=window._paq||[];_paq.push(["setDoNotTrack",!0]),_paq.push(["disableCookies"]),_paq.push(["trackPageView"]),_paq.push(["enableLinkTracking"]),function(){var a="https://analytics.apache.org/";_paq.push(["setTrackerUrl",a+"matomo.php"]),_paq.push(["setSiteId","75"]);var e=document,p=e.createElement("script"),t=e.getElementsByTagName("script")[0];p.async=!0,p.src=a+"matomo.js",t.parentNode.insertBefore(p,t)}()</script><link rel="search" type="application/opensearchdescription+xml" title="Apache Answer" href="/opensearch.xml"> |
| <link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="Apache Answer RSS Feed"> |
| <link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Apache Answer Atom Feed"> |
| |
| |
| |
| <link rel="stylesheet" href="/fonts/fonts.css"><link rel="stylesheet" href="/assets/css/styles.dafb0c64.css"> |
| <script src="/assets/js/runtime~main.5c009e72.js" defer="defer"></script> |
| <script src="/assets/js/main.7aa7d472.js" defer="defer"></script> |
| </head> |
| <body class="navigation-with-keyboard"> |
| <script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return localStorage.getItem("theme")}catch(t){}}();t(null!==e?e:"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_D8pK" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbar--primary"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.svg" alt="Answer Logo" class="themedImage_Pn4p themedImage--light_PnYV"><img src="/img/logo.svg" alt="Answer Logo" class="themedImage_Pn4p themedImage--dark_eYgw"></div></a><a class="navbar__item navbar__link" href="/docs">Docs<!-- --></a><a class="navbar__item navbar__link" href="/plugins">Plugins<!-- --></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/blog">Blog<!-- --></a><a class="navbar__item navbar__link" href="/download">Download<!-- --></a><div class="navbar__item dropdown dropdown--hoverable"><a class="navbar__link" aria-haspopup="true" aria-expanded="false" role="button" href="/community/support">Community<!-- --></a><ul class="dropdown__menu"><li><a class="dropdown__link" href="/community/support">Support<!-- --></a></li><li><a href="https://meta.answer.dev" target="_blank" rel="noopener noreferrer" class="dropdown__link">Q&A Community<!-- --></a></li><li><a class="dropdown__link" href="/community/team">Team<!-- --></a></li><li><a class="dropdown__link" href="/community/security">Security<!-- --></a></li><li><a class="dropdown__link" href="/community/security-model">Security Model<!-- --></a></li><li><a class="dropdown__link" href="/community/contributing">Contributing<!-- --></a></li><li><a href="https://github.com/apache/answer/projects" target="_blank" rel="noopener noreferrer" class="dropdown__link">Roadmap<!-- --></a></li></ul></div><div class="navbar__item dropdown dropdown--hoverable"><a href="https://www.apache.org/" target="_blank" rel="noopener noreferrer" aria-haspopup="true" aria-expanded="false" role="button" class="navbar__link">ASF<!-- --></a><ul class="dropdown__menu"><li><a href="https://www.apache.org" target="_blank" rel="noopener noreferrer" class="dropdown__link">Foundation<!-- --></a></li><li><a href="https://www.apache.org/licenses/" target="_blank" rel="noopener noreferrer" class="dropdown__link">License<!-- --></a></li><li><a href="https://www.apache.org/events/current-event.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Events<!-- --></a></li><li><a href="https://www.apache.org/foundation/sponsorship.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Sponsorship<!-- --></a></li><li><a href="https://privacy.apache.org/policies/privacy-policy-public.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Privacy<!-- --></a></li><li><a class="dropdown__link" href="/community/security">Security<!-- --></a></li><li><a href="https://www.apache.org/foundation/thanks.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Thanks<!-- --></a></li></ul></div></div><div class="navbar__items navbar__items--right"><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a href="#" aria-haspopup="true" aria-expanded="false" role="button" class="navbar__link bi bi-translate"><svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true" class="iconLanguage_DSK9"><path fill="currentColor" d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"></path></svg>English<!-- --></a><ul class="dropdown__menu"><li><a href="/blog/why-the-answer-plugin-system-was-designed-this-way" target="_self" rel="noopener noreferrer" class="dropdown__link dropdown__link--active" lang="en">English<!-- --></a></li><li><a href="/zh-CN/blog/why-the-answer-plugin-system-was-designed-this-way" target="_self" rel="noopener noreferrer" class="dropdown__link" lang="zh-CN">简体中文<!-- --></a></li></ul></div><a href="https://twitter.com/answerdev" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link bi bi-twitter-x navbar-icon-link"></a><a href="https://discord.gg/a6PZZbfnFx" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link bi bi-discord navbar-icon-link"></a><a href="https://github.com/apache/answer" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link bi bi-github navbar-icon-link"></a><div class="searchBox_H2mL"></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_eExm"><div class="container"><div class="justify-content-end mb-4 row"><div class="col-lg-8 col-md-12"><div class="px-0 px-lg-5 pt-5"><header><div class="d-flex align-items-center mb-3"><a class="me-2" href="/blog">Blog<!-- --></a><span class="me-2">/</span><a class="me-2" href="/blog/category/tutorials">Tutorials<!-- --></a></div><h1 class="mb-3"><a class="text-body" href="/blog/why-the-answer-plugin-system-was-designed-this-way">The Packaging Process for Answer Plugins</a></h1><div class="d-flex align-items-center text-secondary"><div class="me-3">LinkinStar</div><time class="me-3" datetime="2023-07-22T00:00:00.000Z">July 22, 2023</time><div>3 min read<!-- --></div></div></header></div></div><div class="col-lg-2 col-md-12"></div></div><div class="justify-content-end row"><div class="col-lg-8 col-md-12"><article class="px-0 px-lg-5 pb-5 mb-5" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="image" content="https://answer.apache.org/2023-07-22-cover@4x.png"><div id="__blog-post-container" class="markdown" itemprop="articleBody"><div class="mb-4"><img decoding="async" loading="lazy" src="/assets/images/2023-07-22-cover@4x-adfc331ff0caa372bd48d7c798155678.png" class="rounded img_RAU7" width="1280px" height="720px"></div><blockquote> |
| <!-- --><ol> |
| <!-- --><li>Why is Answer's plugin system designed in such a way that it seems a bit difficult to use?</li> |
| <!-- --><li>How can I implement plugin functionality using Golang?</li> |
| <!-- --><li>What exactly does Answer's plugin system do when it is compiled and packaged?</li> |
| <!-- --></ol> |
| <!-- --></blockquote> |
| <!-- --><h2 class="anchor anchorWithStickyNavbar_loeA" id="background">Background<!-- --><a href="#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background"></a></h2> |
| <!-- --><p>You can build a Q&A community using Answer easily. However, the basic features of Answer may not sufficiently support to every use case. |
| Therefore, we need to design a plugin system to extend its features. |
| As you may know, Answer is built using <!-- --><code>React.js</code> and <!-- --><code>Golang</code>. Both these languages require compilation. So designing a plugin system is a bit difficult.<!-- --></p> |
| <!-- --><h2 class="anchor anchorWithStickyNavbar_loeA" id="goal--features">Goal & Features<!-- --><a href="#goal--features" class="hash-link" aria-label="Direct link to Goal & Features" title="Direct link to Goal & Features"></a></h2> |
| <!-- --><p>The goal of Answer's plugin system is to provide a <!-- --><strong>flexible</strong> and <!-- --><strong>extendable</strong> architecture that can accommodate a wide range of use cases. Some of the key features of the plugin system include:<!-- --></p> |
| <!-- --><h3 class="anchor anchorWithStickyNavbar_loeA" id="connectors">Connectors<!-- --><a href="#connectors" class="hash-link" aria-label="Direct link to Connectors" title="Direct link to Connectors"></a></h3> |
| <!-- --><p>By default, Answer supports login via email and password. Within the plugin system, developers can easily integrate other authentication, such as GitHub.</p> |
| <!-- --><img src="/assets/images/answer-plugin-connector-2e7bb37348532629256d812cec021c34.png" alt="install-choose-language" width="400"> |
| <!-- --><h3 class="anchor anchorWithStickyNavbar_loeA" id="storage">Storage<!-- --><a href="#storage" class="hash-link" aria-label="Direct link to Storage" title="Direct link to Storage"></a></h3> |
| <!-- --><p>Out of the box, Answer stores files in the local file system. However, there could be scenarios where users might prefer to save their uploaded files to a cloud storage service like <!-- --><code>S3</code>. This can be achieved by the plugin system.<!-- --></p> |
| <!-- --><img src="/assets/images/answer-plugin-storage-014f1ac8b8e1939c2a8d99253adb9724.png" alt="install-choose-language" width="400"> |
| <!-- --><h2 class="anchor anchorWithStickyNavbar_loeA" id="implementation">Implementation<!-- --><a href="#implementation" class="hash-link" aria-label="Direct link to Implementation" title="Direct link to Implementation"></a></h2> |
| <!-- --><p>Now, let's explore how the plugin system is implemented, followed by the reasons behind our design decisions.</p> |
| <!-- --><h3 class="anchor anchorWithStickyNavbar_loeA" id="details">Details<!-- --><a href="#details" class="hash-link" aria-label="Direct link to Details" title="Direct link to Details"></a></h3> |
| <!-- --><p>The general process is as follows:</p> |
| <!-- --><img src="/assets/images/answer-plugin-build-brief-b0b7164eb72df5d3d2b6b0e24f53be2a.png" alt="install-choose-language" width="400"> |
| <!-- --><p>Here are the steps involved in implementing a plugin:</p> |
| <!-- --><ol> |
| <!-- --><li>Generate a <!-- --><code>main.go</code> file.<!-- --></li> |
| <!-- --><li>Import the specific plugin list.</li> |
| <!-- --><li>Execute <!-- --><code>go mod tidy</code> and <!-- --><code>go mod vendor</code> to manage dependencies.<!-- --></li> |
| <!-- --><li>Copy the UI directory.</li> |
| <!-- --><li>Overwrite the <!-- --><code>index.ts</code> file.<!-- --></li> |
| <!-- --><li>Execute <!-- --><code>pnpm install</code> and <!-- --><code>pnpm build</code> to manage the package and build the project.<!-- --></li> |
| <!-- --><li>Merge the <!-- --><code>i18n</code> file from the plugin with the original <!-- --><code>i18n</code> file.<!-- --></li> |
| <!-- --><li>Build a new binary.</li> |
| <!-- --><li>Clean up the byproducts generated during the build process.</li> |
| <!-- --></ol> |
| <!-- --><p><img decoding="async" loading="lazy" alt="answer-plugin-build-all.png" src="/assets/images/answer-plugin-build-all-4a2d4f7304dd15a01d1c624a8a0826a2.png" width="1862" height="846" class="img_RAU7"></p> |
| <!-- --><h3 class="anchor anchorWithStickyNavbar_loeA" id="reason">Reason<!-- --><a href="#reason" class="hash-link" aria-label="Direct link to Reason" title="Direct link to Reason"></a></h3> |
| <!-- --><p>Here are the reasons behind our design choices:</p> |
| <!-- --><h4 class="anchor anchorWithStickyNavbar_loeA" id="static-compilation">Static Compilation<!-- --><a href="#static-compilation" class="hash-link" aria-label="Direct link to Static Compilation" title="Direct link to Static Compilation"></a></h4> |
| <!-- --><blockquote> |
| <!-- --><p>This is the main reason why the plugin system is designed this way.</p> |
| <!-- --></blockquote> |
| <!-- --><p><code>React.js</code> and <!-- --><code>Golang</code> both these languages require compilation. They are not dynamically executable like some other scripting languages. |
| So the plugin system should be a static compilation, which means that the application and plugins are compiled together, resulting in a single binary that can be easily distributed and deployed.<!-- --></p> |
| <!-- --><h4 class="anchor anchorWithStickyNavbar_loeA" id="fixed-functionality">Fixed Functionality<!-- --><a href="#fixed-functionality" class="hash-link" aria-label="Direct link to Fixed Functionality" title="Direct link to Fixed Functionality"></a></h4> |
| <!-- --><p>The plugin system allows users to add features that are fixed for their specific use cases without changing the core system. |
| Furthermore, these functionalities persistently remain operational once they are employed. |
| Therefore, it is sufficient to deliberate on the necessities of their incorporation at the initial stage, and subsequently, package them accordingly. |
| In the future, we can build a Docker image that contains all official plugins, thereby enabling users to access the entire range of features. The enablement or disablement of these functionalities can be managed through the plugin control interface.</p> |
| <!-- --><h4 class="anchor anchorWithStickyNavbar_loeA" id="extension">Extension<!-- --><a href="#extension" class="hash-link" aria-label="Direct link to Extension" title="Direct link to Extension"></a></h4> |
| <!-- --><p>The most important capability of a plugin system is its extensibility. |
| A program can't provide all the functions that every user wants. |
| However, with a plugin system, users can develop their plugins to help them achieve the functions that they want.</p> |
| <!-- --><h2 class="anchor anchorWithStickyNavbar_loeA" id="reference">Reference<!-- --><a href="#reference" class="hash-link" aria-label="Direct link to Reference" title="Direct link to Reference"></a></h2> |
| <!-- --><p>The Caddy is a great open-source software that inspired the design of the Answer plugin system. |
| Caddy is a web server that allows developers to extend its functionality using plugins. |
| Using <!-- --><a href="https://github.com/caddyserver/xcaddy/" target="_blank" rel="noopener noreferrer">xcaddy</a> can easy to make custom builds of the Caddy Web Server.<!-- --></p> |
| <!-- --><h2 class="anchor anchorWithStickyNavbar_loeA" id="more">More<!-- --><a href="#more" class="hash-link" aria-label="Direct link to More" title="Direct link to More"></a></h2> |
| <!-- --><p>In this blog post, we discussed the design and implementation of the plugin system for Answer, a popular open-source Q&A platform. |
| We discussed the motivation behind the design, and the features and principles of the plugin system, and provided a step-by-step guide on implementation. |
| If you are interested in developing plugins for Answer, please feel free to leave us a comment. |
| We will also write an article on how to implement an Answer plugin from scratch, so stay focused!</p></div><div class="mt-3"><div class="d-flex align-items-center text-secondary"><span>Share to<!-- --></span><button aria-label="twitter" class="react-share__ShareButton shareBtn_lEr0" style="background-color:transparent;border:none;padding:0;font:inherit;color:inherit;cursor:pointer"><i class="br bi-twitter" style="font-size:16px"></i></button><button title="The Packaging Process for Answer Plugins" aria-label="facebook" class="react-share__ShareButton shareBtn_lEr0" style="background-color:transparent;border:none;padding:0;font:inherit;color:inherit;cursor:pointer"><i class="br bi-facebook" style="font-size:16px"></i></button><button aria-label="linkedin" class="react-share__ShareButton shareBtn_lEr0" style="background-color:transparent;border:none;padding:0;font:inherit;color:inherit;cursor:pointer"><i class="br bi-linkedin" style="font-size:16px"></i></button></div><div class="mt-4"><a href="https://github.com/apache/answer-website/edit/main/blog/why-the-answer-plugin-system-was-designed-this-way/index.md" target="_blank" rel="noopener noreferrer" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_N_05" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page<!-- --></a></div></div></article></div><div class="col-lg-2 col-md-12"><div class="tableOfContents_PDf4 thin-scrollbar"><ul class="border-0 p-0 table-of-contents table-of-contents__left-border"><li class="m-0 mb-2"><a href="#background" class="fs-14 text-secondary table-of-contents__link toc-highlight">Background</a></li><li class="m-0 mb-2"><a href="#goal--features" class="fs-14 text-secondary table-of-contents__link toc-highlight">Goal & Features</a><ul class="border-0 p-0 ps-3 mt-2"><li class="m-0 mb-2"><a href="#connectors" class="fs-14 text-secondary table-of-contents__link toc-highlight">Connectors</a></li><li class="m-0 mb-2"><a href="#storage" class="fs-14 text-secondary table-of-contents__link toc-highlight">Storage</a></li></ul></li><li class="m-0 mb-2"><a href="#implementation" class="fs-14 text-secondary table-of-contents__link toc-highlight">Implementation</a><ul class="border-0 p-0 ps-3 mt-2"><li class="m-0 mb-2"><a href="#details" class="fs-14 text-secondary table-of-contents__link toc-highlight">Details</a></li><li class="m-0 mb-2"><a href="#reason" class="fs-14 text-secondary table-of-contents__link toc-highlight">Reason</a></li></ul></li><li class="m-0 mb-2"><a href="#reference" class="fs-14 text-secondary table-of-contents__link toc-highlight">Reference</a></li><li class="m-0 mb-2"><a href="#more" class="fs-14 text-secondary table-of-contents__link toc-highlight">More</a></li></ul></div></div></div></div></div><footer class="footer"><div class="container py-3"><div class="d-flex justify-content-between flex-wrap text-center"><div><div class="mb-3"><a href="https://www.apache.org/" target="_blank"><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 525" role="img" style="width:120px"><defs><style>.cls-1{fill:#7c297d}.cls-3{fill:#dd552c}.cls-4{fill:#d22128}</style></defs><path class="cls-1" d="M458.804 181.745h49.045l87.413 220.094h-53.455l-14.777-38.044h-87.406l-15.094 38.044H371.39l87.413-220.094Zm55.65 142.746L483.33 244l-30.814 80.491h61.938ZM622.717 331.722h48.735c.317 21.066 16.037 33.332 40.246 33.332 20.75 0 33.958-8.49 33.958-23.267 0-15.41-14.151-24.526-45.275-31.447-51.57-10.69-76.096-32.066-76.096-68.226 0-39.93 31.757-64.771 82.384-64.771 52.19 0 85.521 28.296 85.521 72.628h-48.11c0-19.806-13.834-31.756-36.785-31.756-21.065 0-33.958 8.806-33.958 23.267 0 13.525 11.634 22.014 45.275 29.871 54.714 12.892 77.665 33.642 77.665 68.542 0 41.505-32.073 66.347-84.262 66.347-55.34 0-89.298-28.929-89.298-74.52ZM852.91 181.745h137.716v45.276h-87.722v55.023h79.859v44.023h-79.86v75.772H852.91V181.745Z"></path><path class="cls-3" d="M141.108 209.888c13.187-32.608 27.9-65.152 43.688-93.997-23.567-17.504-46.196-55.249-55.493-71.972-3.34 3.794-5.508 8.163-6.49 11.718-8.76 31.625 22.42 69.814-2.693 55.861C99.195 99.871 52.08 74.41 34.107 99.717c20.128 25.862 72.773 90.93 107 110.171Z"></path><path d="M184.796 115.891c15.297-27.95 31.6-52.428 48.501-70.063 0 0-16.858 24.4-40.936 73.18 14.582 4.016 56.113 12.256 113.96-2.686 1.422-10.513-5.645-22.075-40.863-25.947-22.993-2.524 27.597-54.902-9.052-79.674a46.281 46.281 0 0 0-3.486-2.14 45.29 45.29 0 0 0-3.911-1.205c-42.803-11.17-48.736 61.409-65.816 45.806-27.6-25.212-45.022-19.321-53.89-9.243 9.297 16.723 31.926 54.468 55.493 71.972Z" style="fill:#f79a23"></path><path class="cls-4" d="M106.682 303.838c9.662-28.946 21.286-61.466 34.426-93.95-34.228-19.241-86.873-84.31-107-110.171-3.594 5.056-6.05 12.108-6.868 21.752-4.39 51.802 49.052 90.153 38.398 97.158-14.092 9.267-42.141-22.26-53.196-2.229 16.023 20.584 48.662 57.777 94.24 87.44Z"></path><path class="cls-3" d="M254.756 192.118c-27.059-9.65 28.276-35.533 46.245-62.991 2.3-3.511 4.676-8.049 5.32-12.805-57.847 14.942-99.378 6.702-113.96 2.686-12.465 25.257-26.859 57.084-41.87 95.458 15.634 6.685 79.47 31.38 169.637 31.507 15.16-39.485-39.691-44.699-65.372-53.855Z"></path><path class="cls-4" d="M117.137 309.049c15.9 4.955 68.584 19.756 124.537 17.528 7.517-20.352-20.586-22.338-22.875-38.661-1.772-12.63 73.957 10.614 98.323-35.311a59.485 59.485 0 0 0 3.006-6.632c-90.167-.127-154.003-24.822-169.637-31.507-10.97 28.044-22.256 59.517-33.354 94.583Z"></path><path class="cls-1" d="M117.137 309.049c-7.145 22.57-14.193 46.682-21.035 72.164a1771.75 1771.75 0 0 0-7.19 27.643c53.106 17.531 102.008.04 103.666-21.638.014-.172-.018-.3-.008-.464 1.264-22.961-33.15-10.234-32.336-24.038.818-13.906 60.081-.081 78.409-29.895a34.139 34.139 0 0 0 3.03-6.244c-55.952 2.228-108.636-12.573-124.536-17.528ZM12.442 216.398c-.774 1.404-1.472 3.026-2.068 4.965-10.292 33.45 62.485 78.385 52.583 88.18-8.925 8.827-20.557-11.343-34.9-3.012a22.05 22.05 0 0 0-4.806 3.75c-16.221 16.619-.254 64.496 45.77 90.052-10.74 36.062-21.432 76.351-31.9 118.486 3.798-1.33 8.342-2.663 9.473-6.245 1.698-6.981 12.194-49.462 29.235-107.094 0 0 3.11-11.806 8.804-31.255a1996.422 1996.422 0 0 1 22.049-70.387c-45.578-29.663-78.217-66.856-94.24-87.44ZM404.167 144.735h9.264v-62.2h23.348v-9.062h-55.96v9.062h23.348v62.2zM464.853 112.958h36.469v31.777h9.358V73.473h-9.358v30.417h-36.47V73.473h-9.256v71.262h9.257v-31.777zM581.403 135.963h-35.17v-23.106h31.588v-8.772h-31.588V82.151h34.106v-8.678h-43.363v71.262h44.427v-8.772z"></path></svg></a></div><div class="fs-14"><div class="my-3"><span>Copyright © 2023 - <!-- -->2025<!-- --> The Apache Software Foundation, Licensed under the Apache License, Version 2.0.<!-- --></span><br><span>Apache, Apache Answer, the Apache logo and the Apache Answer logo are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries.</span></div><span>Feature icons by <!-- --> <!-- --><a href="https://www.flaticon.com" class="link-secondary" target="_blank">Freepik</a>.<!-- --></span></div></div></div></div></footer></div> |
| </body> |
| </html> |