> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.growthbook.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Lambda@Edge Edge App & SDK

> GrowthBook SDK for Lambda@Edge

export const SdkSupportedFeatures = ({sdk}) => {
  const sdkInfo = {
    js: {
      name: "JS SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-js",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/vanilla-typescript",
        name: "Typescript example app"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.36.0"
      }, {
        prerequisites: "≥ v0.34.0"
      }, {
        stickyBucketing: "≥ v0.32.0"
      }, {
        visualEditorDragDrop: "≥ v0.30.0"
      }, {
        remoteEval: "≥ v0.29.0"
      }, {
        semverTargeting: "≥ v0.27.0"
      }, {
        visualEditorJS: "≥ v0.27.0"
      }, {
        visualEditor: "≥ v0.24.0"
      }, {
        bucketingV2: "≥ v0.23.0"
      }, {
        streaming: "≥ v0.21.0"
      }, {
        encryption: "≥ v0.20.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    react: {
      name: "React SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-react",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/next-js",
        name: "Next.js example app"
      }, {
        url: "https://github.com/growthbook/examples/tree/main/next-js-pages",
        name: "Next.js pages example app"
      }, {
        url: "https://docs.growthbook.io/guide/create-react-app-and-growthbook",
        name: "Create React App guide"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook-react"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.26.0"
      }, {
        prerequisites: "≥ v0.24.0"
      }, {
        stickyBucketing: "≥ v0.22.0"
      }, {
        visualEditorDragDrop: "≥ v0.20.0"
      }, {
        remoteEval: "≥ v0.19.0"
      }, {
        semverTargeting: "≥ v0.17.0"
      }, {
        visualEditorJS: "≥ v0.17.0"
      }, {
        visualEditor: "≥ v0.14.0"
      }, {
        bucketingV2: "≥ v0.13.0"
      }, {
        streaming: "≥ v0.11.0"
      }, {
        encryption: "≥ v0.10.1"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    nextjs: {
      name: "Next.js SDK",
      version: "0.1.0",
      github: "https://github.com/vercel/flags/tree/main/packages/adapter-growthbook",
      examples: [{
        url: "https://github.com/vercel/examples/tree/main/flags-sdk/growthbook",
        name: "Next.js Flags SDK example app"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@flags-sdk/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        savedGroupReferences: "≥ v0.1.0"
      }, {
        redirects: "≥ v0.1.0"
      }, {
        prerequisites: "≥ v0.1.0"
      }, {
        stickyBucketing: "≥ v0.1.0"
      }, {
        semverTargeting: "≥ v0.1.0"
      }, {
        bucketingV2: "≥ v0.1.0"
      }, {
        encryption: "≥ v0.1.0"
      }, {
        looseUnmarshalling: "≥ v0.1.0"
      }, {
        namespacesV2: "≥ v0.1.0"
      }]
    },
    php: {
      name: "PHP SDK",
      version: "2.6.1",
      github: "https://github.com/growthbook/growthbook-php",
      examples: [],
      packageRepos: [{
        name: "Packagist (Composer)",
        url: "https://packagist.org/packages/growthbook/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        remoteEval: "≥ v2.5.0"
      }, {
        trackingPlugin: "≥ v2.4.0"
      }, {
        caseInsensitiveRegex: "≥ v2.3.0"
      }, {
        caseInsensitiveMembership: "≥ v2.3.0"
      }, {
        savedGroupReferences: "≥ v1.7.0"
      }, {
        prerequisites: "≥ v1.6.0"
      }, {
        stickyBucketing: "≥ v1.6.0"
      }, {
        semverTargeting: "≥ v1.5.0"
      }, {
        bucketingV2: "≥ v1.2.0"
      }, {
        encryption: "≥ v1.2.0"
      }, {
        looseUnmarshalling: "≥ v1.0.0"
      }, {
        namespacesV2: "≥ v1.0.0"
      }]
    },
    node: {
      name: "Node SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-js",
      examples: [{
        url: "https://docs.growthbook.io/guide/express-js",
        name: "Express.js guide"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.36.0"
      }, {
        prerequisites: "≥ v0.34.0"
      }, {
        stickyBucketing: "≥ v0.32.0"
      }, {
        semverTargeting: "≥ v0.27.0"
      }, {
        bucketingV2: "≥ v0.23.0"
      }, {
        streaming: "≥ v0.21.0"
      }, {
        encryption: "≥ v0.20.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    ruby: {
      name: "Ruby SDK",
      version: "1.3.0",
      github: "https://github.com/growthbook/growthbook-ruby",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/acme_donuts_rails",
        name: "Rails example app"
      }],
      packageRepos: [{
        name: "RubyGems",
        url: "https://rubygems.org/gems/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        prerequisites: "≥ v1.3.0"
      }, {
        stickyBucketing: "≥ v1.3.0"
      }, {
        semverTargeting: "≥ v1.2.2"
      }, {
        encryption: "≥ v1.1.0"
      }, {
        bucketingV2: "≥ v1.0.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    python: {
      name: "Python SDK",
      version: "2.4.0",
      github: "https://github.com/growthbook/growthbook-python",
      examples: [],
      packageRepos: [{
        name: "PyPi",
        url: "https://pypi.org/project/growthbook/"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        remoteEval: "≥ v2.3.0"
      }, {
        trackingPlugin: "≥ v2.2.0"
      }, {
        caseInsensitiveMembership: "≥ v2.1.1"
      }, {
        caseInsensitiveRegex: "≥ v2.1.0"
      }, {
        savedGroupReferences: "≥ v1.2.1"
      }, {
        looseUnmarshalling: "≥ v1.1.0"
      }, {
        namespacesV2: "≥ v1.1.0"
      }, {
        prerequisites: "≥ v1.1.0"
      }, {
        stickyBucketing: "≥ v1.1.0"
      }, {
        semverTargeting: "≥ v1.1.0"
      }, {
        bucketingV2: "≥ v1.0.0"
      }, {
        encryption: "≥ v1.0.0"
      }]
    },
    go: {
      name: "Go SDK",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-golang",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/go-example",
        name: "Go example app"
      }],
      packageRepos: [{
        name: "Go Modules",
        url: "https://pkg.go.dev/github.com/growthbook/growthbook-golang"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        trackingPlugin: "≥ v0.2.8"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        stickyBucketing: "≥ v0.2.3"
      }, {
        prerequisites: "≥ v0.2.0"
      }, {
        savedGroupReferences: "≥ v0.2.0"
      }, {
        bucketingV2: "≥ v0.1.4"
      }, {
        streaming: "≥ v0.1.4"
      }, {
        semverTargeting: "≥ v0.1.4"
      }, {
        encryption: "≥ v0.1.4"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    rust: {
      name: "Rust SDK",
      version: "0.2.1",
      github: "https://github.com/growthbook/growthbook-rust",
      examples: [{
        url: "https://github.com/growthbook/growthbook-rust/tree/main/examples/client",
        name: "Rust example app"
      }],
      packageRepos: [{
        name: "crates.io",
        url: "https://crates.io/crates/growthbook-rust"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        savedGroupReferences: "≥ v0.2.0"
      }, {
        caseInsensitiveRegex: "≥ v0.1.1"
      }, {
        caseInsensitiveMembership: "≥ v0.1.1"
      }, {
        stickyBucketing: "≥ v0.1.0"
      }, {
        encryption: "≥ v0.0.1"
      }, {
        looseUnmarshalling: "≥ v0.0.1"
      }, {
        namespacesV2: "≥ v0.0.1"
      }, {
        prerequisites: "≥ v0.0.1"
      }, {
        semverTargeting: "≥ v0.0.1"
      }, {
        bucketingV2: "≥ v0.0.1"
      }]
    },
    java: {
      name: "Java SDK",
      version: "0.10.10",
      github: "https://github.com/growthbook/growthbook-sdk-java",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/jvm-spring-web",
        name: "JVM with Spring Web example app"
      }, {
        url: "https://github.com/growthbook/examples/tree/main/jvm-kotlin-ktor-example",
        name: "JVM with Kotlin Ktor example app"
      }, {
        url: "https://github.com/growthbook/examples/tree/main/android-example",
        name: "Android example app"
      }, {
        url: "https://growthbook.github.io/growthbook-sdk-java/",
        name: "JavaDoc class docs"
      }],
      packageRepos: [{
        name: "JitPack",
        url: "https://jitpack.io/#growthbook/growthbook-sdk-java"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveMembership: "≥ v0.10.9"
      }, {
        caseInsensitiveRegex: "≥ v0.10.6"
      }, {
        remoteEval: "≥ v0.9.92"
      }, {
        prerequisites: "≥ v0.9.3"
      }, {
        stickyBucketing: "≥ v0.9.3"
      }, {
        streaming: "≥ v0.9.0"
      }, {
        semverTargeting: "≥ v0.7.0"
      }, {
        bucketingV2: "≥ v0.6.0"
      }, {
        encryption: "≥ v0.3.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    csharp: {
      name: "C# SDK",
      version: "1.2.0",
      github: "https://github.com/growthbook/growthbook-c-sharp",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/csharp-example/GrowthBookCSharpExamples",
        name: "C# example app"
      }],
      packageRepos: [{
        name: "NuGet",
        url: "https://www.nuget.org/packages/growthbook-c-sharp"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveMembership: "≥ v1.2.0"
      }, {
        caseInsensitiveRegex: "≥ v1.2.0"
      }, {
        remoteEval: "≥ v1.1.3"
      }, {
        stickyBucketing: "≥ v1.1.0"
      }, {
        prerequisites: "≥ v1.1.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        encryption: "≥ v1.0.0"
      }, {
        streaming: "≥ v1.0.0"
      }, {
        bucketingV2: "≥ v1.0.0"
      }, {
        semverTargeting: "≥ v1.0.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    elixir: {
      name: "Elixir SDK",
      version: "0.3.0",
      github: "https://github.com/growthbook/growthbook-elixir",
      examples: [],
      packageRepos: [{
        name: "Hex",
        url: "https://www.hex.pm/packages/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        encryption: "≥ v0.3.0"
      }, {
        prerequisites: "≥ v0.2.0"
      }, {
        semverTargeting: "≥ v0.2.0"
      }, {
        bucketingV2: "≥ v0.2.0"
      }, {
        looseUnmarshalling: "≥ v0.2.0"
      }, {
        namespacesV2: "≥ v0.2.0"
      }]
    },
    kotlin: {
      name: "Kotlin SDK",
      version: "7.6.0",
      github: "https://github.com/growthbook/growthbook-kotlin",
      examples: [],
      packageRepos: [{
        name: "Maven Central",
        url: "https://mvnrepository.com/artifact/io.growthbook.sdk/GrowthBook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveMembership: "≥ v7.1.1"
      }, {
        caseInsensitiveRegex: "≥ v7.1.1"
      }, {
        remoteEval: "≥ v1.1.50"
      }, {
        streaming: "≥ v1.1.50"
      }, {
        prerequisites: "≥ v1.1.44"
      }, {
        stickyBucketing: "≥ v1.1.44"
      }, {
        bucketingV2: "≥ v1.1.38"
      }, {
        semverTargeting: "≥ v1.1.31"
      }, {
        encryption: "≥ v1.1.23"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    swift: {
      name: "Swift SDK",
      version: "1.2.0",
      github: "https://github.com/growthbook/growthbook-swift",
      examples: [],
      packageRepos: [{
        name: "Swift Package Manager (SPM)",
        url: "https://swiftpackageindex.com/growthbook/growthbook-swift"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        namespacesV2: "≥ v1.1.4"
      }, {
        caseInsensitiveMembership: "≥ v1.1.1"
      }, {
        caseInsensitiveRegex: "≥ v1.1.1"
      }, {
        remoteEval: "≥ v1.0.50"
      }, {
        stickyBucketing: "≥ v1.0.49"
      }, {
        prerequisites: "≥ v1.0.49"
      }, {
        bucketingV2: "≥ v1.0.43"
      }, {
        streaming: "≥ v1.0.43"
      }, {
        semverTargeting: "≥ v1.0.38"
      }, {
        encryption: "≥ v1.0.35"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }]
    },
    reactNative: {
      name: "React Native SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-react",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/react-native-cli",
        name: "React Native CLI example app"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook-react"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.26.0"
      }, {
        prerequisites: "≥ v0.24.0"
      }, {
        stickyBucketing: "≥ v0.22.0"
      }, {
        visualEditorDragDrop: "≥ v0.20.0"
      }, {
        remoteEval: "≥ v0.19.0"
      }, {
        semverTargeting: "≥ v0.17.0"
      }, {
        visualEditorJS: "≥ v0.17.0"
      }, {
        visualEditor: "≥ v0.14.0"
      }, {
        bucketingV2: "≥ v0.13.0"
      }, {
        streaming: "≥ v0.11.0"
      }, {
        encryption: "≥ v0.10.1"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    edgeCloudflare: {
      name: "Cloudflare Workers App & SDK",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-cloudflare",
      examples: [{
        url: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-cloudflare/example",
        name: "Example worker"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-cloudflare"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        savedGroupReferences: "≥ v0.1.12"
      }, {
        looseUnmarshalling: "≥ v0.1.11"
      }, {
        namespacesV2: "≥ v0.1.11"
      }, {
        encryption: "≥ v0.1.11"
      }, {
        streaming: "≥ v0.1.11"
      }, {
        bucketingV2: "≥ v0.1.11"
      }, {
        visualEditor: "≥ v0.1.11"
      }, {
        semverTargeting: "≥ v0.1.11"
      }, {
        visualEditorJS: "≥ v0.1.11"
      }, {
        visualEditorDragDrop: "≥ v0.1.11"
      }, {
        prerequisites: "≥ v0.1.11"
      }, {
        redirects: "≥ v0.1.11"
      }, {
        stickyBucketing: "≥ v0.1.11"
      }]
    },
    edgeFastly: {
      name: "Fastly Compute App & SDK",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-fastly",
      examples: [{
        url: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-fastly/example",
        name: "Example compute worker"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-fastly"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        savedGroupReferences: "≥ v0.1.6"
      }, {
        looseUnmarshalling: "≥ v0.1.5"
      }, {
        namespacesV2: "≥ v0.1.5"
      }, {
        encryption: "≥ v0.1.5"
      }, {
        streaming: "≥ v0.1.5"
      }, {
        bucketingV2: "≥ v0.1.5"
      }, {
        visualEditor: "≥ v0.1.5"
      }, {
        semverTargeting: "≥ v0.1.5"
      }, {
        visualEditorJS: "≥ v0.1.5"
      }, {
        visualEditorDragDrop: "≥ v0.1.5"
      }, {
        prerequisites: "≥ v0.1.5"
      }, {
        redirects: "≥ v0.1.5"
      }, {
        stickyBucketing: "≥ v0.1.5"
      }]
    },
    edgeLambda: {
      name: "Lambda@Edge App & SDK",
      version: "0.0.29",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-lambda",
      examples: [],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-lambda"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.0.27"
      }, {
        caseInsensitiveMembership: "≥ v0.0.27"
      }, {
        savedGroupReferences: "≥ v0.0.7"
      }, {
        looseUnmarshalling: "≥ v0.0.6"
      }, {
        namespacesV2: "≥ v0.0.6"
      }, {
        encryption: "≥ v0.0.6"
      }, {
        streaming: "≥ v0.0.6"
      }, {
        bucketingV2: "≥ v0.0.6"
      }, {
        visualEditor: "≥ v0.0.6"
      }, {
        semverTargeting: "≥ v0.0.6"
      }, {
        visualEditorJS: "≥ v0.0.6"
      }, {
        visualEditorDragDrop: "≥ v0.0.6"
      }, {
        prerequisites: "≥ v0.0.6"
      }, {
        redirects: "≥ v0.0.6"
      }, {
        stickyBucketing: "≥ v0.0.6"
      }]
    },
    edgeUtils: {
      name: "Edge Utils",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-utils",
      examples: [],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-utils"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        savedGroupReferences: "≥ v0.1.5"
      }, {
        looseUnmarshalling: "≥ v0.1.4"
      }, {
        namespacesV2: "≥ v0.1.4"
      }, {
        encryption: "≥ v0.1.4"
      }, {
        streaming: "≥ v0.1.4"
      }, {
        bucketingV2: "≥ v0.1.4"
      }, {
        visualEditor: "≥ v0.1.4"
      }, {
        semverTargeting: "≥ v0.1.4"
      }, {
        visualEditorJS: "≥ v0.1.4"
      }, {
        visualEditorDragDrop: "≥ v0.1.4"
      }, {
        prerequisites: "≥ v0.1.4"
      }, {
        redirects: "≥ v0.1.4"
      }, {
        stickyBucketing: "≥ v0.1.4"
      }]
    },
    flutter: {
      name: "Flutter SDK",
      version: "4.4.0",
      github: "https://github.com/growthbook/growthbook-flutter",
      examples: [],
      packageRepos: [{
        name: "pub.dev",
        url: "https://pub.dev/packages/growthbook_sdk_flutter"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        trackingPlugin: "≥ v4.4.0"
      }, {
        caseInsensitiveRegex: "≥ v4.3.0"
      }, {
        caseInsensitiveMembership: "≥ v4.3.0"
      }, {
        savedGroupReferences: "≥ v3.9.4"
      }, {
        stickyBucketing: "≥ v3.8.0"
      }, {
        remoteEval: "≥ v3.7.0"
      }, {
        streaming: "≥ v3.4.0"
      }, {
        prerequisites: "≥ v3.2.0"
      }, {
        encryption: "≥ v3.1.0"
      }, {
        bucketingV2: "≥ v3.1.0"
      }, {
        semverTargeting: "≥ v3.1.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    roku: {
      name: "Roku SDK",
      version: "1.4.1",
      github: "https://github.com/growthbook/growthbook-roku",
      examples: [{
        url: "https://github.com/growthbook/growthbook-roku/tree/main/examples",
        name: "Roku examples"
      }, {
        url: "https://www.npmjs.com/package/growthbook-roku",
        name: "npm package"
      }],
      packageRepos: [],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        encryption: "≥ v1.4.1"
      }, {
        stickyBucketing: "≥ v1.4.1"
      }, {
        prerequisites: "≥ v1.3.0"
      }, {
        looseUnmarshalling: "≥ v1.3.0"
      }, {
        namespacesV2: "≥ v1.3.0"
      }, {
        semverTargeting: "≥ v1.3.0"
      }, {
        bucketingV2: "≥ v1.3.0"
      }]
    }
  };
  const capabilityDetails = {
    features: {
      label: "Features",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M42.76,50A8,8,0,0,0,40,56V224a8,8,0,0,0,16,0V179.77c26.79-21.16,49.87-9.75,76.45,3.41,16.4,8.11,34.06,16.85,53,16.85,13.93,0,28.54-4.75,43.82-18a8,8,0,0,0,2.76-6V56A8,8,0,0,0,218.76,50c-28,24.23-51.72,12.49-79.21-1.12C111.07,34.76,78.78,18.79,42.76,50ZM216,172.25c-26.79,21.16-49.87,9.74-76.45-3.41-25-12.35-52.81-26.13-83.55-8.4V59.79c26.79-21.16,49.87-9.75,76.45,3.4,25,12.35,52.82,26.13,83.55,8.4Z" />
        </svg>
    },
    experimentation: {
      label: "Experimentation",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M221.69,199.77,160,96.92V40h8a8,8,0,0,0,0-16H88a8,8,0,0,0,0,16h8V96.92L34.31,199.77A16,16,0,0,0,48,224H208a16,16,0,0,0,13.72-24.23ZM110.86,103.25A7.93,7.93,0,0,0,112,99.14V40h32V99.14a7.93,7.93,0,0,0,1.14,4.11L183.36,167c-12,2.37-29.07,1.37-51.75-10.11-15.91-8.05-31.05-12.32-45.22-12.81ZM48,208l28.54-47.58c14.25-1.74,30.31,1.85,47.82,10.72,19,9.61,35,12.88,48,12.88a69.89,69.89,0,0,0,19.55-2.7L208,208Z" />
        </svg>
    },
    encryption: {
      label: "Encrypted Features",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Zm-68-56a12,12,0,1,1-12-12A12,12,0,0,1,140,152Z" />
        </svg>
    },
    streaming: {
      label: "Streaming",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M135.16,84.42a8,8,0,0,0-14.32,0l-72,144a8,8,0,0,0,14.31,7.16L77,208h102.1l13.79,27.58A8,8,0,0,0,200,240a8,8,0,0,0,7.15-11.58ZM128,105.89,155.06,160H100.94ZM85,192l8-16h70.1l8,16Zm74.54-98.26a32,32,0,1,0-63,0,8,8,0,1,1-15.74,2.85,48,48,0,1,1,94.46,0,8,8,0,0,1-7.86,6.58,8.74,8.74,0,0,1-1.43-.13A8,8,0,0,1,159.49,93.74ZM64.15,136.21a80,80,0,1,1,127.7,0,8,8,0,0,1-12.76-9.65,64,64,0,1,0-102.18,0,8,8,0,0,1-12.76,9.65Z" />
        </svg>
    },
    bucketingV2: {
      label: "v2 Hashing",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M224,88H175.4l8.47-46.57a8,8,0,0,0-15.74-2.86l-9,49.43H111.4l8.47-46.57a8,8,0,0,0-15.74-2.86L95.14,88H48a8,8,0,0,0,0,16H92.23L83.5,152H32a8,8,0,0,0,0,16H80.6l-8.47,46.57a8,8,0,0,0,6.44,9.3A7.79,7.79,0,0,0,80,224a8,8,0,0,0,7.86-6.57l9-49.43H144.6l-8.47,46.57a8,8,0,0,0,6.44,9.3A7.79,7.79,0,0,0,144,224a8,8,0,0,0,7.86-6.57l9-49.43H208a8,8,0,0,0,0-16H163.77l8.73-48H224a8,8,0,0,0,0-16Zm-76.5,64H99.77l8.73-48h47.73Z" />
        </svg>
    },
    visualEditor: {
      label: "Visual Editor",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M208,40H48A24,24,0,0,0,24,64V176a24,24,0,0,0,24,24H208a24,24,0,0,0,24-24V64A24,24,0,0,0,208,40Zm8,136a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V64a8,8,0,0,1,8-8H208a8,8,0,0,1,8,8Zm-48,48a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,224Z" />
        </svg>
    },
    semverTargeting: {
      label: "SemVer Targeting",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M208,112a32.05,32.05,0,0,0-30.69,23l-42.21-6a8,8,0,0,1-4.95-2.71L94.43,84.55A32,32,0,1,0,72,87v82a32,32,0,1,0,16,0V101.63l30,35a24,24,0,0,0,14.83,8.14l44,6.28A32,32,0,1,0,208,112ZM64,56A16,16,0,1,1,80,72,16,16,0,0,1,64,56ZM96,200a16,16,0,1,1-16-16A16,16,0,0,1,96,200Zm112-40a16,16,0,1,1,16-16A16,16,0,0,1,208,160Z" />
        </svg>
    },
    visualEditorJS: {
      label: "Visual Editor (JS)",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40v72a8,8,0,0,0,16,0V40h88V88a8,8,0,0,0,8,8h48V216H176a8,8,0,0,0,0,16h24a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160Zm-12.19,145a20.82,20.82,0,0,1-9.19,15.23C133.43,215,127,216,121.13,216a61.34,61.34,0,0,1-15.19-2,8,8,0,0,1,4.31-15.41c4.38,1.2,15,2.7,19.55-.36.88-.59,1.83-1.52,2.14-3.93.34-2.67-.71-4.1-12.78-7.59-9.35-2.7-25-7.23-23-23.11a20.56,20.56,0,0,1,9-14.95c11.84-8,30.71-3.31,32.83-2.76a8,8,0,0,1-4.07,15.48c-4.49-1.17-15.23-2.56-19.83.56a4.54,4.54,0,0,0-2,3.67c-.12.9-.14,1.09,1.11,1.9,2.31,1.49,6.45,2.68,10.45,3.84C133.49,174.17,150.05,179,147.81,196.31ZM80,152v38a26,26,0,0,1-52,0,8,8,0,0,1,16,0,10,10,0,0,0,20,0V152a8,8,0,0,1,16,0Z" />
        </svg>
    },
    remoteEval: {
      label: "Remote Evaluation",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M160,40A88.09,88.09,0,0,0,81.29,88.67,64,64,0,1,0,72,216h88a88,88,0,0,0,0-176Zm0,160H72a48,48,0,0,1,0-96c1.1,0,2.2,0,3.29.11A88,88,0,0,0,72,128a8,8,0,0,0,16,0,72,72,0,1,1,72,72Z" />
        </svg>
    },
    visualEditorDragDrop: {
      label: "Visual Editor Drag & Drop",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M188,80a27.79,27.79,0,0,0-13.36,3.4,28,28,0,0,0-46.64-11A28,28,0,0,0,80,92v20H68a28,28,0,0,0-28,28v12a88,88,0,0,0,176,0V108A28,28,0,0,0,188,80Zm12,72a72,72,0,0,1-144,0V140a12,12,0,0,1,12-12H80v24a8,8,0,0,0,16,0V92a12,12,0,0,1,24,0v28a8,8,0,0,0,16,0V92a12,12,0,0,1,24,0v28a8,8,0,0,0,16,0V108a12,12,0,0,1,24,0Z" />
        </svg>
    },
    stickyBucketing: {
      label: "Sticky Bucketing",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M223.68,66.15,135.68,18h0a15.88,15.88,0,0,0-15.36,0l-88,48.17a16,16,0,0,0-8.32,14v95.64a16,16,0,0,0,8.32,14l88,48.17a15.88,15.88,0,0,0,15.36,0l88-48.17a16,16,0,0,0,8.32-14V80.18A16,16,0,0,0,223.68,66.15ZM128,32h0l80.34,44L128,120,47.66,76ZM40,90l80,43.78v85.79L40,175.82Zm96,129.57V133.82L216,90v85.78Z" />
        </svg>
    },
    redirects: {
      label: "URL Redirects",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M240,88.23a54.43,54.43,0,0,1-16,37L189.25,160a54.27,54.27,0,0,1-38.63,16h-.05A54.63,54.63,0,0,1,96,119.84a8,8,0,0,1,16,.45A38.62,38.62,0,0,0,150.58,160h0a38.39,38.39,0,0,0,27.31-11.31l34.75-34.75a38.63,38.63,0,0,0-54.63-54.63l-11,11A8,8,0,0,1,135.7,59l11-11A54.65,54.65,0,0,1,224,48,54.86,54.86,0,0,1,240,88.23ZM109,185.66l-11,11A38.41,38.41,0,0,1,70.6,208h0a38.63,38.63,0,0,1-27.29-65.94L78,107.31A38.63,38.63,0,0,1,144,135.71a8,8,0,0,0,16,.45A54.86,54.86,0,0,0,144,96a54.65,54.65,0,0,0-77.27,0L32,130.75A54.62,54.62,0,0,0,70.56,224h0a54.28,54.28,0,0,0,38.64-16l11-11A8,8,0,0,0,109,185.66Z" />
        </svg>
    },
    prerequisites: {
      label: "Prerequisites",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M176,152h32a16,16,0,0,0,16-16V104a16,16,0,0,0-16-16H176a16,16,0,0,0-16,16v8H88V80h8a16,16,0,0,0,16-16V32A16,16,0,0,0,96,16H64A16,16,0,0,0,48,32V64A16,16,0,0,0,64,80h8V192a24,24,0,0,0,24,24h64v8a16,16,0,0,0,16,16h32a16,16,0,0,0,16-16V192a16,16,0,0,0-16-16H176a16,16,0,0,0-16,16v8H96a8,8,0,0,1-8-8V128h72v8A16,16,0,0,0,176,152ZM64,32H96V64H64ZM176,192h32v32H176Zm0-88h32v32H176Z" />
        </svg>
    },
    savedGroupReferences: {
      label: "Saved Group References",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M88,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H96A8,8,0,0,1,88,64Zm128,56H96a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Zm0,64H96a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16ZM56,56H40a8,8,0,0,0,0,16H56a8,8,0,0,0,0-16Zm0,64H40a8,8,0,0,0,0,16H56a8,8,0,0,0,0-16Zm0,64H40a8,8,0,0,0,0,16H56a8,8,0,0,0,0-16Z" />
        </svg>
    },
    caseInsensitiveRegex: {
      label: "Case Insensitive Regex",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M87.24,52.59a8,8,0,0,0-14.48,0l-64,136a8,8,0,1,0,14.48,6.81L39.9,160h80.2l16.66,35.4a8,8,0,1,0,14.48-6.81ZM47.43,144,80,74.79,112.57,144ZM200,96c-12.76,0-22.73,3.47-29.63,10.32a8,8,0,0,0,11.26,11.36c3.8-3.77,10-5.68,18.37-5.68,13.23,0,24,9,24,20v3.22A42.76,42.76,0,0,0,200,128c-22.06,0-40,16.15-40,36s17.94,36,40,36a42.73,42.73,0,0,0,24-7.25,8,8,0,0,0,16-.75V132C240,112.15,222.06,96,200,96Zm0,88c-13.23,0-24-9-24-20s10.77-20,24-20,24,9,24,20S213.23,184,200,184Z" />
        </svg>
    },
    caseInsensitiveMembership: {
      label: "Case Insensitive Membership",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M174.63,81.37a80,80,0,1,0-93.26,93.26,80,80,0,1,0,93.26-93.26ZM224,160c0,1.52-.07,3-.18,4.51l-50-50A80,80,0,0,0,176,98,64.11,64.11,0,0,1,224,160Zm-13.47,39.21L157.91,146.6a80.5,80.5,0,0,0,9.93-15.44L219.7,183A64,64,0,0,1,210.53,199.21ZM183,219.7l-51.86-51.86a80.5,80.5,0,0,0,15.44-9.93l52.61,52.62A64,64,0,0,1,183,219.7ZM45.47,56.79,98.09,109.4a80.5,80.5,0,0,0-9.93,15.44L36.3,73A64,64,0,0,1,45.47,56.79ZM73,36.3l51.86,51.86a80.5,80.5,0,0,0-15.44,9.93L56.79,45.47A64,64,0,0,1,73,36.3ZM160,96a64.07,64.07,0,0,1-64,64A64.07,64.07,0,0,1,160,96Zm-2-16a80,80,0,0,0-16.49,2.13l-50-50C93,32.07,94.48,32,96,32A64.11,64.11,0,0,1,158,80.05ZM32,96c0-1.52.07-3,.18-4.51l50,50A80,80,0,0,0,80.05,158,64.11,64.11,0,0,1,32,96ZM98,176a80,80,0,0,0,16.49-2.13l50,50c-1.49.11-3,.18-4.51.18A64.11,64.11,0,0,1,98,176Z" />
        </svg>
    },
    contextualBandits: {
      label: "Contextual Bandits",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M117.25,157.92a60,60,0,1,0-66.5,0A95.83,95.83,0,0,0,3.53,195.63a8,8,0,1,0,13.4,8.74,80,80,0,0,1,134.14,0,8,8,0,0,0,13.4-8.74A95.83,95.83,0,0,0,117.25,157.92ZM40,108a44,44,0,1,1,44,44A44.05,44.05,0,0,1,40,108Zm210.14,98.23a8,8,0,0,1-11.07-2.33A79.83,79.83,0,0,0,172,168a8,8,0,0,1,0-16,44,44,0,1,0-16.34-84.87,8,8,0,1,1-5.94-14.85,60,60,0,0,1,55.53,105.64,95.83,95.83,0,0,1,47.22,31.95A8,8,0,0,1,250.14,206.23Z" />
        </svg>
    },
    trackingPlugin: {
      label: "Tracking Plugin",
      icon: () => <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
          <path d="M240,128a8,8,0,0,1-8,8H204.94l-37.78,75.58A8,8,0,0,1,160,216h-.4a8,8,0,0,1-7.08-5.14L95.35,60.76,63.28,131.31A8,8,0,0,1,56,136H24a8,8,0,0,1,0-16H50.46L88.62,36.69a8,8,0,0,1,14.76.46L160.46,187,187.06,136H232A8,8,0,0,1,240,128Z" />
        </svg>
    }
  };
  const capabilities = (sdkInfo[sdk].capabilities || []).filter(cap => {
    const feature = Object.keys(cap)[0];
    return !cap.looseUnmarshalling && capabilityDetails[feature];
  }).map(cap => {
    const feature = Object.keys(cap)[0];
    return {
      feature,
      version: cap[feature]
    };
  });
  return <div className="flex flex-row flex-wrap gap-[10px] mb-4">
      {capabilities.map(({feature, version}) => <div key={feature} className="inline-flex flex-row gap-[6px] items-center bg-[var(--slate-a3)] rounded-full px-3 h-7 text-[14px] leading-none dark:text-[#f5f7f5]">
          <span className="inline-flex items-center justify-center w-4 h-4 shrink-0 [&_svg]:w-full [&_svg]:h-full [&_svg]:fill-current">
            {capabilityDetails[feature].icon()}
          </span>
          <span className="group relative cursor-pointer">
            {capabilityDetails[feature].label}
            <span className="invisible opacity-0 transition-opacity duration-200 group-hover:visible group-hover:opacity-100 absolute bottom-[calc(100%+6px)] left-1/2 -translate-x-1/2 w-max max-w-[220px] bg-[#444] text-white text-[13px] text-center rounded px-[10px] py-[6px] z-10 pointer-events-none group-hover:pointer-events-auto shadow-md after:content-[''] after:absolute after:top-full after:left-1/2 after:-translate-x-1/2 after:border-[6px] after:border-solid after:border-transparent after:border-t-[#444]">
              {version}
            </span>
          </span>
        </div>)}
    </div>;
};

export const SdkResources = ({sdk}) => {
  const GitHubLogo = () => {
    return <svg viewBox="0 0 128 128">
        <g fill="currentColor">
          <path fillRule="evenodd" clipRule="evenodd" d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"></path>
          <path d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"></path>
        </g>
      </svg>;
  };
  const SlackLogo = () => {
    return <svg viewBox="0 0 128 128">
        <path d="M27.255 80.719c0 7.33-5.978 13.317-13.309 13.317C6.616 94.036.63 88.049.63 80.719s5.987-13.317 13.317-13.317h13.309zm6.709 0c0-7.33 5.987-13.317 13.317-13.317s13.317 5.986 13.317 13.317v33.335c0 7.33-5.986 13.317-13.317 13.317-7.33 0-13.317-5.987-13.317-13.317zm0 0" fill="#de1c59"></path>
        <path d="M47.281 27.255c-7.33 0-13.317-5.978-13.317-13.309C33.964 6.616 39.951.63 47.281.63s13.317 5.987 13.317 13.317v13.309zm0 6.709c7.33 0 13.317 5.987 13.317 13.317s-5.986 13.317-13.317 13.317H13.946C6.616 60.598.63 54.612.63 47.281c0-7.33 5.987-13.317 13.317-13.317zm0 0" fill="#35c5f0"></path>
        <path d="M100.745 47.281c0-7.33 5.978-13.317 13.309-13.317 7.33 0 13.317 5.987 13.317 13.317s-5.987 13.317-13.317 13.317h-13.309zm-6.709 0c0 7.33-5.987 13.317-13.317 13.317s-13.317-5.986-13.317-13.317V13.946C67.402 6.616 73.388.63 80.719.63c7.33 0 13.317 5.987 13.317 13.317zm0 0" fill="#2eb57d"></path>
        <path d="M80.719 100.745c7.33 0 13.317 5.978 13.317 13.309 0 7.33-5.987 13.317-13.317 13.317s-13.317-5.987-13.317-13.317v-13.309zm0-6.709c-7.33 0-13.317-5.987-13.317-13.317s5.986-13.317 13.317-13.317h33.335c7.33 0 13.317 5.986 13.317 13.317 0 7.33-5.987 13.317-13.317 13.317zm0 0" fill="#ebb02e"></path>
      </svg>;
  };
  const CodeLogos = ({name}) => {
    switch (name) {
      case "js":
        return <svg viewBox="0 0 128 128">
            <path fill="#F0DB4F" d="M1.408 1.408h125.184v125.185H1.408z"></path>
            <path fill="#323330" d="M116.347 96.736c-.917-5.711-4.641-10.508-15.672-14.981-3.832-1.761-8.104-3.022-9.377-5.926-.452-1.69-.512-2.642-.226-3.665.821-3.32 4.784-4.355 7.925-3.403 2.023.678 3.938 2.237 5.093 4.724 5.402-3.498 5.391-3.475 9.163-5.879-1.381-2.141-2.118-3.129-3.022-4.045-3.249-3.629-7.676-5.498-14.756-5.355l-3.688.477c-3.534.893-6.902 2.748-8.877 5.235-5.926 6.724-4.236 18.492 2.975 23.335 7.104 5.332 17.54 6.545 18.873 11.531 1.297 6.104-4.486 8.08-10.234 7.378-4.236-.881-6.592-3.034-9.139-6.949-4.688 2.713-4.688 2.713-9.508 5.485 1.143 2.499 2.344 3.63 4.26 5.795 9.068 9.198 31.76 8.746 35.83-5.176.165-.478 1.261-3.666.38-8.581zM69.462 58.943H57.753l-.048 30.272c0 6.438.333 12.34-.714 14.149-1.713 3.558-6.152 3.117-8.175 2.427-2.059-1.012-3.106-2.451-4.319-4.485-.333-.584-.583-1.036-.667-1.071l-9.52 5.83c1.583 3.249 3.915 6.069 6.902 7.901 4.462 2.678 10.459 3.499 16.731 2.059 4.082-1.189 7.604-3.652 9.448-7.401 2.666-4.915 2.094-10.864 2.07-17.444.06-10.735.001-21.468.001-32.237z"></path>
          </svg>;
      case "react":
      case "reactNative":
        return <svg viewBox="0 0 128 128">
            <g fill="#61DAFB">
              <circle cx="64" cy="64" r="11.4"></circle>
              <path d="M107.3 45.2c-2.2-.8-4.5-1.6-6.9-2.3.6-2.4 1.1-4.8 1.5-7.1 2.1-13.2-.2-22.5-6.6-26.1-1.9-1.1-4-1.6-6.4-1.6-7 0-15.9 5.2-24.9 13.9-9-8.7-17.9-13.9-24.9-13.9-2.4 0-4.5.5-6.4 1.6-6.4 3.7-8.7 13-6.6 26.1.4 2.3.9 4.7 1.5 7.1-2.4.7-4.7 1.4-6.9 2.3C8.2 50 1.4 56.6 1.4 64s6.9 14 19.3 18.8c2.2.8 4.5 1.6 6.9 2.3-.6 2.4-1.1 4.8-1.5 7.1-2.1 13.2.2 22.5 6.6 26.1 1.9 1.1 4 1.6 6.4 1.6 7.1 0 16-5.2 24.9-13.9 9 8.7 17.9 13.9 24.9 13.9 2.4 0 4.5-.5 6.4-1.6 6.4-3.7 8.7-13 6.6-26.1-.4-2.3-.9-4.7-1.5-7.1 2.4-.7 4.7-1.4 6.9-2.3 12.5-4.8 19.3-11.4 19.3-18.8s-6.8-14-19.3-18.8zM92.5 14.7c4.1 2.4 5.5 9.8 3.8 20.3-.3 2.1-.8 4.3-1.4 6.6-5.2-1.2-10.7-2-16.5-2.5-3.4-4.8-6.9-9.1-10.4-13 7.4-7.3 14.9-12.3 21-12.3 1.3 0 2.5.3 3.5.9zM81.3 74c-1.8 3.2-3.9 6.4-6.1 9.6-3.7.3-7.4.4-11.2.4-3.9 0-7.6-.1-11.2-.4-2.2-3.2-4.2-6.4-6-9.6-1.9-3.3-3.7-6.7-5.3-10 1.6-3.3 3.4-6.7 5.3-10 1.8-3.2 3.9-6.4 6.1-9.6 3.7-.3 7.4-.4 11.2-.4 3.9 0 7.6.1 11.2.4 2.2 3.2 4.2 6.4 6 9.6 1.9 3.3 3.7 6.7 5.3 10-1.7 3.3-3.4 6.6-5.3 10zm8.3-3.3c1.5 3.5 2.7 6.9 3.8 10.3-3.4.8-7 1.4-10.8 1.9 1.2-1.9 2.5-3.9 3.6-6 1.2-2.1 2.3-4.2 3.4-6.2zM64 97.8c-2.4-2.6-4.7-5.4-6.9-8.3 2.3.1 4.6.2 6.9.2 2.3 0 4.6-.1 6.9-.2-2.2 2.9-4.5 5.7-6.9 8.3zm-18.6-15c-3.8-.5-7.4-1.1-10.8-1.9 1.1-3.3 2.3-6.8 3.8-10.3 1.1 2 2.2 4.1 3.4 6.1 1.2 2.2 2.4 4.1 3.6 6.1zm-7-25.5c-1.5-3.5-2.7-6.9-3.8-10.3 3.4-.8 7-1.4 10.8-1.9-1.2 1.9-2.5 3.9-3.6 6-1.2 2.1-2.3 4.2-3.4 6.2zM64 30.2c2.4 2.6 4.7 5.4 6.9 8.3-2.3-.1-4.6-.2-6.9-.2-2.3 0-4.6.1-6.9.2 2.2-2.9 4.5-5.7 6.9-8.3zm22.2 21l-3.6-6c3.8.5 7.4 1.1 10.8 1.9-1.1 3.3-2.3 6.8-3.8 10.3-1.1-2.1-2.2-4.2-3.4-6.2zM31.7 35c-1.7-10.5-.3-17.9 3.8-20.3 1-.6 2.2-.9 3.5-.9 6 0 13.5 4.9 21 12.3-3.5 3.8-7 8.2-10.4 13-5.8.5-11.3 1.4-16.5 2.5-.6-2.3-1-4.5-1.4-6.6zM7 64c0-4.7 5.7-9.7 15.7-13.4 2-.8 4.2-1.5 6.4-2.1 1.6 5 3.6 10.3 6 15.6-2.4 5.3-4.5 10.5-6 15.5C15.3 75.6 7 69.6 7 64zm28.5 49.3c-4.1-2.4-5.5-9.8-3.8-20.3.3-2.1.8-4.3 1.4-6.6 5.2 1.2 10.7 2 16.5 2.5 3.4 4.8 6.9 9.1 10.4 13-7.4 7.3-14.9 12.3-21 12.3-1.3 0-2.5-.3-3.5-.9zM96.3 93c1.7 10.5.3 17.9-3.8 20.3-1 .6-2.2.9-3.5.9-6 0-13.5-4.9-21-12.3 3.5-3.8 7-8.2 10.4-13 5.8-.5 11.3-1.4 16.5-2.5.6 2.3 1 4.5 1.4 6.6zm9-15.6c-2 .8-4.2 1.5-6.4 2.1-1.6-5-3.6-10.3-6-15.6 2.4-5.3 4.5-10.5 6-15.5 13.8 4 22.1 10 22.1 15.6 0 4.7-5.8 9.7-15.7 13.4z"></path>
            </g>
          </svg>;
      case "vue":
        return <svg viewBox="0 0 128 128">
            <path d="M0 8.934l49.854.158 14.167 24.47 14.432-24.47L128 8.935l-63.834 110.14zm126.98.637l-24.36.02-38.476 66.053L25.691 9.592.942 9.572l63.211 107.89zm-25.149-.008l-22.745.168-15.053 24.647L49.216 9.73l-22.794-.168 37.731 64.476zm-75.834-.17l23.002.009m-23.002-.01l23.002.01" fill="none"></path>
            <path d="M25.997 9.393l23.002.009L64.035 34.36 79.018 9.404 102 9.398 64.15 75.053z" fill="#35495e"></path>
            <path d="M.91 9.569l25.067-.172 38.15 65.659L101.98 9.401l25.11.026-62.966 108.06z" fill="#41b883"></path>
          </svg>;
      case "nextjs":
        return <svg viewBox="0 0 180 180" color="white">
            <defs>
              <linearGradient gradientUnits="userSpaceOnUse" id=":S2:paint0_linear_408_134" x1="109" x2="144.5" y1="116.5" y2="160.5">
                <stop stopColor="white"></stop>
                <stop offset="1" stopColor="white" stopOpacity="0"></stop>
              </linearGradient>
              <linearGradient gradientUnits="userSpaceOnUse" id=":S2:paint1_linear_408_134" x1="121" x2="120.799" y1="54" y2="106.875">
                <stop stopColor="white"></stop>
                <stop offset="1" stopColor="white" stopOpacity="0"></stop>
              </linearGradient>
            </defs>
            <mask height="180" id=":S2:mask0_408_134" maskUnits="userSpaceOnUse" style={{
          maskType: "alpha"
        }} width="180" x="0" y="0">
              <circle cx="90" cy="90" fill="black" r="90"></circle>
            </mask>
            <g mask="url(#:S2:mask0_408_134)">
              <circle cx="90" cy="90" data-circle="true" fill="black" r="90"></circle>
              <path d="M149.508 157.52L69.142 54H54V125.97H66.1136V69.3836L139.999 164.845C143.333 162.614 146.509 160.165 149.508 157.52Z" fill="url(#:S2:paint0_linear_408_134)"></path>
              <rect fill="url(#:S2:paint1_linear_408_134)" height="72" width="12" x="115" y="54"></rect>
            </g>
          </svg>;
      case "php":
        return <svg viewBox="0 0 128 128">
            <path fill="url(#a)" d="M0 64c0 18.593 28.654 33.667 64 33.667 35.346 0 64-15.074 64-33.667 0-18.593-28.655-33.667-64-33.667C28.654 30.333 0 45.407 0 64Z"></path>
            <path fill="#777bb3" d="M64 95.167c33.965 0 61.5-13.955 61.5-31.167 0-17.214-27.535-31.167-61.5-31.167S2.5 46.786 2.5 64c0 17.212 27.535 31.167 61.5 31.167Z"></path>
            <path d="M34.772 67.864c2.793 0 4.877-.515 6.196-1.53 1.306-1.006 2.207-2.747 2.68-5.175.44-2.27.272-3.854-.5-4.71-.788-.874-2.493-1.317-5.067-1.317h-4.464l-2.473 12.732zM20.173 83.547a.694.694 0 0 1-.68-.828l6.557-33.738a.695.695 0 0 1 .68-.561h14.134c4.442 0 7.748 1.206 9.827 3.585 2.088 2.39 2.734 5.734 1.917 9.935-.333 1.711-.905 3.3-1.7 4.724a15.818 15.818 0 0 1-3.128 3.92c-1.531 1.432-3.264 2.472-5.147 3.083-1.852.604-4.232.91-7.07.91h-5.724l-1.634 8.408a.695.695 0 0 1-.682.562z"></path>
            <path fill="#fff" d="M34.19 55.826h3.891c3.107 0 4.186.682 4.553 1.089.607.674.723 2.097.331 4.112-.439 2.257-1.253 3.858-2.42 4.756-1.194.92-3.138 1.386-5.773 1.386h-2.786l2.205-11.342zm6.674-8.1H26.731a1.39 1.39 0 0 0-1.364 1.123L18.81 82.588a1.39 1.39 0 0 0 1.363 1.653h7.35a1.39 1.39 0 0 0 1.363-1.124l1.525-7.846h5.151c2.912 0 5.364-.318 7.287-.944 1.977-.642 3.796-1.731 5.406-3.237a16.522 16.522 0 0 0 3.259-4.087c.831-1.487 1.429-3.147 1.775-4.931.86-4.423.161-7.964-2.076-10.524-2.216-2.537-5.698-3.823-10.349-3.823zM30.301 68.557h4.471c2.963 0 5.17-.557 6.62-1.675 1.451-1.116 2.428-2.98 2.938-5.591.485-2.508.264-4.277-.665-5.308-.931-1.03-2.791-1.546-5.584-1.546h-5.036l-2.743 14.12m10.563-19.445c4.252 0 7.353 1.117 9.303 3.348 1.95 2.232 2.536 5.347 1.76 9.346-.322 1.648-.863 3.154-1.625 4.518-.764 1.366-1.76 2.614-2.991 3.747-1.468 1.373-3.097 2.352-4.892 2.935-1.794.584-4.08.875-6.857.875h-6.296l-1.743 8.97h-7.35l6.558-33.739h14.133"></path>
            <path d="M69.459 74.577a.694.694 0 0 1-.682-.827l2.9-14.928c.277-1.42.209-2.438-.19-2.87-.245-.263-.979-.704-3.15-.704h-5.256l-3.646 18.768a.695.695 0 0 1-.683.56h-7.29a.695.695 0 0 1-.683-.826l6.558-33.739a.695.695 0 0 1 .682-.561h7.29a.695.695 0 0 1 .683.826L64.41 48.42h5.653c4.307 0 7.227.758 8.928 2.321 1.733 1.593 2.275 4.14 1.608 7.573l-3.051 15.702a.695.695 0 0 1-.682.56h-7.407z"></path>
            <path fill="#fff" d="M65.31 38.755h-7.291a1.39 1.39 0 0 0-1.364 1.124l-6.557 33.738a1.39 1.39 0 0 0 1.363 1.654h7.291a1.39 1.39 0 0 0 1.364-1.124l3.537-18.205h4.682c2.168 0 2.624.463 2.641.484.132.14.305.795.019 2.264l-2.9 14.927a1.39 1.39 0 0 0 1.364 1.654h7.408a1.39 1.39 0 0 0 1.363-1.124l3.051-15.7c.715-3.686.103-6.45-1.82-8.217-1.836-1.686-4.91-2.505-9.398-2.505h-4.81l1.421-7.315a1.39 1.39 0 0 0-1.364-1.655zm0 1.39-1.743 8.968h6.496c4.087 0 6.907.714 8.457 2.14 1.553 1.426 2.017 3.735 1.398 6.93l-3.052 15.699h-7.407l2.901-14.928c.33-1.698.208-2.856-.365-3.474-.573-.617-1.793-.926-3.658-.926h-5.829l-3.756 19.327H51.46l6.558-33.739h7.292z"></path>
            <path d="M92.136 67.864c2.793 0 4.878-.515 6.198-1.53 1.304-1.006 2.206-2.747 2.679-5.175.44-2.27.273-3.854-.5-4.71-.788-.874-2.493-1.317-5.067-1.317h-4.463l-2.475 12.732zM77.54 83.547a.694.694 0 0 1-.682-.828l6.557-33.738a.695.695 0 0 1 .682-.561H98.23c4.442 0 7.748 1.206 9.826 3.585 2.089 2.39 2.734 5.734 1.917 9.935a15.878 15.878 0 0 1-1.699 4.724 15.838 15.838 0 0 1-3.128 3.92c-1.53 1.432-3.265 2.472-5.147 3.083-1.852.604-4.232.91-7.071.91h-5.723l-1.633 8.408a.695.695 0 0 1-.683.562z"></path>
            <path fill="#fff" d="M91.555 55.826h3.891c3.107 0 4.186.682 4.552 1.089.61.674.724 2.097.333 4.112-.44 2.257-1.254 3.858-2.421 4.756-1.195.92-3.139 1.386-5.773 1.386h-2.786l2.204-11.342zm6.674-8.1H84.096a1.39 1.39 0 0 0-1.363 1.123l-6.558 33.739a1.39 1.39 0 0 0 1.364 1.653h7.35a1.39 1.39 0 0 0 1.363-1.124l1.525-7.846h5.15c2.911 0 5.364-.318 7.286-.944 1.978-.642 3.797-1.731 5.408-3.238a16.52 16.52 0 0 0 3.258-4.086c.832-1.487 1.428-3.147 1.775-4.931.86-4.423.162-7.964-2.076-10.524-2.216-2.537-5.697-3.823-10.35-3.823zM87.666 68.557h4.47c2.964 0 5.17-.557 6.622-1.675 1.45-1.116 2.428-2.98 2.936-5.591.487-2.508.266-4.277-.665-5.308-.93-1.03-2.791-1.546-5.583-1.546h-5.035Zm10.563-19.445c4.251 0 7.354 1.117 9.303 3.348 1.95 2.232 2.537 5.347 1.759 9.346-.32 1.648-.862 3.154-1.624 4.518-.763 1.366-1.76 2.614-2.992 3.747-1.467 1.373-3.097 2.352-4.892 2.935-1.793.584-4.078.875-6.856.875h-6.295l-1.745 8.97h-7.35l6.558-33.739h14.133"></path>
            <defs>
              <radialGradient id="a" cx="0" cy="0" r="1" gradientTransform="matrix(84.04136 0 0 84.04136 38.426 42.169)" gradientUnits="userSpaceOnUse">
                <stop stopColor="#AEB2D5"></stop>
                <stop offset=".3" stopColor="#AEB2D5"></stop>
                <stop offset=".75" stopColor="#484C89"></stop>
                <stop offset="1" stopColor="#484C89"></stop>
              </radialGradient>
            </defs>
          </svg>;
      case "node":
        return <svg viewBox="0 0 128 128">
            <path fill="url(#a)" d="M66.958.825a6.07 6.07 0 0 0-6.035 0L11.103 29.76c-1.895 1.072-2.96 3.095-2.96 5.24v57.988c0 2.143 1.183 4.167 2.958 5.24l49.82 28.934a6.07 6.07 0 0 0 6.036 0l49.82-28.935c1.894-1.072 2.958-3.096 2.958-5.24V35c0-2.144-1.183-4.167-2.958-5.24z"></path>
            <path fill="url(#b)" d="M116.897 29.76 66.841.825A8.161 8.161 0 0 0 65.302.23L9.21 96.798a6.251 6.251 0 0 0 1.657 1.43l50.057 28.934c1.42.833 3.076 1.072 4.615.595l52.66-96.925a3.702 3.702 0 0 0-1.302-1.072z"></path>
            <path fill="url(#c)" d="M116.898 98.225c1.42-.833 2.485-2.262 2.958-3.81L65.066.108c-1.42-.238-2.959-.119-4.26.715L11.104 29.639l53.606 98.355c.71-.12 1.54-.358 2.25-.715z"></path>
            <defs>
              <linearGradient id="a" x1="34.513" x2="27.157" y1="15.535" y2="30.448" gradientTransform="translate(-129.242 -73.715) scale(6.18523)" gradientUnits="userSpaceOnUse">
                <stop stopColor="#3F873F"></stop>
                <stop offset=".33" stopColor="#3F8B3D"></stop>
                <stop offset=".637" stopColor="#3E9638"></stop>
                <stop offset=".934" stopColor="#3DA92E"></stop>
                <stop offset="1" stopColor="#3DAE2B"></stop>
              </linearGradient>
              <linearGradient id="b" x1="30.009" x2="50.533" y1="23.359" y2="8.288" gradientTransform="translate(-129.242 -73.715) scale(6.18523)" gradientUnits="userSpaceOnUse">
                <stop offset=".138" stopColor="#3F873F"></stop>
                <stop offset=".402" stopColor="#52A044"></stop>
                <stop offset=".713" stopColor="#64B749"></stop>
                <stop offset=".908" stopColor="#6ABF4B"></stop>
              </linearGradient>
              <linearGradient id="c" x1="21.917" x2="40.555" y1="22.261" y2="22.261" gradientTransform="translate(-129.242 -73.715) scale(6.18523)" gradientUnits="userSpaceOnUse">
                <stop offset=".092" stopColor="#6ABF4B"></stop>
                <stop offset=".287" stopColor="#64B749"></stop>
                <stop offset=".598" stopColor="#52A044"></stop>
                <stop offset=".862" stopColor="#3F873F"></stop>
              </linearGradient>
            </defs>
          </svg>;
      case "ruby":
        return <svg viewBox="0 0 128 128">
            <linearGradient id="ruby-original-a" gradientUnits="userSpaceOnUse" x1="157.08" y1="2382.05" x2="131.682" y2="2426.892" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#FB7655"></stop>
              <stop offset="0" stopColor="#FB7655"></stop>
              <stop offset=".41" stopColor="#E42B1E"></stop>
              <stop offset=".99" stopColor="#900"></stop>
              <stop offset="1" stopColor="#900"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-a)" d="M97.078 83.214L28.34 124.031l89.003-6.04 6.855-89.745z"></path>
            <linearGradient id="ruby-original-b" gradientUnits="userSpaceOnUse" x1="169.731" y1="2419.72" x2="136.998" y2="2441.685" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#871101"></stop>
              <stop offset="0" stopColor="#871101"></stop>
              <stop offset=".99" stopColor="#911209"></stop>
              <stop offset="1" stopColor="#911209"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-b)" d="M117.488 117.93l-7.649-52.799-20.837 27.514z"></path>
            <linearGradient id="ruby-original-c" gradientUnits="userSpaceOnUse" x1="143.542" y1="2380.69" x2="110.81" y2="2402.655" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#871101"></stop>
              <stop offset="0" stopColor="#871101"></stop>
              <stop offset=".99" stopColor="#911209"></stop>
              <stop offset="1" stopColor="#911209"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-c)" d="M117.592 117.93l-56.044-4.399-32.91 10.385z"></path>
            <linearGradient id="ruby-original-d" gradientUnits="userSpaceOnUse" x1="74.817" y1="2435.622" x2="79.891" y2="2402.644" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset=".23" stopColor="#E57252"></stop>
              <stop offset=".46" stopColor="#DE3B20"></stop>
              <stop offset=".99" stopColor="#A60003"></stop>
              <stop offset="1" stopColor="#A60003"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-d)" d="M28.717 123.928l14.001-45.867-30.81 6.588z"></path>
            <linearGradient id="ruby-original-e" gradientUnits="userSpaceOnUse" x1="109.719" y1="2466.413" x2="111.589" y2="2432.757" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset=".23" stopColor="#E4714E"></stop>
              <stop offset=".56" stopColor="#BE1A0D"></stop>
              <stop offset=".99" stopColor="#A80D00"></stop>
              <stop offset="1" stopColor="#A80D00"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-e)" d="M88.996 92.797l-12.882-50.46-36.866 34.558z"></path>
            <linearGradient id="ruby-original-f" gradientUnits="userSpaceOnUse" x1="140.691" y1="2497.523" x2="146.289" y2="2473.401" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset=".18" stopColor="#E46342"></stop>
              <stop offset=".4" stopColor="#C82410"></stop>
              <stop offset=".99" stopColor="#A80D00"></stop>
              <stop offset="1" stopColor="#A80D00"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-f)" d="M121.275 43.047L86.426 14.585l-9.704 31.373z"></path>
            <linearGradient id="ruby-original-g" gradientUnits="userSpaceOnUse" x1="123.6" y1="2506.018" x2="147.719" y2="2518.077" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset=".54" stopColor="#C81F11"></stop>
              <stop offset=".99" stopColor="#BF0905"></stop>
              <stop offset="1" stopColor="#BF0905"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-g)" d="M104.978 4.437L84.481 15.764 71.551 4.285z"></path>
            <linearGradient id="ruby-original-h" gradientUnits="userSpaceOnUse" x1="53.674" y1="2444.028" x2="55.66" y2="2424.153" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset="0" stopColor="#fff"></stop>
              <stop offset=".31" stopColor="#DE4024"></stop>
              <stop offset=".99" stopColor="#BF190B"></stop>
              <stop offset="1" stopColor="#BF190B"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-h)" d="M3.802 100.034l8.586-15.659L5.442 65.72z"></path>
            <path fill="#fff" d="M4.981 65.131l6.987 19.821 30.365-6.812L77 45.922l9.783-31.075L71.38 3.969l-26.19 9.802c-8.252 7.675-24.263 22.86-24.84 23.146-.573.291-10.575 19.195-15.369 28.214z"></path>
            <linearGradient id="ruby-original-i" gradientUnits="userSpaceOnUse" x1="40.026" y1="2418.781" x2="133.345" y2="2514.739" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#BD0012"></stop>
              <stop offset="0" stopColor="#BD0012"></stop>
              <stop offset=".07" stopColor="#fff"></stop>
              <stop offset=".17" stopColor="#fff"></stop>
              <stop offset=".27" stopColor="#C82F1C"></stop>
              <stop offset=".33" stopColor="#820C01"></stop>
              <stop offset=".46" stopColor="#A31601"></stop>
              <stop offset=".72" stopColor="#B31301"></stop>
              <stop offset=".99" stopColor="#E82609"></stop>
              <stop offset="1" stopColor="#E82609"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-i)" d="M29.519 29.521c17.882-17.73 40.937-28.207 49.785-19.28 8.843 8.926-.534 30.62-18.418 48.345-17.884 17.725-40.653 28.779-49.493 19.852-8.849-8.92.242-31.191 18.126-48.917z"></path>
            <linearGradient id="ruby-original-j" gradientUnits="userSpaceOnUse" x1="111.507" y1="2409.102" x2="83.398" y2="2416.039" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#8C0C01"></stop>
              <stop offset="0" stopColor="#8C0C01"></stop>
              <stop offset=".54" stopColor="#990C00"></stop>
              <stop offset=".99" stopColor="#A80D0E"></stop>
              <stop offset="1" stopColor="#A80D0E"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-j)" d="M28.717 123.909l13.89-46.012 46.135 14.82c-16.68 15.642-35.233 28.865-60.025 31.192z"></path>
            <linearGradient id="ruby-original-k" gradientUnits="userSpaceOnUse" x1="159.785" y1="2442.837" x2="134.814" y2="2465.217" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#7E110B"></stop>
              <stop offset="0" stopColor="#7E110B"></stop>
              <stop offset=".99" stopColor="#9E0C00"></stop>
              <stop offset="1" stopColor="#9E0C00"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-k)" d="M77.062 45.831l11.844 46.911c13.934-14.65 26.439-30.401 32.563-49.883l-44.407 2.972z"></path>
            <linearGradient id="ruby-original-l" gradientUnits="userSpaceOnUse" x1="168.959" y1="2483.901" x2="156.521" y2="2497.199" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#79130D"></stop>
              <stop offset="0" stopColor="#79130D"></stop>
              <stop offset=".99" stopColor="#9E120B"></stop>
              <stop offset="1" stopColor="#9E120B"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-l)" d="M121.348 43.097c4.74-14.305 5.833-34.825-16.517-38.635l-18.339 10.13 34.856 28.505z"></path>
            <path fill="#9E1209" d="M3.802 99.828c.656 23.608 17.689 23.959 24.945 24.167l-16.759-39.14-8.186 14.973z"></path>
            <radialGradient id="ruby-original-m" cx="138.703" cy="2464.789" r="30.601" gradientTransform="matrix(1 0 0 -1 -47.5 2517)" gradientUnits="userSpaceOnUse">
              <stop offset="0" stopColor="#A80D00"></stop>
              <stop offset="0" stopColor="#A80D00"></stop>
              <stop offset=".99" stopColor="#7E0E08"></stop>
              <stop offset="1" stopColor="#7E0E08"></stop>
            </radialGradient>
            <path fill="url(#ruby-original-m)" d="M77.128 45.904c10.708 6.581 32.286 19.798 32.723 20.041.68.383 9.304-14.542 11.261-22.976l-43.984 2.935z"></path>
            <radialGradient id="ruby-original-n" cx="96.325" cy="2424.465" r="40.679" gradientTransform="matrix(1 0 0 -1 -47.5 2517)" gradientUnits="userSpaceOnUse">
              <stop offset="0" stopColor="#A30C00"></stop>
              <stop offset="0" stopColor="#A30C00"></stop>
              <stop offset=".99" stopColor="#800E08"></stop>
              <stop offset="1" stopColor="#800E08"></stop>
            </radialGradient>
            <path fill="url(#ruby-original-n)" d="M42.589 77.897l18.57 35.828c10.98-5.955 19.579-13.211 27.454-20.983L42.589 77.897z"></path>
            <linearGradient id="ruby-original-o" gradientUnits="userSpaceOnUse" x1="67.509" y1="2393.115" x2="57.373" y2="2427.506" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#8B2114"></stop>
              <stop offset="0" stopColor="#8B2114"></stop>
              <stop offset=".43" stopColor="#9E100A"></stop>
              <stop offset=".99" stopColor="#B3100C"></stop>
              <stop offset="1" stopColor="#B3100C"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-o)" d="M11.914 84.904l-2.631 31.331c4.964 6.781 11.794 7.371 18.96 6.842-5.184-12.9-15.538-38.696-16.329-38.173z"></path>
            <linearGradient id="ruby-original-p" gradientUnits="userSpaceOnUse" x1="145.272" y1="2507.076" x2="167.996" y2="2497.045" gradientTransform="matrix(1 0 0 -1 -47.5 2517)">
              <stop offset="0" stopColor="#B31000"></stop>
              <stop offset="0" stopColor="#B31000"></stop>
              <stop offset=".44" stopColor="#910F08"></stop>
              <stop offset=".99" stopColor="#791C12"></stop>
              <stop offset="1" stopColor="#791C12"></stop>
            </linearGradient>
            <path fill="url(#ruby-original-p)" d="M86.384 14.67l36.891 5.177c-1.969-8.343-8.015-13.727-18.32-15.41L86.384 14.67z"></path>
          </svg>;
      case "python":
        return <svg viewBox="0 0 128 128">
            <linearGradient id="python-original-a" gradientUnits="userSpaceOnUse" x1="70.252" y1="1237.476" x2="170.659" y2="1151.089" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)">
              <stop offset="0" stopColor="#5A9FD4"></stop>
              <stop offset="1" stopColor="#306998"></stop>
            </linearGradient>
            <linearGradient id="python-original-b" gradientUnits="userSpaceOnUse" x1="209.474" y1="1098.811" x2="173.62" y2="1149.537" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)">
              <stop offset="0" stopColor="#FFD43B"></stop>
              <stop offset="1" stopColor="#FFE873"></stop>
            </linearGradient>
            <path fill="url(#python-original-a)" d="M63.391 1.988c-4.222.02-8.252.379-11.8 1.007-10.45 1.846-12.346 5.71-12.346 12.837v9.411h24.693v3.137H29.977c-7.176 0-13.46 4.313-15.426 12.521-2.268 9.405-2.368 15.275 0 25.096 1.755 7.311 5.947 12.519 13.124 12.519h8.491V67.234c0-8.151 7.051-15.34 15.426-15.34h24.665c6.866 0 12.346-5.654 12.346-12.548V15.833c0-6.693-5.646-11.72-12.346-12.837-4.244-.706-8.645-1.027-12.866-1.008zM50.037 9.557c2.55 0 4.634 2.117 4.634 4.721 0 2.593-2.083 4.69-4.634 4.69-2.56 0-4.633-2.097-4.633-4.69-.001-2.604 2.073-4.721 4.633-4.721z" transform="translate(0 10.26)"></path>
            <path fill="url(#python-original-b)" d="M91.682 28.38v10.966c0 8.5-7.208 15.655-15.426 15.655H51.591c-6.756 0-12.346 5.783-12.346 12.549v23.515c0 6.691 5.818 10.628 12.346 12.547 7.816 2.297 15.312 2.713 24.665 0 6.216-1.801 12.346-5.423 12.346-12.547v-9.412H63.938v-3.138h37.012c7.176 0 9.852-5.005 12.348-12.519 2.578-7.735 2.467-15.174 0-25.096-1.774-7.145-5.161-12.521-12.348-12.521h-9.268zM77.809 87.927c2.561 0 4.634 2.097 4.634 4.692 0 2.602-2.074 4.719-4.634 4.719-2.55 0-4.633-2.117-4.633-4.719 0-2.595 2.083-4.692 4.633-4.692z" transform="translate(0 10.26)"></path>
            <radialGradient id="python-original-c" cx="1825.678" cy="444.45" r="26.743" gradientTransform="matrix(0 -.24 -1.055 0 532.979 557.576)" gradientUnits="userSpaceOnUse">
              <stop offset="0" stopColor="#B8B8B8" stopOpacity=".498"></stop>
              <stop offset="1" stopColor="#7F7F7F" stopOpacity="0"></stop>
            </radialGradient>
            <path opacity=".444" fill="url(#python-original-c)" d="M97.309 119.597c0 3.543-14.816 6.416-33.091 6.416-18.276 0-33.092-2.873-33.092-6.416 0-3.544 14.815-6.417 33.092-6.417 18.275 0 33.091 2.872 33.091 6.417z"></path>
          </svg>;
      case "go":
        return <svg viewBox="0 0 128 128">
            <defs>
              <path id="go-original-a" d="M18.8 1h90.5v126H18.8z"></path>
            </defs>
            <clipPath id="go-original-b">
              <use xlinkHref="#go-original-a" overflow="visible"></use>
            </clipPath>
            <path fillRule="evenodd" clipRule="evenodd" fill="#F6D2A2" d="M21.1 68.7c.2 3.5 3.7 1.9 5.3.8 1.5-1.1 2-.2 2.1-2.3.1-1.4.2-2.7.2-4.1-2.3-.2-4.8.3-6.7 1.7-.9.7-2.8 3-.9 3.9" clipPath="url(#go-original-b)"></path>
            <path d="M23 71.2c-.7 0-2-.3-2.2-2.3-.6-.4-.8-.9-.8-1.2-.1-1.2 1.2-2.6 1.9-3.1 1.6-1.2 3.7-1.8 5.9-1.8h1.3v.3c.1 1.1 0 2.2-.1 3.2 0 .3 0 .6-.1.9-.1 1.5-.4 1.7-1.1 2-.3.1-.6.2-1.1.6-.5.3-2.2 1.4-3.7 1.4zm4.8-7.8c-2.1 0-4 .6-5.5 1.7-.7.5-1.7 1.7-1.6 2.5 0 .3.2.6.6.8l.2.1v.2c.1 1.6.9 1.8 1.5 1.8 1 0 2.4-.7 3.3-1.3.6-.4 1-.5 1.3-.6.5-.2.6-.2.7-1.4 0-.3 0-.6.1-.9.1-.9.1-1.9.1-2.8-.3-.1-.5-.1-.7-.1z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#C6B198" d="M21.1 68.7c.5-.2 1.1-.3 1.4-.8" clipPath="url(#go-original-b)"></path>
            <path d="M21.1 69c-.1 0-.3-.1-.3-.2-.1-.2 0-.4.2-.4.1 0 .2-.1.2-.1.4-.2.8-.3 1-.6.1-.1.3-.2.5-.1.1.1.2.3.1.5-.4.5-.9.7-1.3.8l-.2.1h-.2z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#6AD7E5" d="M29.3 26.4c-13.6-3.8-3.5-21.1 7.4-14l-7.4 14z" clipPath="url(#go-original-b)"></path>
            <path d="M29.5 26.8l-.3-.1c-7-2-6.9-7-6.7-8.5.5-3.8 4.1-7.8 8.9-7.8 1.9 0 3.7.6 5.5 1.8l.3.2-7.7 14.4zm1.9-15.7c-4.5 0-7.8 3.7-8.3 7.2-.5 3.6 1.7 6.4 6 7.7l7.1-13.5c-1.5-.9-3.1-1.4-4.8-1.4z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#6AD7E5" d="M89.6 11.1c10.7-7.5 20.5 9.5 8 13.8l-8-13.8z" clipPath="url(#go-original-b)"></path>
            <path d="M97.5 25.3L89.2 11l.3-.2c1.9-1.3 3.8-2 5.7-2 4.6 0 7.9 3.8 8.6 7.5.3 1.5.6 6.6-6 8.8l-.3.2zm-7.4-14l7.7 13.3c3.9-1.4 5.9-4.4 5.3-8-.6-3.4-3.7-6.9-7.9-6.9-1.7-.1-3.4.4-5.1 1.6z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#F6D2A2" d="M92 112.3c2.7 1.7 7.7 6.8 3.6 9.3-3.9 3.6-6.1-4-9.6-5 1.5-2 3.4-3.9 6-4.3" clipPath="url(#go-original-b)"></path>
            <path d="M93.5 122.9c-1.6 0-3-1.6-4.2-3.1-1.1-1.2-2.2-2.5-3.4-2.9l-.5-.1.3-.4c1.2-1.7 3.2-3.9 6.2-4.4h.1l.1.1c1.7 1.1 5.4 4.2 5.3 7.1 0 1.1-.6 2-1.7 2.7-.7.7-1.4 1-2.2 1zm-7-6.5c1.2.5 2.2 1.8 3.2 2.9 1.2 1.5 2.4 2.8 3.7 2.8.6 0 1.2-.3 1.8-.9h.1c.9-.6 1.4-1.3 1.4-2.2 0-2.3-2.9-5.2-4.9-6.5-1.8.5-3.6 1.7-5.3 3.9zm9.1 5.5c-.1 0-.2-.1-.3-.2-.2-.4-.4-.9-.5-1.3-.3-.8-.6-1.6-1.2-2.2-.1-.1-.1-.3 0-.5.1-.1.3-.1.5 0 .7.7 1.1 1.6 1.4 2.5l.5 1.2c.1.2 0 .4-.1.5h-.3z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#F6D2A2" d="M43.2 118.1c-3.2.5-5 3.4-7.7 4.9-2.5 1.5-3.5-.5-3.7-.9-.4-.2-.4.2-1-.4-2.3-3.7 2.4-6.4 4.9-8.2 3.5-.8 5.7 2.2 7.5 4.6" clipPath="url(#go-original-b)"></path>
            <path d="M33.8 123.8c-1.3 0-2-1.1-2.2-1.5h-.1c-.3 0-.5-.1-.9-.5v-.1c-2.2-3.5 1.6-6.2 4.1-8l.9-.6h.2c.4-.1.7-.1 1.1-.1 3 0 4.9 2.6 6.5 4.7l.5.7-.6.1c-1.9.3-3.3 1.5-4.7 2.7-.9.8-1.8 1.5-2.8 2.1-.8.3-1.4.5-2 .5zm-2.2-2.1c.1 0 .2 0 .4.1h.1l.1.1c.2.3.7 1.2 1.7 1.2.5 0 1-.2 1.5-.5 1-.5 1.9-1.3 2.7-2 1.3-1.1 2.7-2.3 4.5-2.8-1.5-2-3.3-4.2-5.8-4.2-.3 0-.6 0-.9.1l-.8.6c-2.6 1.8-5.8 4.1-3.9 7.1.1.2.2.3.4.3zm.2.7c-.2 0-.4-.2-.3-.4.1-1 .6-1.7 1.1-2.5.3-.4.5-.8.7-1.2.1-.2.3-.2.4-.2.2.1.2.3.2.4-.2.5-.5.9-.8 1.3-.5.7-.9 1.3-1 2.1 0 .4-.1.5-.3.5z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" d="M29.9 21.7c-1.8-.9-3.1-2.2-2-4.3 1-1.9 2.9-1.7 4.7-.8l-2.7 5.1zm64.9-1.8c1.8-.9 3.1-2.2 2-4.3-1-1.9-2.9-1.7-4.7-.8l2.7 5.1z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#F6D2A2" d="M107.1 68.2c-.2 3.5-3.7 1.9-5.3.8-1.5-1.1-2-.2-2.1-2.3-.1-1.4-.2-2.7-.2-4.1 2.3-.2 4.8.3 6.7 1.7 1 .8 2.8 3 .9 3.9" clipPath="url(#go-original-b)"></path>
            <path d="M105.3 70.7c-1.5 0-3.2-1.1-3.7-1.4-.5-.3-.8-.5-1.1-.6-.8-.3-1-.5-1.1-2 0-.3 0-.6-.1-.9-.1-1-.2-2.1-.1-3.2v-.3h1.3c2.2 0 4.3.6 5.9 1.8.7.5 2 1.9 1.9 3.1 0 .4-.2.9-.8 1.2-.2 2-1.5 2.3-2.2 2.3zM99.8 63c0 .9 0 1.9.1 2.8 0 .3 0 .6.1.9.1 1.2.2 1.2.7 1.4.3.1.7.3 1.3.6.9.6 2.3 1.3 3.3 1.3.6 0 1.4-.2 1.5-1.8V68l.2-.1c.4-.2.6-.4.6-.8.1-.8-.9-2-1.6-2.5-1.5-1.1-3.5-1.7-5.5-1.7-.2.1-.4.1-.7.1z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#C6B198" d="M107.1 68.2c-.5-.2-1.1-.3-1.4-.8" clipPath="url(#go-original-b)"></path>
            <path d="M107.1 68.6h-.1l-.2-.1c-.5-.2-1-.3-1.3-.8-.1-.1-.1-.4.1-.5.1-.1.4-.1.5.1.2.3.6.4 1 .6.1 0 .2.1.2.1.2.1.3.3.2.4-.1.1-.3.2-.4.2z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#6AD7E5" d="M62.8 4c13.6 0 26.3 1.9 33 15 6 14.6 3.8 30.4 4.8 45.9.8 13.3 2.5 28.6-3.6 40.9-6.5 12.9-22.7 16.2-36 15.7-10.5-.4-23.1-3.8-29.1-13.4-6.9-11.2-3.7-27.9-3.2-40.4.6-14.8-4-29.7.9-44.1C34.5 8.5 48.1 5.1 62.8 4" clipPath="url(#go-original-b)"></path>
            <path d="M63.3 121.9h-2.5c-4.1-.1-10.3-.8-16.4-3.3-5.9-2.4-10.2-5.8-13-10.3-5.6-9.1-4.6-21.6-3.7-32.7.2-2.8.4-5.4.5-7.9.2-5.2-.2-10.6-.7-15.7-.8-9.4-1.6-19.1 1.5-28.5 2.4-7 6.7-12 13.2-15.2 5.1-2.5 11.4-3.9 20.4-4.6C76 3.6 89.3 5.5 96 18.8c4.4 10.7 4.4 22.2 4.5 33.3 0 4.2 0 8.5.3 12.7.1 1.3.2 2.6.2 3.9.8 12.2 1.7 26-3.9 37.2-2.8 5.7-7.7 9.9-14.4 12.6-5.4 2.2-12.2 3.4-19.4 3.4zM62.8 4.3c-14.1 1.1-27.9 4.2-33 19.4-3.1 9.3-2.3 18.9-1.5 28.2.4 5.2.9 10.5.7 15.8-.1 2.5-.3 5.1-.5 7.9-.9 11-1.9 23.4 3.6 32.3 2.3 3.7 9.7 12.5 28.8 13.2h2.5c22.1 0 30.3-9.8 33.3-15.6 5.5-11 4.6-24.8 3.9-36.9-.1-1.3-.2-2.6-.2-3.9-.2-4.2-.3-8.5-.3-12.7-.1-11-.1-22.5-4.4-33.1C92.7 13 88.2 9 82 6.7c-6.4-2.1-13.6-2.4-19.2-2.4z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#fff" d="M65.2 22.2c2.4 14.2 25.6 10.4 22.3-3.9-3-12.8-23.1-9.2-22.3 3.9" clipPath="url(#go-original-b)"></path>
            <path d="M76.2 31.5c-4.5 0-10.2-2.4-11.4-9.2-.2-3.2.8-6.1 2.9-8.3 2.3-2.5 5.8-3.9 9.4-3.9 4.2 0 9.2 2.2 10.6 8.3.8 3.4.2 6.4-1.7 8.8-2.1 2.6-5.8 4.3-9.8 4.3zm-10.7-9.3c.5 2.8 1.8 5 3.9 6.6 1.8 1.4 4.3 2.1 6.8 2.1 3.7 0 7.3-1.6 9.3-4.1 1.8-2.2 2.3-5.1 1.6-8.3-1.3-5.7-6-7.7-10-7.7-3.4 0-6.7 1.4-8.9 3.7-1.9 2-2.9 4.7-2.7 7.7z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#fff" d="M37.5 24.5c3.2 12.3 22.9 9.2 22.2-3.2-.9-14.8-25.3-12-22.2 3.2" clipPath="url(#go-original-b)"></path>
            <path d="M48 32.7c-4.3 0-9.3-2.1-10.9-8.1-.7-3.5 0-6.7 2-9.1 2.2-2.7 5.8-4.3 9.7-4.3 5.2 0 10.7 3.1 11.1 10.1.2 2.9-.7 5.5-2.7 7.6-2.1 2.3-5.6 3.8-9.2 3.8zm.8-20.8c-3.7 0-7.1 1.5-9.2 4-1.9 2.3-2.5 5.2-1.8 8.5C39.2 30 44 32 48 32c3.4 0 6.7-1.3 8.8-3.6 1.8-1.9 2.7-4.4 2.5-7.1-.2-4.3-3.1-9.4-10.5-9.4z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#fff" d="M68 39.2c0 1.8.4 3.9.1 5.9-.5.9-1.4 1-2.2 1.3-1.1-.2-2-.9-2.5-1.9-.3-2.2.1-4.4.2-6.6l4.4 1.3z" clipPath="url(#go-original-b)"></path>
            <path d="M65.9 46.8c-1.3-.2-2.3-1-2.8-2.1-.2-1.6-.1-3.1 0-4.6.1-.7.1-1.4.1-2.1v-.4l5.1 1.6v.2c0 .6.1 1.2.1 1.9.1 1.3.2 2.7 0 4v.1c-.4.8-1.1 1-1.8 1.3-.2-.1-.4 0-.7.1zm-2.2-2.4c.4.9 1.2 1.5 2.1 1.7.2-.1.4-.1.5-.2.6-.2 1.1-.4 1.4-.9.2-1.2.1-2.5 0-3.8 0-.6-.1-1.2-.1-1.7l-3.8-1.2c0 .6-.1 1.2-.1 1.7-.1 1.6-.2 3 0 4.4z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" d="M46.3 22.5c0 2-1.5 3.6-3.3 3.6-1.8 0-3.3-1.6-3.3-3.6s1.5-3.6 3.3-3.6c1.8 0 3.3 1.6 3.3 3.6" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#fff" d="M45.2 23.3c0 .5-.4.9-.8.9s-.8-.4-.8-.9.4-.9.8-.9c.5 0 .8.4.8.9" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" d="M74.2 21.6c0 2-1.5 3.6-3.3 3.6-1.8 0-3.3-1.6-3.3-3.6s1.5-3.6 3.3-3.6c1.8 0 3.3 1.6 3.3 3.6" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#fff" d="M73.2 22.4c0 .5-.3.9-.8.9-.4 0-.8-.4-.8-.9s.3-.9.8-.9c.4 0 .8.4.8.9M58.4 39c-1.5 3.5.8 10.6 4.8 5.4-.3-2.2.1-4.4.2-6.6l-5 1.2z" clipPath="url(#go-original-b)"></path>
            <path d="M60.5 46.6c-.7 0-1.4-.4-1.9-1.2-1.1-1.6-1.3-4.6-.5-6.5l.1-.2 5.5-1.4v.4l-.1 2.2c-.1 1.5-.2 2.9 0 4.4v.1l-.1.1c-1 1.4-2 2.1-3 2.1zm-1.8-7.3c-.6 1.7-.4 4.4.5 5.7.4.6.8.9 1.3.9.7 0 1.5-.6 2.3-1.6-.2-1.5-.1-3 .1-4.4l.1-1.7-4.3 1.1z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#F6D2A2" d="M58.9 32.2c-2.7.2-4.9 3.5-3.5 6 1.9 3.4 6-.3 8.6 0 3 .1 5.4 3.2 7.8.6 2.7-2.9-1.2-5.7-4.1-7l-8.8.4z" clipPath="url(#go-original-b)"></path>
            <path fill="#231F20" d="M69.7 40.2c-.9 0-1.8-.4-2.7-.8-.9-.4-1.9-.8-3-.8h-.3c-.8 0-1.7.3-2.7.7-1.1.4-2.2.7-3.2.7-1.2 0-2.1-.5-2.7-1.6-.7-1.2-.6-2.6.1-3.9.8-1.5 2.2-2.4 3.7-2.6l8.9-.4h.1c2.2.9 4.7 2.6 5.2 4.6.2 1-.1 2-.9 2.9-.8.9-1.6 1.2-2.5 1.2zM64.1 38c1.1 0 2.2.5 3.2.9.9.4 1.7.7 2.5.7.7 0 1.3-.3 1.9-.9.7-.7.9-1.5.8-2.3-.4-1.7-2.8-3.3-4.7-4.1l-8.7.4c-1.3.1-2.5 1-3.2 2.2-.6 1.1-.6 2.3-.1 3.3.5.9 1.1 1.3 2.1 1.3.9 0 1.9-.4 2.9-.7 1.1-.4 2-.7 3-.7 0-.2.1-.2.3-.1z" clipPath="url(#go-original-b)"></path>
            <path fillRule="evenodd" clipRule="evenodd" d="M58.6 32.1c-.2-4.7 8.8-5.3 9.8-1.4 1.1 4-9.4 4.9-9.8 1.4" clipPath="url(#go-original-b)"></path>
          </svg>;
      case "java":
        return <svg viewBox="0 0 128 128">
            <path fill="#0074BD" d="M47.617 98.12s-4.767 2.774 3.397 3.71c9.892 1.13 14.947.968 25.845-1.092 0 0 2.871 1.795 6.873 3.351-24.439 10.47-55.308-.607-36.115-5.969zm-2.988-13.665s-5.348 3.959 2.823 4.805c10.567 1.091 18.91 1.18 33.354-1.6 0 0 1.993 2.025 5.132 3.131-29.542 8.64-62.446.68-41.309-6.336z"></path>
            <path fill="#EA2D2E" d="M69.802 61.271c6.025 6.935-1.58 13.17-1.58 13.17s15.289-7.891 8.269-17.777c-6.559-9.215-11.587-13.792 15.635-29.58 0 .001-42.731 10.67-22.324 34.187z"></path>
            <path fill="#0074BD" d="M102.123 108.229s3.529 2.91-3.888 5.159c-14.102 4.272-58.706 5.56-71.094.171-4.451-1.938 3.899-4.625 6.526-5.192 2.739-.593 4.303-.485 4.303-.485-4.953-3.487-32.013 6.85-13.743 9.815 49.821 8.076 90.817-3.637 77.896-9.468zM49.912 70.294s-22.686 5.389-8.033 7.348c6.188.828 18.518.638 30.011-.326 9.39-.789 18.813-2.474 18.813-2.474s-3.308 1.419-5.704 3.053c-23.042 6.061-67.544 3.238-54.731-2.958 10.832-5.239 19.644-4.643 19.644-4.643zm40.697 22.747c23.421-12.167 12.591-23.86 5.032-22.285-1.848.385-2.677.72-2.677.72s.688-1.079 2-1.543c14.953-5.255 26.451 15.503-4.823 23.725 0-.002.359-.327.468-.617z"></path>
            <path fill="#EA2D2E" d="M76.491 1.587S89.459 14.563 64.188 34.51c-20.266 16.006-4.621 25.13-.007 35.559-11.831-10.673-20.509-20.07-14.688-28.815C58.041 28.42 81.722 22.195 76.491 1.587z"></path>
            <path fill="#0074BD" d="M52.214 126.021c22.476 1.437 57-.8 57.817-11.436 0 0-1.571 4.032-18.577 7.231-19.186 3.612-42.854 3.191-56.887.874 0 .001 2.875 2.381 17.647 3.331z"></path>
          </svg>;
      case "csharp":
        return <svg viewBox="0 0 128 128">
            <path fill="#9B4F96" d="M115.4 30.7L67.1 2.9c-.8-.5-1.9-.7-3.1-.7-1.2 0-2.3.3-3.1.7l-48 27.9c-1.7 1-2.9 3.5-2.9 5.4v55.7c0 1.1.2 2.4 1 3.5l106.8-62c-.6-1.2-1.5-2.1-2.4-2.7z"></path>
            <path fill="#68217A" d="M10.7 95.3c.5.8 1.2 1.5 1.9 1.9l48.2 27.9c.8.5 1.9.7 3.1.7 1.2 0 2.3-.3 3.1-.7l48-27.9c1.7-1 2.9-3.5 2.9-5.4V36.1c0-.9-.1-1.9-.6-2.8l-106.6 62z"></path>
            <path fill="#fff" d="M85.3 76.1C81.1 83.5 73.1 88.5 64 88.5c-13.5 0-24.5-11-24.5-24.5s11-24.5 24.5-24.5c9.1 0 17.1 5 21.3 12.5l13-7.5c-6.8-11.9-19.6-20-34.3-20-21.8 0-39.5 17.7-39.5 39.5s17.7 39.5 39.5 39.5c14.6 0 27.4-8 34.2-19.8l-12.9-7.6zM97 66.2l.9-4.3h-4.2v-4.7h5.1L100 51h4.9l-1.2 6.1h3.8l1.2-6.1h4.8l-1.2 6.1h2.4v4.7h-3.3l-.9 4.3h4.2v4.7h-5.1l-1.2 6h-4.9l1.2-6h-3.8l-1.2 6h-4.8l1.2-6h-2.4v-4.7H97zm4.8 0h3.8l.9-4.3h-3.8l-.9 4.3z"></path>
          </svg>;
      case "rust":
        return <svg viewBox="0 0 128 128">
            <path fill="var(--color-inverse)" d="M62.96.242c-.232.135-1.203 1.528-2.16 3.097-2.4 3.94-2.426 3.942-5.65.55-2.098-2.208-2.605-2.612-3.28-2.607-.44.002-.995.152-1.235.332-.24.18-.916 1.612-1.504 3.183-1.346 3.6-1.41 3.715-2.156 3.86-.46.086-1.343-.407-3.463-1.929-1.565-1.125-3.1-2.045-3.411-2.045-1.291 0-1.655.706-2.27 4.4-.78 4.697-.754 4.681-4.988 2.758-1.71-.776-3.33-1.41-3.603-1.41-.274 0-.792.293-1.15.652-.652.652-.653.655-.475 4.246l.178 3.595-.68.364c-.602.322-1.017.283-3.684-.348-3.48-.822-4.216-.8-4.92.15l-.516.693.692 2.964c.38 1.63.745 3.2.814 3.487.067.287-.05.746-.26 1.02-.348.448-.717.49-3.94.44-5.452-.086-5.761.382-3.51 5.3.718 1.56 1.305 2.98 1.305 3.15 0 .898-.717 1.224-3.794 1.727-1.722.28-3.218.51-3.326.51-.107 0-.43.235-.717.522-.937.936-.671 1.816 1.453 4.814 2.646 3.735 2.642 3.75-1.73 5.421-4.971 1.902-5.072 2.37-1.287 5.96 3.525 3.344 3.53 3.295-.461 5.804C.208 62.8.162 62.846.085 63.876c-.093 1.253-.071 1.275 3.538 3.48 3.57 2.18 3.57 2.246.067 5.56C-.078 76.48.038 77 5.013 78.877c4.347 1.64 4.353 1.66 1.702 5.394-1.502 2.117-1.981 3-1.981 3.653 0 1.223.637 1.535 4.44 2.174 3.206.54 3.92.857 3.92 1.741 0 .182-.588 1.612-1.307 3.177-2.236 4.87-1.981 5.275 3.31 5.275 4.93 0 4.799-.15 3.737 4.294-.8 3.35-.813 3.992-.088 4.715.554.556 1.6.494 4.87-.289 2.499-.596 2.937-.637 3.516-.328l.66.354-.177 3.594c-.178 3.593-.177 3.595.475 4.248.358.36.884.652 1.165.652.282 0 1.903-.63 3.604-1.404 4.22-1.916 4.194-1.932 4.973 2.75.617 3.711.977 4.4 2.294 4.4.327 0 1.83-.88 3.34-1.958 2.654-1.893 3.342-2.19 4.049-1.74.182.115.89 1.67 1.572 3.455 1.003 2.625 1.37 3.31 1.929 3.576 1.062.51 1.72.1 4.218-2.62 3.016-3.286 3.14-3.27 5.602.72 2.72 4.406 3.424 4.396 6.212-.089 2.402-3.864 2.374-3.862 5.621-.47 2.157 2.25 2.616 2.61 3.343 2.61.464 0 1.019-.175 1.23-.388.214-.213.92-1.786 1.568-3.496.649-1.71 1.321-3.2 1.495-3.31.687-.436 1.398-.13 4.048 1.752 1.56 1.108 3.028 1.96 3.377 1.96 1.296 0 1.764-.92 2.302-4.535.46-3.082.554-3.378 1.16-3.685.596-.302.954-.2 3.75 1.07 1.701.77 3.323 1.402 3.604 1.402.282 0 .816-.302 1.184-.672l.672-.67-.184-3.448c-.177-3.29-.16-3.468.364-3.943.54-.488.596-.486 3.615.204 3.656.835 4.338.857 5.025.17.671-.67.664-.818-.254-4.69-1.03-4.346-1.168-4.19 3.78-4.19 3.374 0 3.75-.049 4.18-.523.718-.793.547-1.702-.896-4.779-.729-1.55-1.32-2.96-1.315-3.135.024-.914.743-1.227 4.065-1.767 2.033-.329 3.553-.71 3.829-.96.923-.833.584-1.918-1.523-4.873-2.642-3.703-2.63-3.738 1.599-5.297 5.064-1.866 5.209-2.488 1.419-6.09-3.51-3.335-3.512-3.317.333-5.677 4.648-2.853 4.655-3.496.082-6.335-3.933-2.44-3.93-2.406-.405-5.753 3.78-3.593 3.678-4.063-1.295-5.965-4.388-1.679-4.402-1.72-1.735-5.38 1.588-2.18 1.982-2.903 1.982-3.65 0-1.306-.586-1.598-4.436-2.22-3.216-.52-3.924-.835-3.924-1.75 0-.174.588-1.574 1.307-3.113 1.406-3.013 1.604-4.22.808-4.94-.428-.387-1-.443-4.067-.392-3.208.054-3.618.008-4.063-.439-.486-.488-.48-.557.278-3.725.931-3.88.935-3.975.17-4.694-.777-.73-1.262-.718-4.826.121-2.597.612-3.027.653-3.617.337l-.67-.36.185-3.582.186-3.58-.67-.67c-.369-.37-.891-.67-1.163-.67-.27 0-1.884.64-3.583 1.421-2.838 1.306-3.143 1.393-3.757 1.072-.612-.32-.714-.637-1.237-3.829-.603-3.693-.977-4.412-2.288-4.412-.311 0-1.853.925-3.426 2.055-2.584 1.856-2.93 2.032-3.574 1.807-.533-.186-.843-.59-1.221-1.599-.28-.742-.817-2.172-1.194-3.177-.762-2.028-1.187-2.482-2.328-2.482-.637 0-1.213.458-3.28 2.604-3.25 3.375-3.261 3.374-5.65-.545C66.073 1.78 65.075.382 64.81.24c-.597-.32-1.3-.32-1.85.002m2.96 11.798c2.83 2.014 1.326 6.75-2.144 6.75-3.368 0-5.064-4.057-2.66-6.36 1.358-1.3 3.304-1.459 4.805-.39m-3.558 12.507c1.855.705 2.616.282 6.852-3.8l3.182-3.07 1.347.18c4.225.56 12.627 4.25 17.455 7.666 4.436 3.14 10.332 9.534 12.845 13.93l.537.942-2.38 5.364c-1.31 2.95-2.382 5.673-2.382 6.053 0 .878.576 2.267 1.13 2.726.234.195 2.457 1.265 4.939 2.378l4.51 2.025.178 1.148c.23 1.495.26 5.167.052 6.21l-.163.816h-2.575c-2.987 0-2.756-.267-2.918 3.396-.118 2.656-.76 4.124-2.22 5.075-2.377 1.551-6.304 1.27-7.97-.57-.255-.284-.752-1.705-1.105-3.16-1.03-4.254-2.413-6.64-5.193-8.965-.878-.733-1.595-1.418-1.595-1.522 0-.102.965-.915 2.145-1.803 4.298-3.24 6.77-7.012 7.04-10.747.519-7.126-5.158-13.767-13.602-15.92-2.002-.51-2.857-.526-27.624-.526-14.057 0-25.56-.092-25.56-.204 0-.263 3.125-3.295 4.965-4.816 5.054-4.178 11.618-7.465 18.417-9.22l2.35-.61 3.34 3.387c1.839 1.863 3.64 3.5 4.003 3.637M20.3 46.34c1.539 1.008 2.17 3.54 1.26 5.062-1.405 2.356-4.966 2.455-6.373.178-2.046-3.309 1.895-7.349 5.113-5.24m90.672.13c4.026 2.454.906 8.493-3.404 6.586-2.877-1.273-2.97-5.206-.155-6.64 1.174-.6 2.523-.579 3.56.053M32.163 61.5v15.02h-13.28l-.526-2.285c-1.036-4.5-1.472-9.156-1.211-12.969l.182-2.679 4.565-2.047c2.864-1.283 4.706-2.262 4.943-2.625 1.038-1.584.94-2.715-.518-5.933l-.68-1.502h6.523V61.5M70.39 47.132c2.843.74 4.345 2.245 4.349 4.355.002 1.55-.765 2.52-2.67 3.38-1.348.61-1.562.625-10.063.708l-8.686.084v-8.92h7.782c6.078 0 8.112.086 9.288.393m-2.934 21.554c1.41.392 3.076 1.616 3.93 2.888.898 1.337 1.423 3.076 2.667 8.836 1.05 4.87 1.727 6.46 3.62 8.532 2.345 2.566 1.8 2.466 13.514 2.466 5.61 0 10.198.09 10.198.2 0 .197-3.863 4.764-4.03 4.764-.048 0-2.066-.422-4.484-.939-6.829-1.458-7.075-1.287-8.642 6.032l-1.008 4.702-.91.448c-1.518.75-6.453 2.292-9.01 2.82-4.228.87-8.828 1.162-12.871.821-6.893-.585-16.02-3.259-16.377-4.8-.075-.327-.535-2.443-1.018-4.704-.485-2.26-1.074-4.404-1.31-4.764-1.13-1.724-2.318-1.83-7.547-.674-1.98.44-3.708.796-3.84.796-.248 0-3.923-4.249-3.923-4.535 0-.09 8.728-.194 19.396-.23l19.395-.066.07-6.89c.05-4.865-.018-6.997-.23-7.25-.234-.284-1.485-.358-6.011-.358H53.32v-8.36l6.597.001c3.626.002 7.02.12 7.539.264M37.57 100.02c3.084 1.88 1.605 6.804-2.043 6.8-3.74 0-5.127-4.88-1.94-6.826 1.055-.643 2.908-.63 3.983.026m56.48.206c1.512 1.108 2.015 3.413 1.079 4.95-2.46 4.034-8.612.827-6.557-3.419 1.01-2.085 3.695-2.837 5.478-1.53"></path>
          </svg>;
      case "elixir":
        return <svg viewBox="0 0 128 128">
            <linearGradient id="elixir-original-a" gradientUnits="userSpaceOnUse" x1="835.592" y1="-36.546" x2="821.211" y2="553.414" gradientTransform="matrix(.1297 0 0 .2 -46.03 17.198)">
              <stop offset="0" stopColor="#d9d8dc"></stop>
              <stop offset="1" stopColor="#fff" stopOpacity=".385"></stop>
            </linearGradient>
            <path fillRule="evenodd" clipRule="evenodd" fill="url(#elixir-original-a)" d="M64.4.5C36.7 13.9 1.9 83.4 30.9 113.9c26.8 33.5 85.4 1.3 68.4-40.5-21.5-36-35-37.9-34.9-72.9z"></path>
            <linearGradient id="elixir-original-b" gradientUnits="userSpaceOnUse" x1="942.357" y1="-40.593" x2="824.692" y2="472.243" gradientTransform="matrix(.1142 0 0 .2271 -47.053 17.229)">
              <stop offset="0" stopColor="#8d67af" stopOpacity=".672"></stop>
              <stop offset="1" stopColor="#9f8daf"></stop>
            </linearGradient>
            <path fillRule="evenodd" clipRule="evenodd" fill="url(#elixir-original-b)" d="M64.4.2C36.8 13.6 1.9 82.9 31 113.5c10.7 12.4 28 16.5 37.7 9.1 26.4-18.8 7.4-53.1 10.4-78.5C68.1 33.9 64.2 11.3 64.4.2z"></path>
            <linearGradient id="elixir-original-c" gradientUnits="userSpaceOnUse" x1="924.646" y1="120.513" x2="924.646" y2="505.851" gradientTransform="matrix(.1227 0 0 .2115 -46.493 17.206)">
              <stop offset="0" stopColor="#26053d" stopOpacity=".762"></stop>
              <stop offset="1" stopColor="#b7b4b4" stopOpacity=".278"></stop>
            </linearGradient>
            <path fillRule="evenodd" clipRule="evenodd" fill="url(#elixir-original-c)" d="M56.7 4.3c-22.3 15.9-28.2 75-24.1 94.2 8.2 48.1 75.2 28.3 69.6-16.5-6-29.2-48.8-39.2-45.5-77.7z"></path>
            <linearGradient id="elixir-original-d" gradientUnits="userSpaceOnUse" x1="428.034" y1="198.448" x2="607.325" y2="559.255" gradientTransform="matrix(.1848 0 0 .1404 -42.394 17.138)">
              <stop offset="0" stopColor="#91739f" stopOpacity=".46"></stop>
              <stop offset="1" stopColor="#32054f" stopOpacity=".54"></stop>
            </linearGradient>
            <path fillRule="evenodd" clipRule="evenodd" fill="url(#elixir-original-d)" d="M78.8 49.8c10.4 13.4 12.7 22.6 6.8 27.9-27.7 19.4-61.3 7.4-54-37.3C22.1 63 4.5 96.8 43.3 101.6c20.8 3.6 54 2 58.9-16.1-.2-15.9-10.8-22.9-23.4-35.7z"></path>
            <linearGradient id="elixir-original-e" gradientUnits="userSpaceOnUse" x1="907.895" y1="540.636" x2="590.242" y2="201.281" gradientTransform="matrix(.1418 0 0 .1829 -45.23 17.18)">
              <stop offset="0" stopColor="#463d49" stopOpacity=".331"></stop>
              <stop offset="1" stopColor="#340a50" stopOpacity=".821"></stop>
            </linearGradient>
            <path fillRule="evenodd" clipRule="evenodd" fill="url(#elixir-original-e)" d="M38.1 36.4c-2.9 21.2 35.1 77.9 58.3 71-17.7 35.6-56.9-21.2-64-41.7 1.5-11 2.2-16.4 5.7-29.3z"></path>
            <linearGradient id="elixir-original-f" gradientUnits="userSpaceOnUse" x1="1102.297" y1="100.542" x2="1008.071" y2="431.648" gradientTransform="matrix(.106 0 0 .2448 -47.595 17.242)">
              <stop offset="0" stopColor="#715383" stopOpacity=".145"></stop>
              <stop offset="1" stopColor="#f4f4f4" stopOpacity=".234"></stop>
            </linearGradient>
            <path fillRule="evenodd" clipRule="evenodd" fill="url(#elixir-original-f)" d="M60.4 49.7c.8 7.9 3.9 20.5 0 28.8S38.7 102 43.6 115.3c11.4 24.8 37.1-4.4 36.9-19 1.1-11.8-6.6-38.7-1.8-52.5L76.5 41l-13.6-4c-2.2 3.2-3 7.5-2.5 12.7z"></path>
            <linearGradient id="elixir-original-g" gradientUnits="userSpaceOnUse" x1="1354.664" y1="140.06" x2="1059.233" y2="84.466" gradientTransform="matrix(.09173 0 0 .2828 -48.536 17.28)">
              <stop offset="0" stopColor="#a5a1a8" stopOpacity=".356"></stop>
              <stop offset="1" stopColor="#370c50" stopOpacity=".582"></stop>
            </linearGradient>
            <path fillRule="evenodd" clipRule="evenodd" fill="url(#elixir-original-g)" d="M65.3 10.8C36 27.4 48 53.4 49.3 81.6l19.1-55.4c-1.4-5.7-2.3-9.5-3.1-15.4z"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#330A4C" fillOpacity=".316" d="M68.3 26.1c-14.8 11.7-14.1 31.3-18.6 54 8.1-21.3 4.1-38.2 18.6-54z"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#FFF" d="M45.8 119.7c8 1.1 12.1 2.2 12.5 3 .3 4.2-11.1 1.2-12.5-3z"></path>
            <path fillRule="evenodd" clipRule="evenodd" fill="#EDEDED" fillOpacity=".603" d="M49.8 10.8c-6.9 7.7-14.4 21.8-18.2 29.7-1 6.5-.5 15.7.6 23.5.9-18.2 7.5-39.2 17.6-53.2z"></path>
          </svg>;
      case "kotlin":
        return <svg viewBox="0 0 128 128">
            <defs>
              <linearGradient id="a" x1="500.003" x2="-.097" y1="579.106" y2="1079.206" gradientTransform="translate(15.534 -96.774) scale(.1939)" gradientUnits="userSpaceOnUse">
                <stop offset=".003" stopColor="#e44857"></stop>
                <stop offset=".469" stopColor="#c711e1"></stop>
                <stop offset="1" stopColor="#7f52ff"></stop>
              </linearGradient>
            </defs>
            <path fill="url(#a)" d="M112.484 112.484H15.516V15.516h96.968L64 64Zm0 0"></path>
          </svg>;
      case "swift":
        return <svg viewBox="0 0 128 128">
            <path fill="#f05138" d="M126.33 34.06a39.32 39.32 0 00-.79-7.83 28.78 28.78 0 00-2.65-7.58 28.84 28.84 0 00-4.76-6.32 23.42 23.42 0 00-6.62-4.55 27.27 27.27 0 00-7.68-2.53c-2.65-.51-5.56-.51-8.21-.76H30.25a45.46 45.46 0 00-6.09.51 21.82 21.82 0 00-5.82 1.52c-.53.25-1.32.51-1.85.76a33.82 33.82 0 00-5 3.28c-.53.51-1.06.76-1.59 1.26a22.41 22.41 0 00-4.76 6.32 23.61 23.61 0 00-2.65 7.58 78.5 78.5 0 00-.79 7.83v60.39a39.32 39.32 0 00.79 7.83 28.78 28.78 0 002.65 7.58 28.84 28.84 0 004.76 6.32 23.42 23.42 0 006.62 4.55 27.27 27.27 0 007.68 2.53c2.65.51 5.56.51 8.21.76h63.22a45.08 45.08 0 008.21-.76 27.27 27.27 0 007.68-2.53 30.13 30.13 0 006.62-4.55 22.41 22.41 0 004.76-6.32 23.61 23.61 0 002.65-7.58 78.49 78.49 0 00.79-7.83V34.06z"></path>
            <path fill="#fefefe" d="M85 96.5c-11.11 6.13-26.38 6.76-41.75.47A64.53 64.53 0 0113.84 73a50 50 0 0010.85 6.32c15.87 7.1 31.73 6.61 42.9 0-15.9-11.66-29.4-26.82-39.46-39.2a43.47 43.47 0 01-5.29-6.82c12.16 10.61 31.5 24 38.38 27.79a271.77 271.77 0 01-27-32.34 266.8 266.8 0 0044.47 34.87c.71.38 1.26.7 1.7 1a32.7 32.7 0 001.21-3.51c3.71-12.89-.53-27.54-9.79-39.67C93.25 33.81 106 57.05 100.66 76.51c-.14.53-.29 1-.45 1.55l.19.22c10.59 12.63 7.68 26 6.35 23.5C101 91 90.37 94.33 85 96.5z"></path>
          </svg>;
      case "edgeCloudflare":
        return <svg viewBox="0 0 128 128">
            <path fill="#FFF" d="m115.679 69.288-15.591-8.94-2.689-1.163-63.781.436v32.381h82.061z"></path>
            <path fill="#F38020" d="M87.295 89.022c.763-2.617.472-5.015-.8-6.796-1.163-1.635-3.125-2.58-5.488-2.689l-44.737-.581c-.291 0-.545-.145-.691-.363s-.182-.509-.109-.8c.145-.436.581-.763 1.054-.8l45.137-.581c5.342-.254 11.157-4.579 13.192-9.885l2.58-6.723c.109-.291.145-.581.073-.872-2.906-13.158-14.644-22.97-28.672-22.97-12.938 0-23.913 8.359-27.838 19.952a13.35 13.35 0 0 0-9.267-2.58c-6.215.618-11.193 5.597-11.811 11.811-.145 1.599-.036 3.162.327 4.615C10.104 70.051 2 78.337 2 88.549c0 .909.073 1.817.182 2.726a.895.895 0 0 0 .872.763h82.57c.472 0 .909-.327 1.054-.8l.617-2.216z"></path>
            <path fill="#FAAE40" d="M101.542 60.275c-.4 0-.836 0-1.236.036-.291 0-.545.218-.654.509l-1.744 6.069c-.763 2.617-.472 5.015.8 6.796 1.163 1.635 3.125 2.58 5.488 2.689l9.522.581c.291 0 .545.145.691.363.145.218.182.545.109.8-.145.436-.581.763-1.054.8l-9.924.582c-5.379.254-11.157 4.579-13.192 9.885l-.727 1.853c-.145.363.109.727.509.727h34.089c.4 0 .763-.254.872-.654.581-2.108.909-4.325.909-6.614 0-13.447-10.975-24.422-24.458-24.422"></path>
          </svg>;
      case "edgeFastly":
        return <svg viewBox="0 0 24 24">
            <path fill="#ff282d" d="M13.919 3.036V1.3h.632V0H9.377v1.3h.631v1.749a10.572 10.572 0 00-8.575 10.384C1.433 19.275 6.17 24 12 24c5.842 0 10.567-4.737 10.567-10.567 0-5.186-3.729-9.486-8.648-10.397zm-1.628 15.826v-.607h-.619v.607c-2.757-.158-4.955-2.38-5.101-5.137h.607v-.62h-.607a5.436 5.436 0 015.101-5.089v.607h.62v-.607a5.435 5.435 0 015.137 5.114h-.607v.619h.607a5.444 5.444 0 01-5.138 5.113zm2.26-7.712l-.39-.389-1.979 1.725a.912.912 0 00-.316-.06c-.534 0-.971.448-.971.995 0 .547.437.996.971.996.535 0 .972-.45.972-.996a.839.839 0 00-.049-.304Z" />
          </svg>;
      case "edgeLambda":
        return <svg viewBox="0 0 24 24">
            <path fill="#e57714" d="M4.9855 0c-.2941.0031-.5335.2466-.534.5482L4.446 5.456c0 .1451.06.2835.159.3891a.5322.5322 0 0 0 .3806.1562h3.4282l8.197 17.6805a.5365.5365 0 0 0 .4885.3181h5.811c.2969 0 .5426-.2448.5426-.5482V18.544c0-.3035-.2392-.5482-.5425-.5482h-2.0138L12.7394.3153C12.647.124 12.4564 0 12.2452 0h-7.254Zm.5397 1.0907h6.3678l8.16 17.6804a.5365.5365 0 0 0 .4885.3181h1.8178v3.8173H17.437L9.2402 5.226a.536.536 0 0 0-.4885-.318H5.5223Zm2.0137 8.2366c-.2098.0011-.3937.1193-.4857.3096L.6002 23.2133a.5506.5506 0 0 0 .0313.5282.5334.5334 0 0 0 .4544.25h6.169a.5468.5468 0 0 0 .497-.3096l3.38-7.166a.5405.5405 0 0 0-.0029-.4686L8.036 9.637a.5468.5468 0 0 0-.4942-.3096Zm.0057 1.8036 2.488 5.1522-3.1214 6.6206H1.9465Z" />
          </svg>;
      case "edgeUtils":
        return <svg viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M11 18.004h-4.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99a3.468 3.468 0 0 1 3.307 2.444"></path>
            <path d="M20 21l2 -2l-2 -2"></path>
            <path d="M17 17l-2 2l2 2"></path>
          </svg>;
      case "vercel":
        return <svg viewBox="0 0 128 128">
            <path d="M64.002 8.576 128 119.424H0Zm0 0"></path>
          </svg>;
      case "flutter":
        return <svg viewBox="0 0 128 128">
            <g fill="#3FB6D3">
              <path d="M12.3 64.2L76.3 0h39.4L32.1 83.6zM76.3 128h39.4L81.6 93.9l34.1-34.8H76.3L42.2 93.5z"></path>
            </g>
            <path fill="#27AACD" d="M81.6 93.9l-20-20-19.4 19.6 19.4 19.6z"></path>
            <path fill="#19599A" d="M115.7 128L81.6 93.9l-20 19.2L76.3 128z"></path>
            <linearGradient id="flutter-original-a" gradientUnits="userSpaceOnUse" x1="59.365" y1="116.36" x2="86.825" y2="99.399">
              <stop offset="0" stopColor="#1b4e94"></stop>
              <stop offset=".63" stopColor="#1a5497"></stop>
              <stop offset="1" stopColor="#195a9b"></stop>
            </linearGradient>
            <path fill="url(#flutter-original-a)" d="M61.6 113.1l30.8-8.4-10.8-10.8z"></path>
          </svg>;
      case "roku":
        return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
            <path fill="var(--color-inverse)" d="M5.15 11.042a1.02 1.02 0 0 0-1.016-1.026H3.63v2.043h.504a1.02 1.02 0 0 0 1.016-1.017Zm2.292 4.072h-1.85l-1.468-2.038H3.63v2.033H2V9h2.335c1.346 0 2.445.915 2.445 2.042 0 .687-.421 1.3-1.062 1.676l1.724 2.396Z" />
            <path fill="var(--color-inverse)" d="M9.28 11.408c-.43 0-.797.585-.797 1.31 0 .725.366 1.31.797 1.31.44 0 .806-.586.806-1.31 0-.724-.366-1.31-.806-1.31Zm2.51 1.31a2.497 2.497 0 0 1-2.51 2.491 2.49 2.49 0 0 1-2.5-2.491 2.49 2.49 0 0 1 2.5-2.492 2.497 2.497 0 0 1 2.51 2.492Zm3.824-2.39-1.878 1.877v-1.884h-1.63v4.788h1.63v-1.943l1.96 1.943h2.052l-2.491-2.492 2.063-2.062v2.84c0 .944.567 1.814 1.996 1.814.678 0 1.3-.384 1.603-.732l.733.632H22v-4.781h-1.63v3.096c-.183.32-.439.521-.834.521-.401 0-.585-.237-.585-.998v-2.619h-3.337Z" />
          </svg>;
      default:
        return <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256">
            <path d="M69.12,94.15,28.5,128l40.62,33.85a8,8,0,1,1-10.24,12.29l-48-40a8,8,0,0,1,0-12.29l48-40a8,8,0,0,1,10.24,12.3Zm176,27.7-48-40a8,8,0,1,0-10.24,12.3L227.5,128l-40.62,33.85a8,8,0,1,0,10.24,12.29l48-40a8,8,0,0,0,0-12.29ZM162.73,32.48a8,8,0,0,0-10.25,4.79l-64,176a8,8,0,0,0,4.79,10.26A8.14,8.14,0,0,0,96,224a8,8,0,0,0,7.52-5.27l64-176A8,8,0,0,0,162.73,32.48Z"></path>
          </svg>;
    }
  };
  const GitBranch = () => {
    return <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256">
        <path d="M232,64a32,32,0,1,0-40,31v17a8,8,0,0,1-8,8H96a23.84,23.84,0,0,0-8,1.38V95a32,32,0,1,0-16,0v66a32,32,0,1,0,16,0V144a8,8,0,0,1,8-8h88a24,24,0,0,0,24-24V95A32.06,32.06,0,0,0,232,64ZM64,64A16,16,0,1,1,80,80,16,16,0,0,1,64,64ZM96,192a16,16,0,1,1-16-16A16,16,0,0,1,96,192ZM200,80a16,16,0,1,1,16-16A16,16,0,0,1,200,80Z"></path>
      </svg>;
  };
  const FileCode = () => {
    return <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256">
        <path d="M181.66,146.34a8,8,0,0,1,0,11.32l-24,24a8,8,0,0,1-11.32-11.32L164.69,152l-18.35-18.34a8,8,0,0,1,11.32-11.32Zm-72-24a8,8,0,0,0-11.32,0l-24,24a8,8,0,0,0,0,11.32l24,24a8,8,0,0,0,11.32-11.32L91.31,152l18.35-18.34A8,8,0,0,0,109.66,122.34ZM216,88V216a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V40A16,16,0,0,1,56,24h96a8,8,0,0,1,5.66,2.34l56,56A8,8,0,0,1,216,88Zm-56-8h28.69L160,51.31Zm40,136V96H152a8,8,0,0,1-8-8V40H56V216H200Z"></path>
      </svg>;
  };
  const Package = () => {
    return <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256">
        <path d="M223.68,66.15,135.68,18a15.88,15.88,0,0,0-15.36,0l-88,48.17a16,16,0,0,0-8.32,14v95.64a16,16,0,0,0,8.32,14l88,48.17a15.88,15.88,0,0,0,15.36,0l88-48.17a16,16,0,0,0,8.32-14V80.18A16,16,0,0,0,223.68,66.15ZM128,32l80.34,44-29.77,16.3-80.35-44ZM128,120,47.66,76l33.9-18.56,80.34,44ZM40,90l80,43.78v85.79L40,175.82Zm176,85.78h0l-80,43.79V133.82l32-17.51V152a8,8,0,0,0,16,0V107.55L216,90v85.77Z"></path>
      </svg>;
  };
  const sdkInfo = {
    js: {
      name: "JS SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-js",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/vanilla-typescript",
        name: "Typescript example app"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.36.0"
      }, {
        prerequisites: "≥ v0.34.0"
      }, {
        stickyBucketing: "≥ v0.32.0"
      }, {
        visualEditorDragDrop: "≥ v0.30.0"
      }, {
        remoteEval: "≥ v0.29.0"
      }, {
        semverTargeting: "≥ v0.27.0"
      }, {
        visualEditorJS: "≥ v0.27.0"
      }, {
        visualEditor: "≥ v0.24.0"
      }, {
        bucketingV2: "≥ v0.23.0"
      }, {
        streaming: "≥ v0.21.0"
      }, {
        encryption: "≥ v0.20.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    react: {
      name: "React SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-react",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/next-js",
        name: "Next.js example app"
      }, {
        url: "https://github.com/growthbook/examples/tree/main/next-js-pages",
        name: "Next.js pages example app"
      }, {
        url: "https://docs.growthbook.io/guide/create-react-app-and-growthbook",
        name: "Create React App guide"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook-react"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.26.0"
      }, {
        prerequisites: "≥ v0.24.0"
      }, {
        stickyBucketing: "≥ v0.22.0"
      }, {
        visualEditorDragDrop: "≥ v0.20.0"
      }, {
        remoteEval: "≥ v0.19.0"
      }, {
        semverTargeting: "≥ v0.17.0"
      }, {
        visualEditorJS: "≥ v0.17.0"
      }, {
        visualEditor: "≥ v0.14.0"
      }, {
        bucketingV2: "≥ v0.13.0"
      }, {
        streaming: "≥ v0.11.0"
      }, {
        encryption: "≥ v0.10.1"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    nextjs: {
      name: "Next.js SDK",
      version: "0.1.0",
      github: "https://github.com/vercel/flags/tree/main/packages/adapter-growthbook",
      examples: [{
        url: "https://github.com/vercel/examples/tree/main/flags-sdk/growthbook",
        name: "Next.js Flags SDK example app"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@flags-sdk/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        savedGroupReferences: "≥ v0.1.0"
      }, {
        redirects: "≥ v0.1.0"
      }, {
        prerequisites: "≥ v0.1.0"
      }, {
        stickyBucketing: "≥ v0.1.0"
      }, {
        semverTargeting: "≥ v0.1.0"
      }, {
        bucketingV2: "≥ v0.1.0"
      }, {
        encryption: "≥ v0.1.0"
      }, {
        looseUnmarshalling: "≥ v0.1.0"
      }, {
        namespacesV2: "≥ v0.1.0"
      }]
    },
    php: {
      name: "PHP SDK",
      version: "2.6.1",
      github: "https://github.com/growthbook/growthbook-php",
      examples: [],
      packageRepos: [{
        name: "Packagist (Composer)",
        url: "https://packagist.org/packages/growthbook/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        remoteEval: "≥ v2.5.0"
      }, {
        trackingPlugin: "≥ v2.4.0"
      }, {
        caseInsensitiveRegex: "≥ v2.3.0"
      }, {
        caseInsensitiveMembership: "≥ v2.3.0"
      }, {
        savedGroupReferences: "≥ v1.7.0"
      }, {
        prerequisites: "≥ v1.6.0"
      }, {
        stickyBucketing: "≥ v1.6.0"
      }, {
        semverTargeting: "≥ v1.5.0"
      }, {
        bucketingV2: "≥ v1.2.0"
      }, {
        encryption: "≥ v1.2.0"
      }, {
        looseUnmarshalling: "≥ v1.0.0"
      }, {
        namespacesV2: "≥ v1.0.0"
      }]
    },
    node: {
      name: "Node SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-js",
      examples: [{
        url: "https://docs.growthbook.io/guide/express-js",
        name: "Express.js guide"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.36.0"
      }, {
        prerequisites: "≥ v0.34.0"
      }, {
        stickyBucketing: "≥ v0.32.0"
      }, {
        semverTargeting: "≥ v0.27.0"
      }, {
        bucketingV2: "≥ v0.23.0"
      }, {
        streaming: "≥ v0.21.0"
      }, {
        encryption: "≥ v0.20.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    ruby: {
      name: "Ruby SDK",
      version: "1.3.0",
      github: "https://github.com/growthbook/growthbook-ruby",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/acme_donuts_rails",
        name: "Rails example app"
      }],
      packageRepos: [{
        name: "RubyGems",
        url: "https://rubygems.org/gems/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        prerequisites: "≥ v1.3.0"
      }, {
        stickyBucketing: "≥ v1.3.0"
      }, {
        semverTargeting: "≥ v1.2.2"
      }, {
        encryption: "≥ v1.1.0"
      }, {
        bucketingV2: "≥ v1.0.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    python: {
      name: "Python SDK",
      version: "2.4.0",
      github: "https://github.com/growthbook/growthbook-python",
      examples: [],
      packageRepos: [{
        name: "PyPi",
        url: "https://pypi.org/project/growthbook/"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        remoteEval: "≥ v2.3.0"
      }, {
        trackingPlugin: "≥ v2.2.0"
      }, {
        caseInsensitiveMembership: "≥ v2.1.1"
      }, {
        caseInsensitiveRegex: "≥ v2.1.0"
      }, {
        savedGroupReferences: "≥ v1.2.1"
      }, {
        looseUnmarshalling: "≥ v1.1.0"
      }, {
        namespacesV2: "≥ v1.1.0"
      }, {
        prerequisites: "≥ v1.1.0"
      }, {
        stickyBucketing: "≥ v1.1.0"
      }, {
        semverTargeting: "≥ v1.1.0"
      }, {
        bucketingV2: "≥ v1.0.0"
      }, {
        encryption: "≥ v1.0.0"
      }]
    },
    go: {
      name: "Go SDK",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-golang",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/go-example",
        name: "Go example app"
      }],
      packageRepos: [{
        name: "Go Modules",
        url: "https://pkg.go.dev/github.com/growthbook/growthbook-golang"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        trackingPlugin: "≥ v0.2.8"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        stickyBucketing: "≥ v0.2.3"
      }, {
        prerequisites: "≥ v0.2.0"
      }, {
        savedGroupReferences: "≥ v0.2.0"
      }, {
        bucketingV2: "≥ v0.1.4"
      }, {
        streaming: "≥ v0.1.4"
      }, {
        semverTargeting: "≥ v0.1.4"
      }, {
        encryption: "≥ v0.1.4"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    rust: {
      name: "Rust SDK",
      version: "0.2.1",
      github: "https://github.com/growthbook/growthbook-rust",
      examples: [{
        url: "https://github.com/growthbook/growthbook-rust/tree/main/examples/client",
        name: "Rust example app"
      }],
      packageRepos: [{
        name: "crates.io",
        url: "https://crates.io/crates/growthbook-rust"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        savedGroupReferences: "≥ v0.2.0"
      }, {
        caseInsensitiveRegex: "≥ v0.1.1"
      }, {
        caseInsensitiveMembership: "≥ v0.1.1"
      }, {
        stickyBucketing: "≥ v0.1.0"
      }, {
        encryption: "≥ v0.0.1"
      }, {
        looseUnmarshalling: "≥ v0.0.1"
      }, {
        namespacesV2: "≥ v0.0.1"
      }, {
        prerequisites: "≥ v0.0.1"
      }, {
        semverTargeting: "≥ v0.0.1"
      }, {
        bucketingV2: "≥ v0.0.1"
      }]
    },
    java: {
      name: "Java SDK",
      version: "0.10.10",
      github: "https://github.com/growthbook/growthbook-sdk-java",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/jvm-spring-web",
        name: "JVM with Spring Web example app"
      }, {
        url: "https://github.com/growthbook/examples/tree/main/jvm-kotlin-ktor-example",
        name: "JVM with Kotlin Ktor example app"
      }, {
        url: "https://github.com/growthbook/examples/tree/main/android-example",
        name: "Android example app"
      }, {
        url: "https://growthbook.github.io/growthbook-sdk-java/",
        name: "JavaDoc class docs"
      }],
      packageRepos: [{
        name: "JitPack",
        url: "https://jitpack.io/#growthbook/growthbook-sdk-java"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveMembership: "≥ v0.10.9"
      }, {
        caseInsensitiveRegex: "≥ v0.10.6"
      }, {
        remoteEval: "≥ v0.9.92"
      }, {
        prerequisites: "≥ v0.9.3"
      }, {
        stickyBucketing: "≥ v0.9.3"
      }, {
        streaming: "≥ v0.9.0"
      }, {
        semverTargeting: "≥ v0.7.0"
      }, {
        bucketingV2: "≥ v0.6.0"
      }, {
        encryption: "≥ v0.3.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    csharp: {
      name: "C# SDK",
      version: "1.2.0",
      github: "https://github.com/growthbook/growthbook-c-sharp",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/csharp-example/GrowthBookCSharpExamples",
        name: "C# example app"
      }],
      packageRepos: [{
        name: "NuGet",
        url: "https://www.nuget.org/packages/growthbook-c-sharp"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveMembership: "≥ v1.2.0"
      }, {
        caseInsensitiveRegex: "≥ v1.2.0"
      }, {
        remoteEval: "≥ v1.1.3"
      }, {
        stickyBucketing: "≥ v1.1.0"
      }, {
        prerequisites: "≥ v1.1.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        encryption: "≥ v1.0.0"
      }, {
        streaming: "≥ v1.0.0"
      }, {
        bucketingV2: "≥ v1.0.0"
      }, {
        semverTargeting: "≥ v1.0.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    elixir: {
      name: "Elixir SDK",
      version: "0.3.0",
      github: "https://github.com/growthbook/growthbook-elixir",
      examples: [],
      packageRepos: [{
        name: "Hex",
        url: "https://www.hex.pm/packages/growthbook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        encryption: "≥ v0.3.0"
      }, {
        prerequisites: "≥ v0.2.0"
      }, {
        semverTargeting: "≥ v0.2.0"
      }, {
        bucketingV2: "≥ v0.2.0"
      }, {
        looseUnmarshalling: "≥ v0.2.0"
      }, {
        namespacesV2: "≥ v0.2.0"
      }]
    },
    kotlin: {
      name: "Kotlin SDK",
      version: "7.6.0",
      github: "https://github.com/growthbook/growthbook-kotlin",
      examples: [],
      packageRepos: [{
        name: "Maven Central",
        url: "https://mvnrepository.com/artifact/io.growthbook.sdk/GrowthBook"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveMembership: "≥ v7.1.1"
      }, {
        caseInsensitiveRegex: "≥ v7.1.1"
      }, {
        remoteEval: "≥ v1.1.50"
      }, {
        streaming: "≥ v1.1.50"
      }, {
        prerequisites: "≥ v1.1.44"
      }, {
        stickyBucketing: "≥ v1.1.44"
      }, {
        bucketingV2: "≥ v1.1.38"
      }, {
        semverTargeting: "≥ v1.1.31"
      }, {
        encryption: "≥ v1.1.23"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    swift: {
      name: "Swift SDK",
      version: "1.2.0",
      github: "https://github.com/growthbook/growthbook-swift",
      examples: [],
      packageRepos: [{
        name: "Swift Package Manager (SPM)",
        url: "https://swiftpackageindex.com/growthbook/growthbook-swift"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        namespacesV2: "≥ v1.1.4"
      }, {
        caseInsensitiveMembership: "≥ v1.1.1"
      }, {
        caseInsensitiveRegex: "≥ v1.1.1"
      }, {
        remoteEval: "≥ v1.0.50"
      }, {
        stickyBucketing: "≥ v1.0.49"
      }, {
        prerequisites: "≥ v1.0.49"
      }, {
        bucketingV2: "≥ v1.0.43"
      }, {
        streaming: "≥ v1.0.43"
      }, {
        semverTargeting: "≥ v1.0.38"
      }, {
        encryption: "≥ v1.0.35"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }]
    },
    reactNative: {
      name: "React Native SDK",
      version: "1.7.0",
      github: "https://github.com/growthbook/growthbook/tree/main/packages/sdk-react",
      examples: [{
        url: "https://github.com/growthbook/examples/tree/main/react-native-cli",
        name: "React Native CLI example app"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/growthbook-react"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        contextualBandits: "≥ v1.7.0"
      }, {
        caseInsensitiveMembership: "≥ v1.6.4"
      }, {
        caseInsensitiveRegex: "≥ v1.6.3"
      }, {
        trackingPlugin: "≥ v1.4.0"
      }, {
        savedGroupReferences: "≥ v1.1.0"
      }, {
        redirects: "≥ v0.26.0"
      }, {
        prerequisites: "≥ v0.24.0"
      }, {
        stickyBucketing: "≥ v0.22.0"
      }, {
        visualEditorDragDrop: "≥ v0.20.0"
      }, {
        remoteEval: "≥ v0.19.0"
      }, {
        semverTargeting: "≥ v0.17.0"
      }, {
        visualEditorJS: "≥ v0.17.0"
      }, {
        visualEditor: "≥ v0.14.0"
      }, {
        bucketingV2: "≥ v0.13.0"
      }, {
        streaming: "≥ v0.11.0"
      }, {
        encryption: "≥ v0.10.1"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    edgeCloudflare: {
      name: "Cloudflare Workers App & SDK",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-cloudflare",
      examples: [{
        url: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-cloudflare/example",
        name: "Example worker"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-cloudflare"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        savedGroupReferences: "≥ v0.1.12"
      }, {
        looseUnmarshalling: "≥ v0.1.11"
      }, {
        namespacesV2: "≥ v0.1.11"
      }, {
        encryption: "≥ v0.1.11"
      }, {
        streaming: "≥ v0.1.11"
      }, {
        bucketingV2: "≥ v0.1.11"
      }, {
        visualEditor: "≥ v0.1.11"
      }, {
        semverTargeting: "≥ v0.1.11"
      }, {
        visualEditorJS: "≥ v0.1.11"
      }, {
        visualEditorDragDrop: "≥ v0.1.11"
      }, {
        prerequisites: "≥ v0.1.11"
      }, {
        redirects: "≥ v0.1.11"
      }, {
        stickyBucketing: "≥ v0.1.11"
      }]
    },
    edgeFastly: {
      name: "Fastly Compute App & SDK",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-fastly",
      examples: [{
        url: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-fastly/example",
        name: "Example compute worker"
      }],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-fastly"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        savedGroupReferences: "≥ v0.1.6"
      }, {
        looseUnmarshalling: "≥ v0.1.5"
      }, {
        namespacesV2: "≥ v0.1.5"
      }, {
        encryption: "≥ v0.1.5"
      }, {
        streaming: "≥ v0.1.5"
      }, {
        bucketingV2: "≥ v0.1.5"
      }, {
        visualEditor: "≥ v0.1.5"
      }, {
        semverTargeting: "≥ v0.1.5"
      }, {
        visualEditorJS: "≥ v0.1.5"
      }, {
        visualEditorDragDrop: "≥ v0.1.5"
      }, {
        prerequisites: "≥ v0.1.5"
      }, {
        redirects: "≥ v0.1.5"
      }, {
        stickyBucketing: "≥ v0.1.5"
      }]
    },
    edgeLambda: {
      name: "Lambda@Edge App & SDK",
      version: "0.0.29",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-lambda",
      examples: [],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-lambda"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.0.27"
      }, {
        caseInsensitiveMembership: "≥ v0.0.27"
      }, {
        savedGroupReferences: "≥ v0.0.7"
      }, {
        looseUnmarshalling: "≥ v0.0.6"
      }, {
        namespacesV2: "≥ v0.0.6"
      }, {
        encryption: "≥ v0.0.6"
      }, {
        streaming: "≥ v0.0.6"
      }, {
        bucketingV2: "≥ v0.0.6"
      }, {
        visualEditor: "≥ v0.0.6"
      }, {
        semverTargeting: "≥ v0.0.6"
      }, {
        visualEditorJS: "≥ v0.0.6"
      }, {
        visualEditorDragDrop: "≥ v0.0.6"
      }, {
        prerequisites: "≥ v0.0.6"
      }, {
        redirects: "≥ v0.0.6"
      }, {
        stickyBucketing: "≥ v0.0.6"
      }]
    },
    edgeUtils: {
      name: "Edge Utils",
      version: "0.2.9",
      github: "https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-utils",
      examples: [],
      packageRepos: [{
        name: "npm",
        url: "https://www.npmjs.com/package/@growthbook/edge-utils"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        caseInsensitiveRegex: "≥ v0.2.7"
      }, {
        caseInsensitiveMembership: "≥ v0.2.7"
      }, {
        savedGroupReferences: "≥ v0.1.5"
      }, {
        looseUnmarshalling: "≥ v0.1.4"
      }, {
        namespacesV2: "≥ v0.1.4"
      }, {
        encryption: "≥ v0.1.4"
      }, {
        streaming: "≥ v0.1.4"
      }, {
        bucketingV2: "≥ v0.1.4"
      }, {
        visualEditor: "≥ v0.1.4"
      }, {
        semverTargeting: "≥ v0.1.4"
      }, {
        visualEditorJS: "≥ v0.1.4"
      }, {
        visualEditorDragDrop: "≥ v0.1.4"
      }, {
        prerequisites: "≥ v0.1.4"
      }, {
        redirects: "≥ v0.1.4"
      }, {
        stickyBucketing: "≥ v0.1.4"
      }]
    },
    flutter: {
      name: "Flutter SDK",
      version: "4.4.0",
      github: "https://github.com/growthbook/growthbook-flutter",
      examples: [],
      packageRepos: [{
        name: "pub.dev",
        url: "https://pub.dev/packages/growthbook_sdk_flutter"
      }],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        trackingPlugin: "≥ v4.4.0"
      }, {
        caseInsensitiveRegex: "≥ v4.3.0"
      }, {
        caseInsensitiveMembership: "≥ v4.3.0"
      }, {
        savedGroupReferences: "≥ v3.9.4"
      }, {
        stickyBucketing: "≥ v3.8.0"
      }, {
        remoteEval: "≥ v3.7.0"
      }, {
        streaming: "≥ v3.4.0"
      }, {
        prerequisites: "≥ v3.2.0"
      }, {
        encryption: "≥ v3.1.0"
      }, {
        bucketingV2: "≥ v3.1.0"
      }, {
        semverTargeting: "≥ v3.1.0"
      }, {
        looseUnmarshalling: "≥ v0.0.0"
      }, {
        namespacesV2: "≥ v0.0.0"
      }]
    },
    roku: {
      name: "Roku SDK",
      version: "1.4.1",
      github: "https://github.com/growthbook/growthbook-roku",
      examples: [{
        url: "https://github.com/growthbook/growthbook-roku/tree/main/examples",
        name: "Roku examples"
      }, {
        url: "https://www.npmjs.com/package/growthbook-roku",
        name: "npm package"
      }],
      packageRepos: [],
      capabilities: [{
        features: "All versions"
      }, {
        experimentation: "All versions"
      }, {
        encryption: "≥ v1.4.1"
      }, {
        stickyBucketing: "≥ v1.4.1"
      }, {
        prerequisites: "≥ v1.3.0"
      }, {
        looseUnmarshalling: "≥ v1.3.0"
      }, {
        namespacesV2: "≥ v1.3.0"
      }, {
        semverTargeting: "≥ v1.3.0"
      }, {
        bucketingV2: "≥ v1.3.0"
      }]
    }
  };
  const SLACK_URL = "https://join.slack.com/t/growthbookusers/shared_invite/zt-2xw8fu279-Y~hwnfCEf7WrEI9qScHURQ";
  const Row = ({href, icon, children}) => {
    const rowClass = "mint-flex mint-items-center mint-gap-2 mint-p-3 mint-border-b mint-border-[#00002f26] dark:mint-border-[#d6ebfd30]";
    const iconSpan = <span className="inline-flex items-center justify-center w-[1.2em] h-[1.2em] shrink-0 [&_svg]:w-full [&_svg]:h-full">
        {icon}
      </span>;
    if (href) {
      return <a href={href} target="_blank" rel="noreferrer" className={rowClass + " mint-text-inherit mint-no-underline hover:mint-text-inherit hover:mint-underline"}>
          {iconSpan}
          {children}
        </a>;
    }
    return <div className={rowClass}>
        {iconSpan}
        {children}
      </div>;
  };
  const {name, version, github, examples, packageRepos} = sdkInfo[sdk];
  const formattedVersion = version.replace(/^v?/, "v");
  const githubName = github.split("/").pop();
  return <section className="grid mb-4">
      <header className="col-span-full flex justify-between items-center gap-4 p-3 border-b border-[#00002f26] dark:border-[#d6ebfd30]">
        <div className="font-semibold flex items-center gap-2 dark:text-[#f5f7f5]">
          <span className="inline-flex items-center justify-center w-[1.2em] h-[1.2em] shrink-0 [&_svg]:w-full [&_svg]:h-full">
            <CodeLogos name={sdk} />
          </span>
          <span>{name} Resources</span>
        </div>
        <div className="flex items-center gap-2">
          <span className="inline-flex items-center justify-center w-[1.2em] h-[1.2em] shrink-0 [&_svg]:w-full [&_svg]:h-full">
            <GitBranch />
          </span>
          {formattedVersion}
        </div>
      </header>

      <Row href={github} icon={<GitHubLogo />}>
        {githubName}
      </Row>

      {packageRepos.map(repo => <Row key={repo.name} href={repo.url} icon={<Package />}>
          {repo.name}
        </Row>)}

      {examples.map(({url, name}) => <Row key={name} href={url} icon={<FileCode />}>
          {name}
        </Row>)}

      <Row href={SLACK_URL} icon={<SlackLogo />}>
        Get help on Slack
      </Row>
    </section>;
};

export const ExternalLink = () => {
  return <svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" style={{
    display: "inline-block",
    verticalAlign: "-0.125em",
    marginLeft: "0.15em"
  }}>
      <path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path>
    </svg>;
};

<Badge color="purple">BETA</Badge>

<SdkResources sdk="edgeLambda" />

<Warning>
  **Beta**

  Our Lambda\@Edge implementation is in **beta**. If you experience any issues, let us know either on [Slack](https://slack.growthbook.io/) or [create an issue](https://github.com/growthbook/growthbook-proxy/issues).
</Warning>

## Overview

GrowthBook currently supports two levels of integration with most edge workers, including Lambda\@Edge:

1. Our turnkey Edge App
   * Automatically run server-side or hybrid [Visual Experiments](/app/visual) without redraw flicker.
   * Automatically run server-side or hybrid [URL Redirect Experiments](/app/url-redirects) without flicker or delay.
   * Perform custom feature flagging and experimentation logic.
   * Optionally inject the JavaScript SDK with hydrated payload, allowing the front-end to pick up where the edge left off without any extra network requests. We use an enhanced version of our [HTML Script Tag](/lib/script-tag) for this purpose.

2. Support for edge apps using our JavaScript SDK

## References

* Our Lambda\@Edge SDK repository, which supports the above use cases, is [here <ExternalLink />](https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-lambda)
* You may find it useful to review our [JavaScript SDK](/lib/js). Many of the concepts which apply to both on-edge and injected frontend SDKs are based on our JS SDK.

## Worker Configuration

<Tip>
  **Get up to speed with Lambda\@Edge**

  This tutorial assumes some familiarity with building and deploying AWS Lambda\@Edge applications. You can get up to speed by following the AWS [Tutorial: Create a basic Lambda@Edge function <ExternalLink />](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-how-it-works-tutorial.html) guide.

  Note that our Edge App responds directly to a `viewer-request` without forwarding to an origin; interaction with CloudFront is minimal (Step 2 in the AWS tutorial).
</Tip>

You may either use our turnkey Edge App for Lambda\@Edge or build your own app from scratch using our JavaScript SDK.

## Turnkey Edge App

Our Edge App runs as a smart proxy layer between your application and your end users. In absence of Visual or URL Redirect experiments, the Edge App will simply proxy the user request to your site and return the response, optionally injecting a fully-bootstrapped JavaScript SDK onto the rendered HTML page. If the request URL matches an Visual or URL Redirect experiment and the targeting conditions are satisfied, the Edge App may also perform one or more URL redirects behind the scenes (the public-facing URL does not change) and/or mutate the DOM for Visual Experiments. Additionally, by using [lifecycle hooks](#lifecycle-hooks) you can perform custom logic such as feature flagging as well as proxying and early returns.

<Warning>
  **Body size constraints**

  `viewer-request` responses are currently limited to **40 KB**! Please ensure the DOM returned by both your origin server and by your Lambda function are optimized. You also may need to skip SDK injection when using Lambda\@Edge.
</Warning>

<Note>
  **URL Redirects on edge**

  The Edge App defaults to running URL Redirect Experiments in the browser only. This is because edge redirects load a separate page's content without altering the URL. After the redirect, some sites may experience problems with loading assets or endpoints with relative paths.

  You can enable URL Redirects on edge by setting environment variable `RUN_URL_REDIRECT_EXPERIMENTS` to "edge" or "everywhere".

  Additionally if your redirect is cross-domain (e.g. redirection from "public.mysite.io" to "newsite.io"), you must also set `RUN_CROSS_ORIGIN_URL_REDIRECT_EXPERIMENTS`.

  See [environment variables](#environment-variables) for more information.
</Note>

We will assume that you have a basic Lambda\@Edge application set up, and that it is configured to respond to viewer requests. Note that our Edge App will not attempt to reach your CF cache nor origin and instead will fetch/proxy to your web server during the *viewer request / response* lifecycle. Therefore a minimal CloudFront setup is advised.

Once your application is set up, simply install the SDK and implement our custom request handler.

### Install the SDK

<CodeGroup>
  ```bash npm theme={null}
  npm install --save @growthbook/edge-lambda
  ```

  ```bash Yarn theme={null}
  yarn add --save @growthbook/edge-lambda
  ```

  ```bash pnpm theme={null}
  pnpm add --save @growthbook/edge-lambda
  ```

  ```bash bun theme={null}
  bun add @growthbook/edge-lambda
  ```
</CodeGroup>

### Implement the Edge App request handler

A basic implementation of our Edge App only requires a few lines of code:

```ts theme={null}
import { handleRequest } from "@growthbook/edge-lambda";

export async function handler(event, ctx, callback) {
  // Manually build your environment:
  const env = buildEnv();

  // Specify additional edge endpoint information:
  env.host = "www.mysite.io";

  // Uncomment for ease of testing locally - returns response instead of using callback():
  // env.returnResponse = true;

  handleRequest(event, callback, env);
}

function buildEnv() {
  // todo: define environment variables here
}
```

### Configure the Edge App

Use a combination of environment variables and optional runtime configuration to add required fields and to customize the Edge App behavior.

#### Environment variables

Unfortunately Lambda\@Edge does not have native support for environment variables. You will need to implement your own mechanism to build an `Env` environment (a TypeScript interface is exported in `"@growthbook/edge-lambda"`). You will need to inject your environment variables into the handler either directly into your codebase or at compile time. Our `buildEnv()` method is a placeholder for your preferred mechanism.

<Tip>
  **Tip (for a subset of use cases)**

  We do offer a utility function called `mapHeadersToConfigEnv(req, originType="custom", prefix="x-env-")` (exported from `"@growthbook/edge-lambda"`) that can build a valid `Env` environment from custom CF origin headers. However this is only useful if your app is set up to reach your origin server through CF (this is not the default behavior of our Edge App).
</Tip>

Add these required fields, at minimum, to your environment variables:

```typescript theme={null}
function buildEnv() {
  return {
    // required fields:
    PROXY_TARGET: "https://internal.mysite.io",  // The non-edge URL to your website
    GROWTHBOOK_API_HOST: "https://cdn.growthbook.io",
    GROWTHBOOK_CLIENT_KEY: "sdk-abc123",
    GROWTHBOOK_DECRYPTION_KEY: "key_abc123",  // Only include for encrypted SDK Connections
  };
}
```

You may want to further customize the app. Here is a list of common customization variables:

```bash theme={null}
# Disable or change the rendering behavior of Visual Experiments:
# ==========
RUN_VISUAL_EDITOR_EXPERIMENTS="everywhere"|"edge"|"browser"|"skip"  # default: "everywhere"

# URL Redirect Experiments are disabled on edge by default. Because the URL does not change, some sites
# may experience problems with loading assets or endpoints with relative paths:
# ==========
RUN_URL_REDIRECT_EXPERIMENTS="everywhere"|"edge"|"browser"|"skip"  # default: "browser"
RUN_CROSS_ORIGIN_URL_REDIRECT_EXPERIMENTS="everywhere"|"edge"|"browser"|"skip"  # default: "browser"
# Mutate browser URL via window.history.replaceState() to reflect the new URL:
INJECT_REDIRECT_URL_SCRIPT="true"  # default "true".

# Do not inject a bootstrapped JavaScript SDK onto the page:
# ==========
DISABLE_INJECTIONS="true"  # default "false"


# Customize the edge or injected browser SDK behavior:
# ==========
ENABLE_STREAMING="true"  # default "false". Streaming SSE updates on browser.
ENABLE_STICKY_BUCKETING="true"  # default "false". Use cookie-based sticky bucketing on edge and browser.
```

#### Runtime configuration

You may want to provide context to your edge app at runtime rather than using environment variables. For example, if you have additional [targeting attributes](/lib/js#attributes) available, you may inject them by modifying your request handler code:

```ts theme={null}
import { handleRequest } from "@growthbook/edge-lambda";
import { getCookies } from "./helpers";

export async function handler(event, ctx, callback) {
  const env = buildEnv();
  env.host = "www.mysite.io";

  // example getCookies method
  const cookie = getCookies(event);
  const config = {
    attributes: {
      userType: cookie["userId"] ? "logged in" : "anonymous"
    }
  };

  handleRequest(event, callback, env, config);
}
```

#### More customization options

For a full list of customizations, view our vendor-agnostic [Edge Utility repository <ExternalLink />](https://github.com/growthbook/growthbook-proxy/tree/main/packages/lib/edge-utils).

### Tracking Experiment Views

Running A/B tests requires a [tracking callback](/lib/js#experimentation-ab-testing). Our turnkey Edge App defaults to using built-in front-end tracking. The tracking call automatically integrates with Segment.io, GA4, and Google Tag Manager by using the mechanism outlined in our [HTML Script Tag](/lib/script-tag#tracking-experiment-views). In order to do this, the app keeps track of tracking calls triggered on edge and injects them into the front-end SDK to be automatically triggered on page load.

You may wish to either customize front-end tracking or switch to edge tracking (or use both concurrently if running hybrid edge + front-end experiments).

Why might you be interested in tracking on edge? Tracking on an edge or backend environment allows you to ensure the callback is fired before any differentiation across variations, eliminating experimental bias. While not eliminating this risk, the default injected front-end tracking introduced by our Edge App does reduce this risk relative to solely using a front-end SDK.

To change the front-end tracking callback, set the `GROWTHBOOK_TRACKING_CALLBACK` to your custom tracking JS code:

```bash theme={null}
# todo: replace with your own tracking library
GROWTHBOOK_TRACKING_CALLBACK="(experiment, results) => { console.log('browser tracking callback', {experiment, results}); }"
```

To track on edge, you must inject your own tracking callback into the edge request handler code. Any experiments that run on edge will use the edge tracking callback and not the front-end callback (hybrid edge + front-end experiments being an exception):

```ts theme={null}
import { handleRequest } from "@growthbook/edge-lambda";

export async function handler(event, ctx, callback) {
  const env = buildEnv();
  env.host = "www.mysite.io";

  const config = {
    edgeTrackingCallback: (experiment, results) => {
      // todo: replace with your tracking library
      console.log('edge tracking callback', {experiment, results});
    }
  };

  handleRequest(event, callback, env, config);
}
```

### Targeting Attributes

The following targeting attributes are set automatically by the Edge App.

* `id` - a long-lived user identifier, stored in a `gbuuid` cookie (see [Cookie Policy and GDPR](#cookie-policy-and-gdpr) for how the cookie is written and when to use `PERSIST_UUID`)
* `url`
* `path`
* `host`
* `query`
* `pageTitle`
* `deviceType` - either `mobile` or `desktop`
* `browser` - one of `chrome`, `edge`, `firefox`, `safari`, or `unknown`
* `utmSource`
* `utmMedium`
* `utmCampaign`
* `utmTerm`
* `utmContent`

You can customize both the primary identifier name (`id`) and cookie name (`gbuuid`) by setting the `UUID_KEY` and `UUID_COOKIE_NAME` environment variables respectively.

As shown in the [runtime configuration](#runtime-configuration) section above, you can also pass custom attributes via runtime config. You can also skip automatic attribute generation and rely solely on custom attributes by setting the environment variable `SKIP_AUTO_ATTRIBUTES="true"`.

### Routing

By default, the Edge App will process all `GET` requests (other HTTP verbs are proxied through without running through our app logic).

It is generally preferable to configure your routing rules outside of our Edge App when possible. For instance, you may only want to invoke the Edge App at `https://yourdomain.io/landing-page`.

There may be situations when you will need to provide finer-grained routing / URL targeting rules within our Edge App. You will need to include a JSON encoded string of route rules in your `ROUTES` environment variable.

For instance, you may want to do a proxy pass-through (do not process) for `mysite.io/account/*` or `mysite.io/settings/*`. Your routes may look like this:

```bash theme={null}
ROUTES='[{ "pattern":"mysite.io/account/*", "behavior":"proxy" }, { "pattern":"mysite.io/settings/*", "behavior":"proxy" }]'
```

A route uses the following interface, with many of the properties being optional:

```ts theme={null}
{
  pattern: string;
  type?: "regex" | "simple";  // default: "simple"
  behavior?: "intercept" | "proxy" | "error";  // default: "intercept"
  includeFileExtensions?: boolean;  // Include requests to filenames like "*.jpg". default: false (pass-through).
  statusCode?: number; // Alter the status code (default is 404 when using "error")
  body?: string; // Alter the body (for setting an error message body)
}
```

When multiple routes are included in your `ROUTES` array, only the first match is used.

### Cookie Policy and GDPR

The Edge App uses a random unique identifier, stored in a first-party cookie named `gbuuid`, to provide a consistent user experience to your visitors by preventing them from being re-bucketed into different A/B test variations. It follows the same mechanism as discussed in our [HTML Script Tag docs](/lib/script-tag#cookie-policy-and-gdpr).

#### Persisting the `gbuuid` Cookie from the Edge

By default, the Edge App generates a `gbuuid` for each visitor and exposes it as the `id` targeting attribute, but it does **not** write the cookie from the edge server itself. Instead, the cookie is persisted in the browser by the injected front-end SDK once the page loads.

This works for most setups. However, the `gbuuid` cookie will **not** be written if any of the following are true:

* You have disabled SDK injection (`DISABLE_INJECTIONS="true"`), which is common with Lambda\@Edge due to the 40 KB `viewer-request` body limit.
* You need the `gbuuid` cookie to be available on the very first request — for example, before the browser has a chance to execute the injected SDK.

In these cases, add `PERSIST_UUID: "true"` to the environment returned by your `buildEnv()` function. The Edge App will then include a `Set-Cookie: gbuuid=...` header on its response, ensuring the cookie is stored on the first request.

```typescript theme={null}
function buildEnv() {
  return {
    PROXY_TARGET: "https://internal.mysite.io",
    GROWTHBOOK_API_HOST: "https://cdn.growthbook.io",
    GROWTHBOOK_CLIENT_KEY: "sdk-abc123",
    PERSIST_UUID: "true",
  };
}
```

If you are using `NO_AUTO_COOKIES` to wait for consent (see the [next section](#delay-storing-the-cookie-until-consent-is-granted)), no cookies — including `gbuuid` — will be written until the `growthbookpersist` event is dispatched, regardless of `PERSIST_UUID`.

#### Delay Storing the Cookie Until Consent is Granted

If you must delay persisting the `gbuuid` cookie until a user consents, you can set the environment variable `NO_AUTO_COOKIES="true"`.

This will still generate a UUID for the user, but will not persist it. That means, if the user refreshes the page, they will have a new random UUID generated.environment

You have the option to manually persist this cookie at any time, for example when a user grants consent on your cookie banner. All you need to do is fire this custom event from javascript on the rendered page:

```js theme={null}
document.dispatchEvent(new CustomEvent("growthbookpersist"));
```

<Note>
  **Sticky Bucketing and consent**

  If you are using Sticky Bucketing, a persistent sticky bucket assignments cookie will automatically be generated. If you require user permission before writing cookies, you should:

  * Either do not enable Sticky Bucketing on edge (do not use `ENABLE_STICKY_BUCKETING`)
  * Or only enable Sticky Bucketing per each user via runtime configuration. (only pass `config.enableStickyBucketing: true` if user has consented — identifiable by checking for presence of the `gbuuid` cookie).
</Note>

### Lifecycle hooks

You can perform custom logic and optionally return a response at various stages in the Edge App's lifecycle. This allows for expressiveness of custom routing, user attribute mutation, header and body (DOM) mutation, and custom feature flag and experiment implementations – while preserving the ability to automatically run Visual and URL Redirect experiments and SDK hydration.

With each hook, you may mutate any of the provided attributes *or* return an early response to halt the Edge App processing. The following hooks are available:

* `onRequest` - Fired on initial user request. Can exit early based on requested URL.
* `onRoute` - Fired after standard routing has been processed. Can exit early (proxy) based on manual routing logic.
* `onUserAttributes` - Fired after auto-attributes have been assigned to the user. Either enhance the provided `attributes` object or exit early if desired.
* `onGrowthBookInit` - Fired after the Edge App's internal GrowthBook SDK has been initialized. Call SDK functions or exit early if desired.
* `onBeforeOriginFetch` - Similar hook to the above; triggers after any URL Redirect experiments have run but before any origin requests have been made.
* `onOriginFetch` - Fired immediately after the origin fetch has been made, but before the full response body has been captured. Useful for exiting early based on response status or headers.
* `onBodyReadyParams` - Fired once the entire response body has been parsed. In addition to early exiting, you may begin to mutate the final response body via `resHeaders` and the `setBody()` method. The text `body` as well as the optional parsed virtual DOM `root` (disabled by default, use `ALWAYS_PARSE_DOM` to enable) are exposed. NOTE: If mutating the `root` DOM, it is your responsibility to `setBody()` with the latest changes before the response is returned.
* `onBeforeResponse` - The final hook fired before the response is returned to the user, triggering after both visual editor changes and client SDK hydration have been injected. While the virtual DOM is no longer available, this hook can be used to apply any final changes the body via `setBody()`.

To use one or more lifecycle hooks, pass any hooks to your `handleRequest` method:

```ts theme={null}
  const hooks = {
    onRoute: (params) => {
      if (params.requestUrl === "https://mysite.io/skip") {
        return params.context.helpers.proxyRequest(context, params.req, params.res);
      }
    },
    onBeforeResponse: (params) => {
      params.setBody(params.body + `<script>console.log("custom logic")</script>`);
    }
  };

  handleRequest(event, callback, env, undefined, hooks);
```

## Manual SDK Integration on Edge

You may be interested in building your own edge application using the GrowthBook SDK and not using our turnkey Edge App. Or you may want to do custom feature flagging on specific routes while running our Edge App on other routes.

To use the GrowthBook on edge, simply include our standard [JavaScript SDK](/lib/js) (`@growthbook/growthbook` NPM package).

```ts theme={null}
import { GrowthBook, setPolyfills } from "@growthbook/growthbook";

export async function handler(event, ctx, callback) {
  // 1. Init the GrowthBook SDK and choose an optional caching strategy

  // A. Use the KV as a managed payload store to eliminate SDK requests to the GrowthBook API entirely.
  // Requires setting up an SDK Webhook.
  const payload = await getPayloadFromProvider(); // not implemented, build your own
  const growthbook = new GrowthBook(gbContext);
  await growthbook.init({ payload: payload });

  // B. Or provide a KV cache layer so that the GrowthBook SDK doesn't need to make as many requests
  // to the GrowthBook API. No SDK Webhook needed.
  const localStoragePolyfill = getLocalStoragePolyfill(env); // not implemented, build your own
  setPolyfills({ localStorage: localStoragePolyfill });
  await growthbook.init();

  // 2. Start feature flagging
  if (growthbook.isOn("my-feature")) {
    const resp = { status: "200", body: "<h1>foo</h1>" };
    callback(null, resp);
  } else {
    const resp = { status: "200", body: "<h1>bar</h1>" };
    callback(null, resp);
  }
}
```

## Payload Caching via edge datastore

By default, the Edge App will make a network request to the GrowthBook API on each user request in order to fetch the current feature and experiment values. This is a blocking call that delays page delivery. There is an in-memory short-lived cache layer on this call, but it won't always protect you.

If you have access to a distributed key-value store such as DynamoDB, you can likely overcome this problem. There are 2 levels of key-value integration available:

1. You can either completely eliminate the blocking call to the GrowthBook API by implementing a GrowthBook-to-edge-keyval push model via **SDK Webhooks**.
2. Alternatively, you can eliminate most of these network requests by using an edge key-val store as a just-in-time payload cache.

You can also use these strategies in your own manual SDK integration.

We are unable to offer specific guidance about how to configure or connect to your key-val store because there are many possible network configurations and data stores within an AWS edge application.

### Configuring a SDK Webhook

For key-val stored payloads (1), we eliminate network requests from edge to GrowthBook by using a GrowthBook SDK Webhook to push the SDK payload to the key-val store on change.

1. Create an [SDK Webhook](/app/webhooks/sdk-webhooks) on the same SDK Connection that you are using for edge integration.
2. Select **HTTP Endpoint** as the Webhook Type.
3. Set the **Endpoint URL** to your key-val store's REST API endpoint, if available. You may need to build your own private Lambda endpoint to handle the webhook, in which case webhook verification may be important.
4. Change the **Method** to `PUT` (or whichever verb is required by your endpoint).
5. Set the **Payload format** to "SDK Payload only".

Now whenever feature and experiment values change, your edge worker will have immediate access to the latest values. You can also test the webhook by using the "Test Webhook" button on the SDK Connection page.

## Supported Features

<SdkSupportedFeatures sdk="edgeLambda" />
