mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 00:15:05 +00:00
Merge branch 'prepare-v1'
This commit is contained in:
commit
7908319e40
10 files changed
+235
-75
No files matched your search
@@ -22,6 +22,9 @@ Instead, it can use code-centric tools like `find_symbol`, `find_referencing_sym
|
||||
<a href="lessons_learned.md"><img src="https://img.shields.io/badge/Lessons-Learned-7c4700?style=flat&logo=readthedocs&logoColor=white&labelColor=7c4700" alt="Lessons Learned" /></a>
|
||||
</p>
|
||||
|
||||
> [!TIP]
|
||||
> The [**Serena JetBrains plugin**](#the-serena-jetbrains-plugin) has been released!
|
||||
|
||||
## LLM Integration
|
||||
|
||||
Serena provides the necessary [tools](https://oraios.github.io/serena/01-about/035_tools.html) for coding workflows, but an LLM is required to do the actual work,
|
||||
@@ -55,23 +58,46 @@ Note how Serena's tools enable Claude to find and edit the right symbols.
|
||||
|
||||
https://github.com/user-attachments/assets/6eaa9aa1-610d-4723-a2d6-bf1e487ba753
|
||||
|
||||
### Programming Language Support & Semantic Analysis Capabilities
|
||||
## Programming Language Support & Semantic Analysis Capabilities
|
||||
|
||||
Serena's semantic code analysis capabilities build on **language servers** using the widely implemented
|
||||
language server protocol (LSP). The LSP provides a set of versatile code querying
|
||||
and editing functionalities based on symbolic understanding of the code.
|
||||
Serena provides a set of versatile code querying and editing functionalities
|
||||
based on symbolic understanding of the code.
|
||||
Equipped with these capabilities, Serena discovers and edits code just like a seasoned developer
|
||||
making use of an IDE's capabilities would.
|
||||
Serena can efficiently find the right context and do the right thing even in very large and
|
||||
complex projects! So not only is it free and open-source, it frequently achieves better results
|
||||
than existing solutions that charge a premium.
|
||||
complex projects!
|
||||
|
||||
There are two alternative technologies powering these capabilities:
|
||||
|
||||
* **Language servers** implementing the language server Protocol (LSP) — the free/open-source alternative.
|
||||
* **The Serena JetBrains Plugin**, which leverages the powerful code analysis and editing
|
||||
capabilities of your JetBrains IDE.
|
||||
|
||||
You can choose either of these backends depending on your preferences and requirements.
|
||||
|
||||
### Language Servers
|
||||
|
||||
Serena incorporates a powerful abstraction layer for the integration of language servers
|
||||
that implement the language server protocol (LSP).
|
||||
The underlying language servers are typically open-source projects (like Serena) or at least freely available for use.
|
||||
|
||||
Language servers provide support for a wide range of programming languages.
|
||||
With Serena's LSP library, we provide **support for over 30 programming languages**, including
|
||||
AL, Bash, C#, C/C++, Clojure, Dart, Elixir, Elm, Erlang, Fortran, Go, Groovy (partial support), Haskell, Java, Javascript, Julia, Kotlin, Lua, Markdown, Nix, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Scala, Swift, TOML, TypeScript, YAML, and Zig.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Some languages require additional dependencies to be installed; see the [Language Support](https://oraios.github.io/serena/01-about/020_programming-languages.html) page for details.
|
||||
> Some language servers require additional dependencies to be installed; see the [Language Support](https://oraios.github.io/serena/01-about/020_programming-languages.html) page for details.
|
||||
|
||||
### The Serena JetBrains Plugin
|
||||
|
||||
As an alternative to language servers, the [Serena JetBrains Plugin](https://plugins.jetbrains.com/plugin/28946-serena/)
|
||||
leverages the powerful code analysis capabilities of your JetBrains IDE.
|
||||
The plugin naturally supports all programming languages and frameworks that are supported by JetBrains IDEs,
|
||||
including IntelliJ IDEA, PyCharm, Android Studio, AppCode, WebStorm, PhpStorm, RubyMine, GoLand, AppCode, CLion, Rider, and others.
|
||||
|
||||
<a href="https://plugins.jetbrains.com/plugin/28946-serena/"><img src="docs/_static/images/jetbrains-marketplace-button.png"></a>
|
||||
|
||||
The plugin offers the most robust and most powerful Serena experience.
|
||||
See our [documentation page](https://oraios.github.io/serena/02-usage/025_jetbrains_plugin.html) for further details and instructions.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
||||
@@ -1,16 +1,31 @@
|
||||
# Language Support
|
||||
|
||||
Serena's semantic code analysis capabilities build on **language servers** using the widely implemented
|
||||
language server protocol (LSP). The LSP provides a set of versatile code querying
|
||||
and editing functionalities based on symbolic understanding of the code.
|
||||
Serena provides a set of versatile code querying and editing functionalities
|
||||
based on symbolic understanding of the code.
|
||||
Equipped with these capabilities, Serena discovers and edits code just like a seasoned developer
|
||||
making use of an IDE's capabilities would.
|
||||
Serena can efficiently find the right context and do the right thing even in very large and
|
||||
complex projects! So not only is it free and open-source, it frequently achieves better results
|
||||
than existing solutions that charge a premium.
|
||||
complex projects!
|
||||
|
||||
Language servers provide support for a wide range of programming languages.
|
||||
With Serena, we provide direct, out-of-the-box support for:
|
||||
There are two alternative technologies powering these capabilities:
|
||||
|
||||
* **Language servers** implementing the language server Protocol (LSP) — the free/open-source alternative.
|
||||
* **The Serena JetBrains Plugin**, which leverages the powerful code analysis and editing
|
||||
capabilities of your JetBrains IDE.
|
||||
|
||||
You can choose either of these backends depending on your preferences and requirements.
|
||||
|
||||
## Language Servers
|
||||
|
||||
Serena incorporates a powerful abstraction layer for the integration of language servers
|
||||
that implement the language server protocol (LSP).
|
||||
It even supports multiple language servers in parallel to support polyglot projects.
|
||||
|
||||
The language servers themselves are typically open-source projects (like Serena)
|
||||
or at least freely available for use.
|
||||
|
||||
We currently provide direct, out-of-the-box support for the programming languages listed below.
|
||||
Some languages require additional installations or setup steps, as noted.
|
||||
|
||||
* **AL**
|
||||
* **Bash**
|
||||
@@ -68,3 +83,34 @@ With Serena, we provide direct, out-of-the-box support for:
|
||||
|
||||
Support for further languages can easily be added by providing a shallow adapter for a new language server implementation,
|
||||
see Serena's [memory on that](https://github.com/oraios/serena/blob/main/.serena/memories/adding_new_language_support_guide.md).
|
||||
|
||||
## The Serena JetBrains Plugin
|
||||
|
||||
As an alternative to language servers, the [Serena JetBrains Plugin](https://plugins.jetbrains.com/plugin/28946-serena/)
|
||||
leverages the powerful code analysis capabilities of JetBrains IDEs.
|
||||
The plugin naturally supports all programming languages and frameworks that are supported by JetBrains IDEs,
|
||||
including IntelliJ IDEA, PyCharm, Android Studio, AppCode, WebStorm, PhpStorm, RubyMine, GoLand, AppCode, CLion, Rider, and others.
|
||||
|
||||
When using the plugin, Serena connects to an instance of your JetBrains IDE via the plugin. For users who already
|
||||
work in a JetBrains IDE, this means Serena seamlessly integrates with the IDE instance you typically have open anyway,
|
||||
requiring no additional setup or configuration beyond the plugin itself. This approach offers several key advantages:
|
||||
|
||||
* **External library indexing**: Dependencies and libraries are fully indexed and accessible to Serena
|
||||
* **No additional setup**: No need to download or configure separate language servers
|
||||
* **Enhanced performance**: Faster tool execution thanks to optimized IDE integration
|
||||
* **Multi-language excellence**: First-class support for polyglot projects with multiple languages and frameworks
|
||||
|
||||
Even if you prefer to work in a different code editor, you can still benefit from the JetBrains plugin by running
|
||||
a JetBrains IDE instance (most have free community editions) alongside your preferred editor with your project
|
||||
opened and indexed. Serena will connect to the IDE for code analysis while you continue working in your editor
|
||||
of choice.
|
||||
|
||||
```{raw} html
|
||||
<p>
|
||||
<a href="https://plugins.jetbrains.com/plugin/28946-serena/">
|
||||
<img style="background-color:transparent;" src="../_static/images/jetbrains-marketplace-button.png">
|
||||
</a>
|
||||
</p>
|
||||
```
|
||||
|
||||
See the [JetBrains Plugin documentation](../02-usage/025_jetbrains_plugin) for usage details.
|
||||
@@ -2,14 +2,20 @@
|
||||
|
||||
Serena is a command-line tool with a variety of sub-commands.
|
||||
This section describes
|
||||
* varies ways of running Serena
|
||||
* various ways of running Serena
|
||||
* how to run and configure the most important command, i.e. starting the MCP server
|
||||
* other useful commands.
|
||||
|
||||
## Ways of Running Serena
|
||||
|
||||
In the following, we will refer to the command used to run Serena as `<serena>`,
|
||||
which you should replace with the appropriate command based on your chosen method.
|
||||
which you should replace with the appropriate command based on your chosen method,
|
||||
as detailed below.
|
||||
|
||||
In general, to get help, append `--help` to the command, i.e.
|
||||
|
||||
<serena> --help
|
||||
<serena> <command> --help
|
||||
|
||||
### Using uvx
|
||||
|
||||
@@ -92,6 +98,12 @@ Given your preferred method of running Serena, you can start the MCP server usin
|
||||
Note that no matter how you run the MCP server, Serena will, by default, start a web-based dashboard on localhost that will allow you to inspect
|
||||
the server's operations, logs, and configuration.
|
||||
|
||||
:::{tip}
|
||||
By default, Serena will use language servers for code understanding and analysis.
|
||||
With the [Serena JetBrains Plugin](025_jetbrains_plugin), we recently introduced a powerful alternative,
|
||||
which has several advantages over the language server-based approach.
|
||||
:::
|
||||
|
||||
### Standard I/O Mode
|
||||
|
||||
The typical usage involves the client (e.g. Claude Code, Codex or Cursor) running
|
||||
@@ -150,7 +162,11 @@ to get a list of all available options.
|
||||
Some useful options include:
|
||||
|
||||
* `--project <path|name>`: specify the project to work on by name or path.
|
||||
* `--project-from-cwd`: auto-detect project from current working directory (searches up for `.serena/project.yml` or `.git`, falls back to CWD). Intended only for CLI-based agents like Claude Code, Gemini and Codex.
|
||||
* `--project-from-cwd`: auto-detect the project from current working directory
|
||||
(looking for a directory containing `.serena/project.yml` or `.git` in parent directories, activating the current directory if none is found);
|
||||
This option is intended for CLI-based agents like Claude Code, Gemini and Codex, which are typically started from within the project directory
|
||||
and which do not change directories during their operation.
|
||||
* `--language-backend JetBrains`: use the Serena JetBrains Plugin as the language backend (overriding the default backend configured in the central configuration)
|
||||
* `--context <context>`: specify the operation [context](contexts) in which Serena shall operate
|
||||
* `--mode <mode>`: specify one or more [modes](modes) to enable (can be passed several times)
|
||||
* `--enable-web-dashboard <true|false>`: enable or disable the web dashboard (enabled by default)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# The Serena JetBrains Plugin
|
||||
|
||||
The [JetBrains Plugin](https://plugins.jetbrains.com/plugin/28946-serena/) allows Serena to
|
||||
leverage the powerful code analysis and editing capabilities of your JetBrains IDE.
|
||||
|
||||
```{raw} html
|
||||
<p>
|
||||
<a href="https://plugins.jetbrains.com/plugin/28946-serena/">
|
||||
<img style="background-color:transparent;" src="../_static/images/jetbrains-marketplace-button.png">
|
||||
</a>
|
||||
</p>
|
||||
```
|
||||
|
||||
We recommend the JetBrains plugin as the preferred way of using Serena,
|
||||
especially for users of JetBrains IDEs.
|
||||
|
||||
**Purchasing the JetBrains Plugin supports the Serena project.**
|
||||
The proceeds from plugin sales allow us to dedicate more resources to further developing and improving Serena.
|
||||
|
||||
## Configuring Serena
|
||||
|
||||
After installing the plugin, you need to configure Serena to use it.
|
||||
|
||||
**Central Configuration**.
|
||||
Edit the global Serena configuration file located at `~/.serena/serena_config.yml`
|
||||
(`%USERPROFILE%\.serena\config.yaml` on Windows).
|
||||
Change the `language_backend` setting as follows:
|
||||
|
||||
```yaml
|
||||
language_backend: JetBrains
|
||||
```
|
||||
|
||||
**Per-Instance Configuration**.
|
||||
The configuration setting in the global config file can be overridden on a
|
||||
per-instance basis by providing the arguments `--language-backend JetBrains` when
|
||||
launching the Serena MCP server.
|
||||
|
||||
## Advantages of the JetBrains Plugin
|
||||
|
||||
There are multiple features that are only available when using the JetBrains plugin:
|
||||
|
||||
* **External library indexing**: Dependencies and libraries are fully indexed and accessible to Serena
|
||||
* **No additional setup**: No need to download or configure separate language servers
|
||||
* **Enhanced performance**: Faster tool execution thanks to optimized IDE integration
|
||||
* **Multi-language excellence**: First-class support for polyglot projects with multiple languages and frameworks
|
||||
|
||||
We are also working on additional features like a `move_symbol` tool and debugging-related capabilities that
|
||||
will be available exclusively through the JetBrains plugin.
|
||||
|
||||
## Usage with Other Editors
|
||||
|
||||
We realize that not everyone uses a JetBrains IDE as their main code editor.
|
||||
You can still take advantage of the JetBrains plugin by running a JetBrains IDE instance alongside your
|
||||
preferred editor. Most JetBrains IDEs have a free community edition that you can use for this purpose.
|
||||
You just need to make sure that the project you are working on is open and indexed in the JetBrains IDE,
|
||||
so that Serena can connect to it.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 66 KiB |
@@ -97,11 +97,18 @@ body {
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
height: var(--header-height);
|
||||
order: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-sponsor {
|
||||
.logo-container img {
|
||||
height: calc(var(--header-height) - 20px);
|
||||
margin-top: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.header-banner {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -109,11 +116,6 @@ body {
|
||||
max-height: var(--header-height);
|
||||
}
|
||||
|
||||
.logo-container img {
|
||||
height: var(--header-height);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -178,7 +180,7 @@ body {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.platinum-sponsor-slide {
|
||||
.platinum-banner-slide {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -188,26 +190,26 @@ body {
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.platinum-sponsor-slide.active {
|
||||
.platinum-banner-slide.active {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.sponsor-image {
|
||||
.banner-image {
|
||||
object-fit: contain;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.sponsor-border {
|
||||
.banner-border {
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.platinum-sponsor-slide .sponsor-image {
|
||||
.platinum-banner-slide .banner-image {
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.gold-sponsors-section {
|
||||
.gold-banners-section {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
@@ -223,18 +225,19 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.gold-sponsor-slide {
|
||||
.gold-banner-slide {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.gold-sponsor-slide.active {
|
||||
.gold-banner-slide.active {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.gold-sponsor-slide .sponsor-image {
|
||||
.gold-banner-slide .banner-image {
|
||||
max-width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
@@ -40,56 +40,74 @@ class LogMessage {
|
||||
};
|
||||
}
|
||||
|
||||
class SponsorRotation {
|
||||
function updateThemeAwareImage($img, theme=null) {
|
||||
if (!theme) {
|
||||
const isDarkMode = $('html').data("theme") == 'dark';
|
||||
theme = isDarkMode ? 'dark' : 'light';
|
||||
}
|
||||
console.log("updating theme-aware image to theme:", theme);
|
||||
const newSrc = $img.data('src-' + theme);
|
||||
if (newSrc) {
|
||||
$img.attr('src', newSrc);
|
||||
}
|
||||
}
|
||||
|
||||
class BannerRotation {
|
||||
constructor() {
|
||||
this.platinumIndex = 0;
|
||||
this.goldIndex = 0;
|
||||
this.platinumTimer = null;
|
||||
this.goldTimer = null;
|
||||
this.platinumInterval = 5000;
|
||||
this.goldInterval = 5000;
|
||||
this.platinumInterval = 15000;
|
||||
this.goldInterval = 15000;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
let self = this;
|
||||
this.loadSponsors(function() {
|
||||
this.loadBanners(function() {
|
||||
self.startPlatinumRotation();
|
||||
self.startGoldRotation();
|
||||
});
|
||||
}
|
||||
|
||||
loadSponsors(onSuccess) {
|
||||
loadBanners(onSuccess) {
|
||||
$.ajax({
|
||||
url: 'https://oraios-software.de/serena-sponsors/manifest.php',
|
||||
url: 'https://oraios-software.de/serena-banners/manifest.php',
|
||||
type: 'GET',
|
||||
success: function (response) {
|
||||
console.log('Sponsors loaded:', response);
|
||||
console.log('Banners loaded:', response);
|
||||
|
||||
function fillSponsors($container, sponsors, className) {
|
||||
$.each(sponsors, function (index, sponsor) {
|
||||
let $img = $('<img src="' + sponsor.image + '" alt="' + sponsor.alt + '" class="sponsor-image">');
|
||||
let $anchor = $('<a href="' + sponsor.link + '" target="_blank"></a>');
|
||||
function fillBanners($container, banners, className) {
|
||||
$.each(banners, function (index, banner) {
|
||||
let $img = $('<img src="' + banner.image + '" alt="' + banner.alt + '" class="banner-image">');
|
||||
if (banner.image_dark) {
|
||||
$img.addClass('theme-aware-img');
|
||||
$img.attr('data-src-dark', banner.image_dark);
|
||||
$img.attr('data-src-light', banner.image);
|
||||
updateThemeAwareImage($img);
|
||||
}
|
||||
let $anchor = $('<a href="' + banner.link + '" target="_blank"></a>');
|
||||
$anchor.append($img);
|
||||
let $sponsor = $('<div class="' + className + '-slide" data-sponsor="' + (index + 1) + '"></div>');
|
||||
$sponsor.append($anchor);
|
||||
let $banner = $('<div class="' + className + '-slide" data-banner="' + (index + 1) + '"></div>');
|
||||
$banner.append($anchor);
|
||||
if (index === 0) {
|
||||
$sponsor.addClass('active');
|
||||
$banner.addClass('active');
|
||||
}
|
||||
if (sponsor.border) {
|
||||
$img.addClass('sponsor-border');
|
||||
if (banner.border) {
|
||||
$img.addClass('banner-border');
|
||||
}
|
||||
$container.append($sponsor);
|
||||
$container.append($banner);
|
||||
});
|
||||
}
|
||||
|
||||
fillSponsors($('#gold-sponsors'), response.gold, 'gold-sponsor');
|
||||
fillSponsors($('#platinum-sponsors'), response.platinum, 'platinum-sponsor');
|
||||
fillBanners($('#gold-banners'), response.gold, 'gold-banner');
|
||||
fillBanners($('#platinum-banners'), response.platinum, 'platinum-banner');
|
||||
onSuccess();
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
console.error('Error loading sponsors:', error);
|
||||
console.error('Error loading banners:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -109,7 +127,7 @@ class SponsorRotation {
|
||||
}
|
||||
|
||||
rotatePlatinum(direction) {
|
||||
const $slides = $('.platinum-sponsor-slide');
|
||||
const $slides = $('.platinum-banner-slide');
|
||||
const total = $slides.length;
|
||||
|
||||
if (total === 0) return;
|
||||
@@ -133,7 +151,7 @@ class SponsorRotation {
|
||||
}
|
||||
|
||||
rotateGold(direction) {
|
||||
const $groups = $('.gold-sponsor-slide');
|
||||
const $groups = $('.gold-banner-slide');
|
||||
const total = $groups.length;
|
||||
|
||||
if (total === 0) return;
|
||||
@@ -360,8 +378,8 @@ class Dashboard {
|
||||
// Initialize theme
|
||||
this.initializeTheme();
|
||||
|
||||
// Initialize sponsor rotation
|
||||
//this.sponsorRotation = new SponsorRotation();
|
||||
// Initialize banner rotation
|
||||
this.bannerRotation = new BannerRotation();
|
||||
|
||||
// Add ESC key handler for closing modals
|
||||
$(document).keydown(function (e) {
|
||||
@@ -1463,6 +1481,9 @@ class Dashboard {
|
||||
this.setTheme(newTheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theme {'light' | 'dark'}
|
||||
*/
|
||||
setTheme(theme) {
|
||||
// Set the theme on the document element
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
@@ -1476,8 +1497,11 @@ class Dashboard {
|
||||
this.$themeText.text('Dark');
|
||||
}
|
||||
|
||||
// Update the logo based on theme
|
||||
this.updateLogo(theme);
|
||||
// Update theme-aware images
|
||||
$(".theme-aware-img").each(function() {
|
||||
const $img = $(this);
|
||||
updateThemeAwareImage($img, theme);
|
||||
});
|
||||
|
||||
// Save to localStorage
|
||||
localStorage.setItem('serena-theme', theme);
|
||||
@@ -1486,17 +1510,6 @@ class Dashboard {
|
||||
this.updateChartsTheme();
|
||||
}
|
||||
|
||||
updateLogo(theme) {
|
||||
const logoElement = document.getElementById('serena-logo');
|
||||
if (logoElement) {
|
||||
if (theme === 'dark') {
|
||||
logoElement.src = 'serena-logo-dark-mode.svg';
|
||||
} else {
|
||||
logoElement.src = 'serena-logo.svg';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateChartsTheme() {
|
||||
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||
const textColor = isDark ? '#ffffff' : '#000000';
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
<div class="header-left">
|
||||
|
||||
<div class="logo-container">
|
||||
<img id="serena-logo" src="serena-logs.png" alt="Serena">
|
||||
<img id="serena-logo" class="theme-aware-img" src="serena-logo.svg" data-src-light="serena-logo.svg" data-src-dark="serena-logo-dark-mode.svg" alt="Serena">
|
||||
</div>
|
||||
|
||||
<!-- Platinum Sponsors in Header -->
|
||||
<div id="platinum-sponsors" class="header-sponsor">
|
||||
<!-- Platinum Banners in Header -->
|
||||
<div id="platinum-banners" class="header-banner">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -134,8 +134,8 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Gold Sponsors -->
|
||||
<section id="gold-sponsors" class="gold-sponsors-section">
|
||||
<!-- Gold Banners -->
|
||||
<section id="gold-banners" class="gold-banners-section">
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user