L3S DRM Developer Guide
The DRM UI can be implemented in your aircraft's cockpit using different gauge technologies. Choose the implementation that best fits your aircraft's architecture.
HTML/JS Gauge Implementation
Most Common: This is the standard implementation method used by most aircraft developers.
The DRM UI is implemented like a regular HTML/JS gauge in the aircraft's cockpit.
This allows you to display the DRM activation UI and handle user input (e.g., entering a license key) directly within the simulator. If you use an installer, you can add a license.key to the work folder, which will be used to activate the DRM.
In this case, no user input is required, and the DRM activation will be done automatically, without ever showing the UI.
Since the DRM UI is a HTML/JS gauge, it can be fully customized to fit your aircraft's design and user experience.

Required Files
The gauge folder contains the three required files to display the DRM activation UI in your aircraft's cockpit:
ModuleDrmGauge.htmlModuleDrmGauge.jsModuleDrmGauge.css
These are used to allow user interaction (e.g., entering a license key) and to display error or success messages.
As mentioned in the Overview, you must add this gauge to your 3D cockpit. If you use a dedicated VCockpit, ensure it is only visible when the
L:DRM_UI_VISIBLE_<ProductName>LVAR is set to1. The suffix is derived fromdata-expected-product-name(spaces become underscores, special characters are stripped). For example,data-expected-product-name="DRM Demo"producesL:DRM_UI_VISIBLE_DRM_Demo. Alternatively, if you usetransparentSuccessScreen(true)in C++, you can overlay the gauge on an existing instrument — it will become transparent after activation (see the panel.cfg examples below).
It is required that ModuleDrmGauge.js is properly loaded with the aircraft.
If it is missing or fails to load, DRM activation will not succeed.
HTML File Configuration
The last line of ModuleDrmGauge.html contains a <script> tag with two attributes that must be configured for your aircraft:
<script type="text/html" import-script="/Pages/VCockpit/Instruments/MyCompany/MyAircraft_DRM/ModuleDrmGauge.js" data-expected-product-name="My Aircraft"></script>import-script— The path toModuleDrmGauge.jsmatching your aircraft's instrument folder. For example, if yourpanel.cfgreferencesMyCompany_Aircraft_DRM/ModuleDrmGauge.html, the import-script path should point toModuleDrmGauge.jsin the same folder.data-expected-product-name— A prefix filter matched against the.productName()value set in your C++ builder. The gauge only activates when the product name starts with this value.
This is useful when a single HTML gauge file is shared across multiple product variants. For example, if you have.productName("L3 707-100")and.productName("L3 707-200")in separate builds, settingdata-expected-product-name="L3 707"allows one HTML file to serve both.
Hashes: If you use file-hash verification, remember that editing
ModuleDrmGauge.htmlchanges its hash. Rebuild or update your C++ file hashes after modifying this file.
Example panel.cfg Entry
Option 1: Dedicated VCockpit
Add the DRM gauge as its own VCockpit slot, shown only when L:DRM_UI_VISIBLE_<ProductName> == 1 (e.g. L:DRM_UI_VISIBLE_DRM_Demo):
[Vcockpit03]
size_mm=1024,768
pixel_size=1024,768
texture=$SCREEN_3
background_color=255,0,0
htmlgauge00=MyCompany_Aircraft_DRM/ModuleDrmGauge.html, 0,0,1024,768Option 2: Overlay on an existing gauge
When using transparentSuccessScreen(true) in C++, you can place the DRM gauge on top of an existing gauge (e.g., an EFB) at the same coordinates. The DRM gauge will automatically become transparent after activation, revealing the gauge underneath:
[VCockpit01]
size_mm=2048,4096
pixel_size=2048,4096
texture=$GAUGES_UNIFIED
background_color=0,0,0
htmlgauge00=MyCompany_Aircraft_EFB/EFB.html, 0,2900,1024,768
htmlgauge01=MyCompany_Aircraft_DRM/ModuleDrmGauge.html, 0,2900,1024,768Tip: The DRM gauge is listed after the EFB gauge so it renders on top. After activation, the transparent DRM gauge becomes invisible and the EFB is fully usable.
WASM Gauge Implementation
Not required when using the HTML/JS gauge described above. This is an advanced alternative for handling DRM authentication directly within your WASM code.
Show WASM Gauge Implementation
WASM gauge implementation gives you full control over the DRM authentication flow within your C++ WASM module. This approach is ideal when you want to integrate DRM activation into existing cockpit systems or create custom UI experiences.
Requirements
Important: Even when using WASM gauge implementation, you still need JavaScript components for username injection. A standalone JS-to-WASM username injector is currently work in progress.
Recommended setup:
- Set up the JavaScript panel for testing purposes
- Keep the JS components for username injection (required for DRM functionality)
- Implement your custom authentication UI in WASM
Authentication Flow
1. Monitor Ready State
Before attempting authentication, monitor the IsReady() function:
// Check if DRM is ready to receive authentication
if (DRMPublish::IsReady()) {
// DRM module is ready - username received from JS
// and no request is currently in progress
} else {
// Still waiting for username from JS or request in progress
// Continue checking in your update loop
}IsReady() returns false when:
- No username has been received yet via JavaScript
- An authentication request is already in progress
2. Authenticate with Key
When the user inputs a license key and the system is ready:
// User has entered a key via your custom WASM UI
std::string userKey = GetKeyFromYourUI(); // Your implementation
if (DRMPublish::IsReady()) {
// Authenticate with the plaintext key
DRMPublish::AuthenticateWithKey(userKey);
}Note: Pass the key in plaintext - the DRM system handles all encryption and security internally.
3. Subsequent Launches
After successful authentication:
// On subsequent launches, check authentication status
if (DRMPublish::IsAuthenticated()) {
// User is already authenticated
// No need to show authentication UI
} else {
// Show authentication UI for key input
}Automatic Storage: The DRM module automatically stores and loads authentication data. You don't need to save or resend keys on each launch.
Integration with Standard Flow
After authentication via WASM, all other DRM functionality works identically to the standard C++ integration:
- Use callback functions defined in the Builder pattern (see C++ Integration page)
Best Practice: Start with the JavaScript implementation for testing, then migrate to WASM gauge implementation once your authentication flow is working correctly.