npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

luqta-sdk

v1.0.16

Published

Luqta SDK - Official JavaScript/TypeScript SDK for Luqta API integration. Easy-to-use client for React, Angular, Vue, Next.js, Svelte, and vanilla JavaScript. Supports CDN and npm installation with TypeScript support, authentication, user management, and

Readme

Luqta Web SDK

npm version License: MIT TypeScript

Official JavaScript/TypeScript SDK for integrating Luqta contest management, user engagement, and gamification features into web applications.


Quick Start (5 Minutes)

Step 1: Install the SDK

npm install luqta-sdk

Or use CDN:

<script src="https://unpkg.com/luqta-sdk@latest/dist/luqta-sdk.min.js"></script>

Step 2: Add a Container Element

<div id="luqta-container"></div>

Step 3: Initialize and Render

import { LuqtaClient } from 'luqta-sdk';

const client = new LuqtaClient({
  mode: 'preconfigured',
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  containerId: 'luqta-container',
  user: { email: '[email protected]' }
});

await client.render();

That's it! The SDK will display a complete contest UI with all features.


Table of Contents


Features

| Feature | Description | |---------|-------------| | Pre-built UI | Complete contest UI with zero design work | | Custom Branding | Match your app's colors, fonts, and logo | | 5 Level Types | Text, QR Code, Link, Image Upload, Quiz | | QR Scanner | Built-in camera scanner for QR codes | | Image Upload | File picker with preview | | Quiz System | Multi-question flow with results | | Bilingual | English and Arabic with RTL support | | TypeScript | Full type definitions included | | Zero Dependencies | Lightweight core library |


Installation

Option 1: npm (Recommended)

npm install luqta-sdk
import { LuqtaClient } from 'luqta-sdk';

Option 2: CDN

<!-- Add before </body> -->
<script src="https://unpkg.com/luqta-sdk@latest/dist/luqta-sdk.min.js"></script>

<script>
  const client = new LuqtaSDK.LuqtaClient({
    // your config
  });
</script>

Usage Modes

1. Pre-configured UI Mode (Recommended)

Best for: Quick integration with minimal code. The SDK handles all UI, screens, and user flows.

Option A: All-in-One Initialization

<!DOCTYPE html>
<html>
<head>
  <title>My App with Luqta</title>
</head>
<body>
  <!-- Container where SDK UI will appear -->
  <div id="luqta-container" style="width: 100%; max-width: 800px; margin: 0 auto;"></div>

  <script src="https://unpkg.com/luqta-sdk@latest/dist/luqta-sdk.min.js"></script>
  <script>
    async function initLuqta() {
      const client = new LuqtaSDK.LuqtaClient({
        mode: 'preconfigured',
        apiKey: 'YOUR_API_KEY',
        appId: 'YOUR_APP_ID',
        containerId: 'luqta-container',
        user: { email: '[email protected]' }
      });

      await client.render();
    }

    initLuqta();
  </script>
</body>
</html>

Option B: Step-by-Step Initialization (More Control)

For more control over the initialization process, use separate steps:

// Step 1: Create client with credentials
const client = new LuqtaSDK.LuqtaClient({
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  user: { email: '[email protected]' }
});

// Step 2: Initialize SDK (validates credentials, fetches initial data)
const result = await client.initializeSdk();
console.log('Found contests:', result.contests.data?.items?.length);

// Step 3: Configure UI settings (optional - call anytime before render)
client.configure({
  containerId: 'luqta-container',
  branding: {
    primaryColor: '#5304fb',
    secondaryColor: '#8f67fd',
    appName: 'My App'
  },
  locale: 'en',
  rtl: false,
  onAction: (action) => console.log('Action:', action),
  onError: (error) => console.error('Error:', error)
});

// Step 4: Render the UI
await client.render();

With Custom Branding

const client = new LuqtaClient({
  mode: 'preconfigured',
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  containerId: 'luqta-container',
  user: { email: '[email protected]' },

  // Customize to match your brand
  branding: {
    primaryColor: '#5304fb',      // Main buttons and links
    secondaryColor: '#8f67fd',    // Gradients
    backgroundColor: '#ffffff',   // Page background
    textColor: '#111827',         // Text color
    logoUrl: 'https://yoursite.com/logo.png',
    appName: 'My App',
    borderRadius: 12,             // Rounded corners (px)
    fontFamily: 'Inter, sans-serif'
  },

  // Language settings
  locale: 'en',  // 'en' or 'ar'
  rtl: false,    // true for Arabic

  // Track user actions
  onAction: (action) => {
    console.log('User action:', action.type, action.data);
  },

  // Handle errors
  onError: (error) => {
    console.error('SDK error:', error.message);
  }
});

await client.render();

What the Pre-configured UI Includes

  1. Contest List - Grid of available contests with banners and status
  2. Contest Detail - Full contest info with levels, prizes, and progress
  3. Level Modals - Different UI for each level type:
    • Text: Input field
    • QR: Camera scanner with "Scan Now" button
    • Link: Opens link in new tab
    • Image: Upload area with preview
    • Quiz: Question flow with options
  4. Congratulation Screens - Level and contest completion celebrations
  5. Progress Tracking - Visual progress bars and completed badges

2. Custom UI Mode (API Only)

Best for: Building your own UI design while using SDK for API calls.

Step 1: Create Client

import { LuqtaClient } from 'luqta-sdk';

const client = new LuqtaClient({
  mode: 'custom',
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  user: { email: '[email protected]' }
});

Step 2: Initialize User

// Required before any user-specific API calls
await client.initializeUser();

Step 3: Use API Methods

// Get all contests
const contests = await client.contests.getAll({ page: 1, per_page: 10 });
console.log(contests.data.items);

// Participate in a contest
await client.contests.participate(123);

// Get contest progress with levels
const progress = await client.contests.getProgress(123);
console.log(progress.data.levels);

// Complete a text level
await client.levels.complete(456, { textContent: 'my answer' });

// Complete a QR level
await client.levels.complete(456, { qrCode: 'scanned_data' });

// Complete an image level
await client.levels.completeWithImage(456, 'https://example.com/photo.jpg');

// Start and complete a quiz
const quiz = await client.quiz.start(789);
await client.quiz.submitAnswer(quiz.data.attempt.id, 1, 101);
const results = await client.quiz.submit(quiz.data.attempt.id);

Complete Examples

Example 1: React Integration

import { useEffect, useState } from 'react';
import { LuqtaClient } from 'luqta-sdk';

function LuqtaContests() {
  const [client, setClient] = useState(null);

  useEffect(() => {
    const initClient = async () => {
      const luqtaClient = new LuqtaClient({
        mode: 'preconfigured',
        apiKey: process.env.REACT_APP_LUQTA_API_KEY,
        appId: process.env.REACT_APP_LUQTA_APP_ID,
        containerId: 'luqta-container',
        user: { email: '[email protected]' },
        branding: {
          primaryColor: '#5304fb'
        },
        onAction: (action) => {
          if (action.type === 'level_completed') {
            console.log('Points earned:', action.data.points_earned);
          }
        }
      });

      await luqtaClient.render();
      setClient(luqtaClient);
    };

    initClient();
  }, []);

  return <div id="luqta-container" style={{ minHeight: '600px' }} />;
}

export default LuqtaContests;

Example 2: Vue.js Integration

<template>
  <div id="luqta-container" style="min-height: 600px;"></div>
</template>

<script>
import { LuqtaClient } from 'luqta-sdk';

export default {
  name: 'LuqtaContests',
  data() {
    return {
      client: null
    };
  },
  async mounted() {
    this.client = new LuqtaClient({
      mode: 'preconfigured',
      apiKey: import.meta.env.VITE_LUQTA_API_KEY,
      appId: import.meta.env.VITE_LUQTA_APP_ID,
      containerId: 'luqta-container',
      user: { email: '[email protected]' }
    });

    await this.client.render();
  }
};
</script>

Example 3: Next.js Integration

'use client';
import { useEffect } from 'react';

export default function LuqtaPage() {
  useEffect(() => {
    const initLuqta = async () => {
      // Dynamic import for client-side only
      const { LuqtaClient } = await import('luqta-sdk');

      const client = new LuqtaClient({
        mode: 'preconfigured',
        apiKey: process.env.NEXT_PUBLIC_LUQTA_API_KEY,
        appId: process.env.NEXT_PUBLIC_LUQTA_APP_ID,
        containerId: 'luqta-container',
        user: { email: '[email protected]' }
      });

      await client.render();
    };

    initLuqta();
  }, []);

  return <div id="luqta-container" style={{ minHeight: '600px' }} />;
}

Example 4: Vanilla JavaScript (Full Page)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Luqta Contests</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; background: #f5f5f5; }
    #luqta-container {
      max-width: 900px;
      margin: 20px auto;
      background: white;
      border-radius: 16px;
      min-height: 80vh;
    }
  </style>
</head>
<body>
  <div id="luqta-container"></div>

  <script src="https://unpkg.com/luqta-sdk@latest/dist/luqta-sdk.min.js"></script>
  <script>
    (async function() {
      try {
        const client = new LuqtaSDK.LuqtaClient({
          mode: 'preconfigured',
          apiKey: 'YOUR_API_KEY',
          appId: 'YOUR_APP_ID',
          containerId: 'luqta-container',
          user: { email: '[email protected]' },
          branding: {
            primaryColor: '#5304fb',
            appName: 'My Contests'
          },
          locale: 'en',
          onAction: function(action) {
            console.log('Action:', action.type);

            if (action.type === 'contest_joined') {
              console.log('Joined contest:', action.data.contest_name);
            }

            if (action.type === 'level_completed') {
              console.log('Earned points:', action.data.points_earned);
            }
          }
        });

        await client.render();
        console.log('Luqta SDK loaded successfully!');

      } catch (error) {
        console.error('Failed to load Luqta SDK:', error);
      }
    })();
  </script>
</body>
</html>

Example 5: Arabic RTL Layout

const client = new LuqtaClient({
  mode: 'preconfigured',
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  containerId: 'luqta-container',
  user: { email: '[email protected]' },
  locale: 'ar',  // Arabic language
  rtl: true      // Right-to-left layout
});

await client.render();

Example 6: Step-by-Step with User Sync (New Users)

When integrating with your app where users might not exist in Luqta yet:

const client = new LuqtaSDK.LuqtaClient({
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID'
});

// Step 1: Initialize SDK (no user needed)
await client.initializeSdk();
console.log('SDK ready!');

// Step 2: Set user from your app's auth
client.setUser({
  email: currentUser.email,
  phone_number: currentUser.phone
});

// Step 3: Try to initialize user
try {
  await client.initializeUser();
} catch (error) {
  if (error.code === 'USER_NOT_SYNCED') {
    // User doesn't exist in Luqta - sync them first
    await client.syncAndInitializeUser({
      name: currentUser.name,
      email: currentUser.email,
      phone_number: currentUser.phone,
      gender: currentUser.gender,
      country: currentUser.country
    });
  } else {
    throw error;
  }
}

// Step 4: Configure and render UI
client.configure({
  containerId: 'luqta-container',
  branding: { primaryColor: '#5304fb' }
});

await client.render();

Configuration Options

Required Options

| Option | Type | Description | |--------|------|-------------| | apiKey | string | Your Luqta API key | | appId | string | Your Luqta application ID |

Pre-configured Mode Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | mode | string | - | Must be 'preconfigured' | | containerId | string | - | ID of the HTML container element | | user | object | - | User identification (email or phone) | | branding | object | - | Custom branding options (see below) | | locale | string | 'en' | Language: 'en' or 'ar' | | rtl | boolean | false | Enable right-to-left layout | | onAction | function | - | Callback for user actions | | onError | function | - | Callback for errors |

Branding Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | primaryColor | string | '#5304fb' | Main action color | | secondaryColor | string | '#8f67fd' | Secondary/gradient color | | backgroundColor | string | '#ffffff' | Background color | | textColor | string | '#111827' | Main text color | | logoUrl | string | - | URL to your logo image | | appName | string | - | App name displayed in header | | borderRadius | number | 8 | Border radius in pixels | | fontFamily | string | 'system-ui' | Font family |

User Identification

Provide at least one:

user: {
  email: '[email protected]'
}
// OR
user: {
  phone_number: '+923001234567'  // E.164 format
}
// OR both
user: {
  email: '[email protected]',
  phone_number: '+923001234567'
}

API Reference

SDK Initialization Methods

// Initialize SDK (validates API key and App ID, fetches initial data)
const result = await client.initializeSdk();
// Returns: { success: true, contests: PaginatedResponse<Contest> }

// Check if SDK is ready
const sdkReady = client.isSdkReady();

// Fetch contests (after SDK initialization)
const contests = await client.fetchContests({ page: 1, per_page: 10 });

UI Configuration Methods

// Configure UI settings (for step-by-step initialization)
client.configure({
  containerId: 'luqta-container',
  branding: {
    primaryColor: '#5304fb',
    secondaryColor: '#8f67fd',
    backgroundColor: '#ffffff',
    textColor: '#111827',
    logoUrl: 'https://example.com/logo.png',
    appName: 'My App',
    borderRadius: 12,
    fontFamily: 'Inter, sans-serif'
  },
  locale: 'en',
  rtl: false,
  screens: ['contests', 'quizzes', 'rewards', 'profile'],
  onAction: (action) => console.log(action),
  onError: (error) => console.error(error)
});

// Update branding after initialization
client.setBranding({
  primaryColor: '#ff5722',
  logoUrl: 'https://example.com/new-logo.png'
});

// Get current branding
const branding = client.getBranding();

// Set language
client.setLocale('ar', true); // Arabic with RTL

// Get current locale
const locale = client.getLocale();

// Render UI (for preconfigured mode)
await client.render();

// Refresh UI content
await client.refreshUI();

Contest Methods

// Get all contests (paginated)
const contests = await client.contests.getAll({ page: 1, per_page: 10 });

// Get trending contests
const trending = await client.contests.getTrending();

// Get premium contests
const premium = await client.contests.getPremium();

// Get recent contests
const recent = await client.contests.getRecent();

// Participate in a contest
await client.contests.participate(contestId);

// Participate with access code (for private contests)
await client.contests.participate(contestId, 'ACCESS_CODE');

// Get contest progress with levels
const progress = await client.contests.getProgress(contestId);

// Get contest history
const history = await client.contests.getHistory();

Level Methods

// Complete text level
await client.levels.complete(levelId, { textContent: 'answer' });

// Complete QR level
await client.levels.complete(levelId, { qrCode: 'scanned_data' });

// Complete link level
await client.levels.complete(levelId, { link: 'https://...' });

// Complete image level
await client.levels.completeWithImage(levelId, 'https://image-url.com/photo.jpg');
// OR with base64
await client.levels.completeWithImage(levelId, 'data:image/jpeg;base64,...');

// Get congratulation data after completing a level
const congrats = await client.levels.getCongratulation(levelId, contestId);

Quiz Methods

// Start a quiz
const quiz = await client.quiz.start(quizId);
// Returns: attempt, progress, current_question, full_quiz

// Submit an answer
const result = await client.quiz.submitAnswer(attemptId, questionId, optionId);
// Returns: is_correct, progress, can_proceed

// Submit/complete the quiz
const results = await client.quiz.submit(attemptId);
// Returns: score, grade, statistics

User Management Methods

// Set user identification (before initialization)
client.setUser({
  email: '[email protected]',
  phone_number: '+923001234567'  // Optional
});

// Initialize user session (required for user-specific APIs)
await client.initializeUser();

// Sync user profile data to Luqta
await client.syncUser({
  name: 'John Doe',
  email: '[email protected]',
  phone_number: '+923001234567',
  gender: 'male',
  country: 'PK'
});

// Sync AND initialize in one call (convenience method)
await client.syncAndInitializeUser({
  name: 'John Doe',
  email: '[email protected]',
  phone_number: '+923001234567'
});

// Check if user is initialized
const isReady = client.isInitialized();

Profile Methods

// Get user profile
const profile = await client.profile.get();

// Get user activities
const activities = await client.profile.getActivities();

// Get user progress
const progress = await client.profile.getProgress();

// Submit app feedback
await client.profile.submitFeedback(5, 'Great app!');

Reward Methods

// Get rewards list (no user required)
const rewards = await client.rewards.getList();

// Get user earnings (requires user initialization)
const earnings = await client.rewards.getEarnings();

// Redeem a reward
await client.rewards.redeem(rewardId, points);

// Get reward history
const rewardHistory = await client.rewards.getHistory();

// Get prize history
const prizeHistory = await client.rewards.getPrizeHistory();

Notification Methods

// Get all notifications
const notifications = await client.notifications.getAll();

// Mark notifications as read
await client.notifications.markAsRead([notificationId1, notificationId2]);

// Update notification settings
await client.notifications.updateSettings({
  push_enabled: true,
  email_enabled: false
});

Level Types

The SDK supports 5 level types:

| Type | Description | Completion Method | |------|-------------|-------------------| | text | User enters a text answer | complete(id, { textContent: '...' }) | | qr | User scans a QR code | complete(id, { qrCode: '...' }) | | link | User visits a URL | complete(id, { link: '...' }) | | image | User uploads a photo | completeWithImage(id, 'url') | | quiz | User answers questions | quiz.start(), quiz.submit() |

Pre-configured UI for Each Type

Text Level:

  • Simple input field
  • Submit button

QR Level:

  • QR icon with animated rings
  • "Scan Now" button
  • Opens camera for scanning
  • Fallback manual input

Link Level:

  • Opens URL in new tab
  • Auto-completes on visit

Image Level:

  • Dashed upload area
  • Click to select file
  • Image preview before submit
  • "Upload photo" button

Quiz Level:

  • Question with options
  • Progress indicator
  • Answer feedback
  • Results screen with grade

Error Handling

import { LuqtaClient, LuqtaError } from 'luqta-sdk';

try {
  await client.contests.participate(123);
} catch (error) {
  if (error instanceof LuqtaError) {
    console.error('Error Code:', error.code);
    console.error('Message:', error.message);

    // Handle specific errors
    switch (error.code) {
      case 'USER_NOT_INITIALIZED':
        await client.initializeUser();
        break;
      case 'NETWORK_ERROR':
        alert('Please check your internet connection');
        break;
      default:
        alert(error.message);
    }
  }
}

Common Error Codes

| Code | Meaning | Solution | |------|---------|----------| | MISSING_API_KEY | API key not provided | Add apiKey to config | | MISSING_APP_ID | App ID not provided | Add appId to config | | SDK_NOT_INITIALIZED | SDK not initialized | Call initializeSdk() first | | USER_NOT_INITIALIZED | User session not started | Call initializeUser() first | | USER_NOT_SYNCED | User needs to be synced first | Call syncUser() or syncAndInitializeUser() | | MISSING_USER_CONFIG | No user email/phone provided | Set user in config or call setUser() | | INVALID_EMAIL_FORMAT | Email format invalid | Use valid email | | INVALID_PHONE_FORMAT | Phone format invalid | Use E.164 format (+123...) | | NETWORK_ERROR | No internet connection | Check connection | | TIMEOUT | Request took too long | Try again |


TypeScript Support

The SDK includes full TypeScript definitions:

import {
  LuqtaClient,
  LuqtaError,
  Contest,
  Level,
  Quiz,
  ApiResponse,
  PaginatedResponse,
  BrandingConfig,
  UIConfig,
  UIAction,
  UserProfile,
  UserIdentification
} from 'luqta-sdk';

// Type-safe configuration
const config: PreconfiguredModeConfig = {
  mode: 'preconfigured',
  apiKey: 'key',
  appId: 'app',
  containerId: 'container',
  user: { email: '[email protected]' }
};

const client = new LuqtaClient(config);

// Type-safe responses
const response: PaginatedResponse<Contest> = await client.contests.getAll();
const contests: Contest[] = response.data.items;

FAQ

How do I get API keys?

Contact Luqta support or sign up at luqta.com to get your API key and App ID.

Can I use this without user authentication?

Yes! For public contest listings, you don't need user authentication:

const client = new LuqtaClient({
  mode: 'custom',
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID'
  // No user needed
});

await client.initializeSdk();
const contests = await client.contests.getAll();

How do I change the language?

// Option 1: During initialization
const client = new LuqtaClient({
  // ...
  locale: 'ar',
  rtl: true
});

// Option 2: After initialization
client.setLocale('ar', true);
await client.refreshUI();

How do I track user actions?

const client = new LuqtaClient({
  // ...
  onAction: (action) => {
    switch (action.type) {
      case 'contest_joined':
        analytics.track('Contest Joined', action.data);
        break;
      case 'level_completed':
        analytics.track('Level Completed', action.data);
        break;
      case 'quiz_completed':
        analytics.track('Quiz Completed', action.data);
        break;
    }
  }
});

Does it work with React/Vue/Angular?

Yes! The SDK is framework-agnostic. See the Complete Examples section for framework-specific code.

How do I customize the colors?

const client = new LuqtaClient({
  // ...
  branding: {
    primaryColor: '#FF5722',    // Orange
    secondaryColor: '#FF9800',  // Light orange
    backgroundColor: '#FAFAFA', // Light gray
    textColor: '#212121'        // Dark gray
  }
});

Can I use my own UI?

Yes! Use Custom UI Mode and build your own interface:

const client = new LuqtaClient({
  mode: 'custom',  // API only, no UI
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  user: { email: '[email protected]' }
});

await client.initializeUser();
const contests = await client.contests.getAll();
// Now build your own UI with the data

What's the difference between initializeSdk() and initializeUser()?

  • initializeSdk(): Validates your API key and App ID. No user info needed. Required before fetching contests.
  • initializeUser(): Creates a user session for user-specific actions (participate, complete levels, etc.). Requires email or phone.
// SDK init (app-level) - always do this first
await client.initializeSdk();

// User init (optional) - only if you need user-specific features
await client.initializeUser();

What if I get "USER_NOT_SYNCED" error?

This means the user doesn't exist in Luqta yet. Sync them first:

try {
  await client.initializeUser();
} catch (error) {
  if (error.code === 'USER_NOT_SYNCED') {
    await client.syncAndInitializeUser({
      name: 'User Name',
      email: '[email protected]'
    });
  }
}

Can I configure the UI after creating the client?

Yes! Use the configure() method:

const client = new LuqtaClient({
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID'
});

await client.initializeSdk();

// Configure UI later
client.configure({
  containerId: 'luqta-container',
  branding: { primaryColor: '#5304fb' }
});

await client.render();

Support


License

MIT License - see LICENSE for details.