SpeakTrue Repository Engineering Deep-Dive Reference
Last updated: 2026-06-29
Purpose and usage
This is a single-entry deep index for first-time engineers and cross-surface contributors. It is meant to answer:
- what every file in the active iOS, Android, web, and backend function layers does,
- which files are touched when behavior changes,
- and the minimum verification set for a safe change.
Scope
- iOS Swift app: runtime, tests, UI, services, and project metadata.
- Android Kotlin app: shell, feature modules, tests, resources, and build scripts.
- Backend: Supabase edge functions (TypeScript), shared function modules, and migration-adjacent touchpoints.
- Web: legacy Python runtime + marketing static site + runtime assets used for compatibility, auth, signup, and compatibility paths.
One-time orientation checklist
- Read
README.md, then docs/index.md for canonical entry points.
- Read contracts:
docs/contracts/native-speech-parity-anchor.md and docs/contracts/speech-workflow-contract.md.
- Treat
backend/supabase/functions/_shared/* as policy and auth contract boundaries.
- Before behavior changes, align code changes with migration files in
backend/supabase/migrations and parity/contract docs.
- For release work, use the docs in
docs/ops/* and related scripts.
Repository governance and verification map
Run this sequence before major changes:
- Identify changed files and their upstream/downstream surfaces.
- Inspect contracts and migration implications.
- Update source files + tests + migration/docs in the same pass.
- Validate with:
- feature-level tests on the touched surface,
- backend function tests,
- regression scripts in
scripts/,
- and
git diff --check.
Deployment and runbook anchors
- iOS:
ios/SpeakTrue.xcodeproj, ios/Config, ios/SpeakTrue/*.swift, ios/SpeakTrue.entitlements.
- Android:
android/ Gradle/build tree, plus docs/ops/ANDROID_PLAY_RELEASE_CHECKLIST.md and docs/ops/ANDROID_PLAY_RELEASE_EVIDENCE_TEMPLATE.md.
- Backend:
backend/supabase/functions, backend/supabase/migrations, and scripts under scripts/.
- Marketing:
docs/ops/CLOUDFLARE_PAGES_DEPLOY.md, web/marketing/*.
- Legacy web:
web/python-web-app/src, web/python-web-app/wsgi.py, web/python-web-app/Procfile.
Change playbooks
Speech and voice generation changes
- iOS:
ios/SpeakTrue/AIProxyService.swift, speech view models and payload builders.
- Android:
android/app/src/main/java/com/speaktrue/features/tts, features/stt, features/sts packages.
- Backend:
backend/supabase/functions/tts-generate, stt-transcribe, shared _shared/quotas.ts, _shared/entitlements.ts, _shared/usage.ts.
- Re-run: function handler tests + surface feature tests + any migration sanity checks.
Soundboard changes
- iOS:
ios/SpeakTrue/Soundboard*.swift, SoundboardCache*, StorageManager, and storage sync services.
- Android:
android/app/src/main/java/com/speaktrue/features/soundboard and storage settings surfaces.
- Backend:
soundboard-save-generated, soundboard-delete, clip-order-batch, plus any storage bucket/RPC migrations.
- Re-run: soundboard contract tests, parity tests, and migration scripts.
Auth/consent/onboarding changes
- iOS:
ios/SpeakTrue/AuthService.swift, AuthGateView.swift, SignInView.swift, AI-sharing consent files.
- Android:
features/auth, features/agreement.
- Backend: auth/policy helpers in
backend/supabase/functions/_shared/auth-context.ts, _shared/cors.ts.
- Re-run: auth and navigation tests for touched surfaces.
Exhaustive file-level behavior index
This section captures each file with important declarations/signatures and serves as a first-pass behavior map.
- For non-code assets and binaries, files are still listed where relevant but usually without declaration lines.
- The index is intentionally broad and should be paired with the detailed docs already in
docs/reference/*.
- For concise ownership summaries of each file path, cross-check
ios-file-inventory.md, android-file-inventory.md, and web-file-inventory.md.
iOS + Android (swift, kotlin, tests, configs)
Declaration index for first-pass navigation; couple this with existing iOS/Android inventories and per-feature contract docs for deeper behavior interpretation.
iOS (Swift)
ios/SpeakTrueUITests/SpeakTrueUITests.swift
- File type: Swift
- Ownership: source-code
- 8:import XCTest
- 10:final class SpeakTrueUITests: XCTestCase {
- 12: override func setUpWithError() throws {
- 21: override func tearDownWithError() throws {
- 26: func testExample() throws {
- 28: let app = XCUIApplication()
ios/SpeakTrueUITests/SpeakTrueUITestsLaunchTests.swift
- File type: Swift
- Ownership: source-code
- 8:import XCTest
- 10:final class SpeakTrueUITestsLaunchTests: XCTestCase {
- 12: override class var runsForEachTargetApplicationUIConfiguration: Bool {
- 16: override func setUpWithError() throws {
- 21: func testLaunch() throws {
- 22: let app = XCUIApplication()
ios/SpeakTrueTests/ColorExtensionTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 2:import SwiftUI
- 5:final class ColorExtensionTests: XCTestCase {
- 6: func testFromHexSixDigitRGB() {
- 7: let color = Color.fromHex(“#ff0000”)
- 8: let components = rgbaComponents(for: color)
ios/SpeakTrueTests/STTAndSTSViewModelTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 2:import AVFoundation
- 6:final class STTAndSTSViewModelTests: XCTestCase {
- 11: func testSTTViewModelDefaultsAndFormatting() {
- 12: let viewModel = makeSTTViewModel()
- 28: func testSTTTranscribeRecordingFailsGracefullyWhenSettingsMissing() {
ios/SpeakTrueTests/AIProxyModelCodingTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class AIProxyModelCodingTests: XCTestCase {
- 6: func testAIProxyErrorDescriptionsAreUserReadable() {
- 20: func testBYOKStatusResponseDecoding() throws {
- 21: let json = “””
- 29: let response = try JSONDecoder().decode(AIProxyService.BYOKStatusResponse.self, from: json)
ios/SpeakTrueTests/TTSPlaybackModeBehaviorTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class TTSPlaybackModeBehaviorTests: XCTestCase {
- 8: func testShouldUseStreamingTransportForStreamingAndBufferedModes() {
- 14: func testMakeGeneratePayloadMapsPlaybackModeToResponseMode() {
- 15: let settings = makeSettings(mode: .buffered)
- 17: let payload = TTSViewModel.makeGeneratePayload(textToSend: “Hello world”, userSettings: settings)
ios/SpeakTrueTests/AsyncTimeoutTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 4:final class AsyncTimeoutTests: XCTestCase {
- 9: func testWithTimeoutReturnsValueBeforeDeadline() async throws {
- 10: let value = try await AsyncTimeout.withTimeout(nanoseconds: 500_000_000, operationName: “fast-op”) {
- 18: func testWithTimeoutPropagatesOperationError() async {
- 31: func testWithTimeoutThrowsOperationTimeoutError() async {
ios/SpeakTrueTests/SpeakTrueTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 4:final class SpeakTrueTests: XCTestCase {
- 5: func testSmokeAuthStateSignedOutDefaults() {
ios/SpeakTrueTests/SettingsDiffTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class SettingsDiffTests: XCTestCase {
- 8: func testTTSPlaybackModeDisplayNames() {
- 14: func testTTSPlaybackModeDetails() {
- 20: func testTTSPlaybackModeMapsToAPIResponseMode() {
- 26: func testSTSWorkflowModeDisplayNamesAndDefaults() {
ios/SpeakTrueTests/MainTabNavigationTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 4:final class MainTabNavigationTests: XCTestCase {
- 5: func testNativeBottomNavigationIncludesVoiceCloning() {
- 22: func testNavigateToTTSNotificationNameIsStable() {
- 26: func testFirstRunTourCoversRequestedTabsAndFeatures() {
- 27: let steps = AppTourContracts.steps
ios/SpeakTrueTests/AuthAndSessionTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class AuthAndSessionTests: XCTestCase {
- 6: func testAuthStateSignedInFlagBehavior() {
- 11: func testAuthStateEmailDisplayFallsBackWhenMissing() {
- 12: let state = AuthState.signedIn(userId: “user-1”, email: nil)
- 16: func testAuthStateUserIdDisplaySignedOut() {
ios/SpeakTrueTests/AppContractsTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 10:final class AppContractsTests: XCTestCase {
- 14: func testVoiceClonePreflightPayloadEncodingForSupabaseEndpoint() throws {
- 15: let payload = AIProxyService.VoiceClonePreflightPayload(
- 27: let data = try JSONEncoder().encode(payload)
- 28: let object = try JSONSerialization.jsonObject(with: data) as? [String: Any]
ios/SpeakTrueTests/VoiceCloneViewModelValidationTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class VoiceCloneViewModelValidationTests: XCTestCase {
- 8: func testValidationErrorsRequireVoiceNameConsentAndSample() {
- 9: let viewModel = makeViewModel()
- 16: func testValidationErrorsFlagSampleDurationBoundaries() {
- 17: let viewModel = makeViewModel()
ios/SpeakTrueTests/SettingsContractsTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class SettingsContractsTests: XCTestCase {
- 8: func testPronunciationShortcutSubtitleForEntryCounts() {
- 14: func testNormalizedSelectedStylePresetIDKeepsValidCurrentSelection() {
- 15: let presets = [
- 20: let selected = SettingsContracts.normalizedSelectedStylePresetID(currentID: “p1”, presets: presets)
ios/SpeakTrueTests/CloudStorageModelCodingTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class CloudStorageModelCodingTests: XCTestCase {
- 6: func testClipGenerationMetadataEncodingUsesSharedSnakeCaseContract() throws {
- 7: let metadata = ClipGenerationMetadata(
- 23: let data = try JSONEncoder().encode(metadata)
- 24: let object = try XCTUnwrap(
ios/SpeakTrueTests/ConfigurationAndThemeTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 5:final class ConfigurationAndThemeTests: XCTestCase {
- 6: func testThemeCatalogContainsExpectedDefaultTheme() {
- 10: func testThemeCatalogIDsAreUnique() {
- 11: let ids = Theme.allThemes.map(\ .id)
- 12: let uniqueIDs = Set(ids)
ios/SpeakTrueTests/SoundboardCacheManagerTests.swift
- File type: Swift
- Ownership: source-code
- 1:import XCTest
- 4:final class SoundboardCacheManagerTests: XCTestCase {
- 5: func testCacheEntryDecodesLegacyIndexWithoutPreserveFlag() throws {
- 6: let json = “””
- 15: let decoder = JSONDecoder()
- 17: let entry = try decoder.decode(SoundboardCacheEntry.self, from: Data(json.utf8))
ios/SpeakTrue/TTSCatSelectView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct CategorySelectionView: View {
- 5: let onCategorySelected: (String) -> Void
- 6: let categories: [CategoryInfo] // Change from @ObservedObject var categoryService
- 8: var body: some View {
- 39: private func categoryRow(for categoryInfo: CategoryInfo) -> some View {
ios/SpeakTrue/SoundboardCacheIndex.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 4: var entries: [String: SoundboardCacheEntry] = [:]
- 8: var category: String
- 9: var filePath: String
- 10: var sizeBytes: Int64
- 11: var lastAccessedAt: Date
ios/SpeakTrue/ShareSheet.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 3:import SwiftUI
- 4:import UIKit
- 6:struct ShareSheet: UIViewControllerRepresentable {
- 8: let url: URL
ios/SpeakTrue/SupabaseConfig.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 5: static let projectURL = “SUPABASE_PROJECT_URL”
- 6: static let publishableKey = “SUPABASE_PUBLISHABLE_KEY”
- 7: static let redirectURL = “SUPABASE_REDIRECT_URL”
- 8: static let googleReversedClientID = “GOOGLE_REVERSED_CLIENT_ID”
- 9: static let googleWebClientID = “GOOGLE_WEB_CLIENT_ID”
ios/SpeakTrue/SoundboardView.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 3:import UIKit
- 4:import AVFoundation
- 6:import UniformTypeIdentifiers
- 9:extension CloudCategory: Identifiable {
ios/SpeakTrue/ContentView.swift
- File type: Swift
- Ownership: source-code
- 8:import SwiftUI
- 10:struct ContentView: View {
- 11: var body: some View {
ios/SpeakTrue/BreakManager.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 4:class BreakManager {
- 12: func applyBreaks(to text: String, sentenceDuration: Double, punctuationDuration: Double) -> String {
- 13: var processedText = text
- 15: let sentenceBreak = String(format: “%.1fs”, sentenceDuration)
ios/SpeakTrue/VoiceCloneViewModel.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import AVFoundation
- 3:import CoreMedia
- 4:import Combine
- 7:final class VoiceCloneViewModel: NSObject, ObservableObject {
- 8: struct VoiceCloneScript: Identifiable, Hashable {
ios/SpeakTrue/AudioControlsView.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 3:import Combine
- 5:struct AudioControlsView: View {
- 8: var body: some View {
- 9: let hasAudio = viewModel.audioData != nil
ios/SpeakTrue/STSViewModel.swift
- File type: Swift
- Ownership: source-code
- 2:import Foundation
- 3:import Combine
- 6:class STSViewModel: ObservableObject {
- 31: private var recordingURL: URL?
- 32: private let recorderService = AudioRecorderService(filePrefix: “sts-recording”)
- 33: private let playerService = AudioPlayerService()
ios/SpeakTrue/SupabaseClientProvider.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 4:import Supabase
- 9: static let shared: SupabaseClient? = {
- 16: let host = url.host, !host.isEmpty else {
- 21: let publishableKey = SupabaseConfig.publishableKey
- 27: let options = SupabaseClientOptions(
ios/SpeakTrue/STTViewModel.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 5:class STTViewModel: ObservableObject {
- 19: private var recordingURL: URL?
- 20: private let recorderService = AudioRecorderService(filePrefix: “stt-recording”)
- 21: private let realtimeSTTService = RealtimeSTTService()
ios/SpeakTrue/ElevenLabsService.swift
- File type: Swift
- Ownership: source-code
- 7:import Foundation
- 10:struct Voice: Identifiable, Codable {
- 20: var id: String
- 21: var name: String
- 24: var category: String?
- 25: var description: String?
ios/SpeakTrue/AppTheme.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 4:struct Theme: Identifiable, Equatable {
- 5: let id: String
- 6: let name: String
- 7: let primary: Color
- 8: let secondary: Color
ios/SpeakTrue/SoundboardViewModel.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 3:import SwiftUI
- 6:class SoundboardViewModel: ObservableObject {
- 13: private let cloudService = CloudStorageService()
- 15: var rootCategories: [CloudCategory] {
ios/SpeakTrue/AsyncTimeout.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 3:struct OperationTimeoutError: LocalizedError {
- 4: let operationName: String
- 5: let timeoutLabel: String
- 7: var errorDescription: String? {
- 13: private actor State {
ios/SpeakTrue/LiveVoiceSTSService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 3:struct LiveVoiceSTSStats {
- 4: let liveSegmentCount: Int
- 5: let liveTtsCharacterCount: Int
- 6: let liveTTSFailed: Bool
- 10:final class LiveVoiceSTSService {
ios/SpeakTrue/SoundboardAudioClips.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 3:import Foundation
- 4:import SwiftUI
- 5:import Combine
- 21:class AudioClip: ObservableObject {
- 27: let clipId: String?
- File type: Swift
- Ownership: source-code
- 2:import Foundation
- 3:import SwiftUI
- 5:struct HeaderViewSTT: View {
- 6: var body: some View {
ios/SpeakTrue/UserSettings.swift
- File type: Swift
- Ownership: source-code
- 8:import Foundation
- 9:import SwiftUI
- 10:import Combine
- 13:class UserSettings: ObservableObject {
- 26: var apiResponseMode: String {
- 37: var displayName: String {
ios/SpeakTrue/SettingsTabView.swift
- File type: Swift
- Ownership: source-code
- 8:import SwiftUI
- 9:import Combine
- 11:import UIKit
- 23: var id: String { rawValue }
- 25: var title: String {
- 50: var id: String { rawValue }
ios/SpeakTrue/AIProxyService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 4:import Supabase
- 13: var errorDescription: String? {
- 47:final class AIProxyService {
- 49: private let client: SupabaseClient?
- 58: struct TTSGeneratePayload: Encodable {
ios/SpeakTrue/AudioRecorderService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import AVFoundation
- 3:import Combine
- 6:final class AudioRecorderService: ObservableObject {
- 12: private var audioRecorder: AVAudioRecorder?
- 13: private var durationTimer: Timer?
ios/SpeakTrue/SignInView.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 5:import CryptoKit
- 9:import AuthenticationServices
- 13:import Security
- 21:struct SignInView: View {
ios/SpeakTrue/AIDataSharingConsentGateView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct AIDataSharingConsentGateView: View {
- 4: let userId: String
- 11: var body: some View {
- 57: private func selectTourTab(_ tab: AppTourTab?) {
- 64: private var disabledOverlay: some View {
ios/SpeakTrue/AuthService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 5:import AuthenticationServices
- 9:import UIKit
- 13:import Supabase
- 17:final class AuthService: ObservableObject {
ios/SpeakTrue/ColorExtension.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 4:extension Color {
- 5: static func fromHex(_ hex: String) -> Color {
- 6: let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
- 7: var int: UInt64 = 0
- 9: let a, r, g, b: UInt64
ios/SpeakTrue/StartupLoadingView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct StartupLoadingView: View {
- 4: let progress: Double
- 5: let statusText: String
- 9: var body: some View {
ios/SpeakTrue/AIDataSharingAgreementService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 5:import Supabase
- 9:final class AIDataSharingAgreementService: ObservableObject {
- 10: static let currentAgreementVersion = AIDataSharingConsent.currentAgreementVersion
- 19: private let client: SupabaseClient?
ios/SpeakTrue/SpeechToTextView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 2:import AVFoundation
- 3:import UIKit
- 5:struct SpeechToTextView: View {
- 15: var body: some View {
- 53: var recordingSection: some View {
ios/SpeakTrue/AuthState.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 7: var isSignedIn: Bool {
- 14: var emailDisplay: String {
- 23: var userIdDisplay: String {
ios/SpeakTrue/AudioPlayerService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import AVFoundation
- 3:import Combine
- 6:final class AudioPlayerService: NSObject, ObservableObject {
- 11: var onPlaybackFinished: (() -> Void)?
- 13: private var audioPlayer: AVAudioPlayer?
ios/SpeakTrue/DebugLogger.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 18: static func debug(_ message: String) {
- 22: static func info(_ message: String) {
- 26: static func warning(_ message: String) {
- 30: static func error(_ message: String) {
- 34: static func success(_ message: String) {
ios/SpeakTrue/VoiceModelSelectionView.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 3:import AVFoundation
- 5:struct VoiceSelectionView: View {
- 7: let voices: [Voice]
- 9: private var selectedVoiceName: String {
ios/SpeakTrue/UserSettingsSyncService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 5:import Supabase
- 9:final class UserSettingsSyncService: ObservableObject {
- 15: private let client: SupabaseClient?
- 24: func syncOnSignIn(userId: String, userSettings: UserSettings) async {
ios/SpeakTrue/SoundboardCategories.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 3:import Combine
- 4:import AVFoundation
- 8:protocol AudioCategoryType: ObservableObject {
- 9: var name: String { get }
ios/SpeakTrue/SBCategoryDetailView.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 3:import AVFoundation
- 5:import UniformTypeIdentifiers
- 8:import UIKit
- 21:struct CategoryDetailView<T: AudioCategoryType>: View {
ios/SpeakTrue/TextToSpeechView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 2:import AVFoundation
- 4:struct TextToSpeechView: View {
- 15: var body: some View {
- 173: private func handleGenerateSpeech() {
- 177: private func shareGeneratedAudioOnly() {
ios/SpeakTrue/CategoryInfo.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 3:struct CategoryInfo {
- 4: let name: String
- 5: let subdirectoryName: String
ios/SpeakTrue/PronunciationGlossaryView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct PronunciationGlossaryView: View {
- 8: var body: some View {
- File type: Swift
- Ownership: source-code
- 7:import Foundation
- 8:import SwiftUI
- 10:struct HeaderViewTTS: View {
- 11: var body: some View {
ios/SpeakTrue/LiveVoiceAudioPlayer.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 5:final class LiveVoiceAudioPlayer {
- 11: private let audioEngine = AVAudioEngine()
- 12: private let playerNode = AVAudioPlayerNode()
- 13: private var webSocketTask: URLSessionWebSocketTask?
- 14: private var receiveTask: Task<Void, Never>?
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 4:struct GenerateButtonView: View {
- 5: let action: () -> Void
- 6: let isDisabled: Bool
- 8: var body: some View {
ios/SpeakTrue/RealtimeSTTService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 4:struct RealtimeSTTResult {
- 5: let transcript: String
- 6: let audioBytesSent: Int
- 10:final class RealtimeSTTService {
- 13: private let audioEngine = AVAudioEngine()
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct ResetButtonView: View {
- 4: let resetAction: () -> Void
- 5: let showMessage: Bool
- 7: var body: some View {
ios/SpeakTrue/PronunciationGlossaryViewModel.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 5:final class PronunciationGlossaryViewModel: ObservableObject {
- 18: private let proxyService = AIProxyService()
- 19: private var editingEntryID: String?
- 21: let entryLimit = 500
ios/SpeakTrue/AppTour.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 2:import Combine
- 11: var title: String {
- 27:struct AppTourStep: Equatable {
- 28: let tab: AppTourTab
- 29: let title: String
ios/SpeakTrue/TTSViewModel.swift
- File type: Swift
- Ownership: source-code
- 2:import Foundation
- 3:import Combine
- 6:class TTSViewModel: ObservableObject {
- 18: private let breakManager = BreakManager()
- 19: private let cloudService = CloudStorageService()
- 20: private let proxyService = AIProxyService()
ios/SpeakTrue/SpeechToSpeechView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 2:import AVFoundation
- 4:struct SpeechToSpeechView: View {
- 15: var body: some View {
- 107: var recordingSection: some View {
- 109: let isLiveInterpreterMode = userSettings.stsWorkflowMode == .liveInterpreter
ios/SpeakTrue/SpeakTrueApp.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 2:import Combine
- 3:import AVFoundation
- 6:final class StartupState: ObservableObject {
- 13: var progress: Double {
- 14: let total = 2.0
ios/SpeakTrue/AuthGateView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct AuthGateView: View {
- 7: var body: some View {
ios/SpeakTrue/AIDataSharingConsent.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 4: static let userDefaultsKey = “ai_data_sharing_consent_accepted”
- 5: static let currentAgreementVersion = “2026-05-06-ai-data-sharing-v1”
- 7: static let alertTitle = “Share data with ElevenLabs?”
- 9: static let disclosureText = “””
- 23: static let shortNotice = “This feature sends required text or audio to ElevenLabs for AI speech processing.”
ios/SpeakTrue/TextInputView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct TextInputView: View {
- 7: var body: some View {
ios/SpeakTrue/ElevenLabsSTTService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 3:struct TranscriptionResponse: Codable {
- 4: let text: String
- 7:struct transcribeModel: Identifiable, Codable {
- 14: var id: String
- 15: var name: String
ios/SpeakTrue/SettingsView.swift
- File type: Swift
- Ownership: source-code
- 7:import Foundation
- 8:import Combine
- 9:import SwiftUI
- 11:struct SettingsView: View {
- 17: let selectedModelId: String
- 19: var body: some View {
ios/SpeakTrue/StorageManager.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import Combine
- 5:final class StorageManager: ObservableObject {
- 12: private let cloudService = CloudStorageService()
- 14: func checkAuthenticationStatus() {
- 18: func testConnection() {
ios/SpeakTrue/VoiceCloneTabView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 2:import UniformTypeIdentifiers
- 4:struct VoiceCloneTabView: View {
- 20: var body: some View {
- 99: private var preflightCard: some View {
- 211: private var cloneInputCard: some View {
ios/SpeakTrue/SettingsModels.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 26:struct SettingsSnapshot: Equatable {
- 27: var defaultVoice: String
- 28: var defaultModel: String
- 29: var stability: Double
- 30: var similarity: Double
ios/SpeakTrue/CloudStorageService.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 4:import Supabase
- 7:private let soundboardCategoryLimit = 20
- 9:struct CloudCategoryRecord: Decodable {
- 10: let id: String
- 11: let name: String
ios/SpeakTrue/StorageTestView.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 2:import SwiftUI
- 4:struct StorageTestView: View {
- 7: var body: some View {
ios/SpeakTrue/MainTabView.swift
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:import UIKit
- 13: var id: Int { rawValue }
- 15: var title: String {
- 30: var systemImage: String {
- 46:struct MainTabView: View {
- File type: Swift
- Ownership: source-code
- 1:import SwiftUI
- 3:struct WaveformView: View {
- 4: let audioLevels: [Float]
- 5: let currentLevel: Float
- 7: var body: some View {
- 16: let sensitivityExponent: Float = 3.0
ios/SpeakTrue/SoundboardCacheManager.swift
- File type: Swift
- Ownership: source-code
- 1:import Foundation
- 3:actor SoundboardCacheManager {
- 4: static let shared = SoundboardCacheManager()
- 6: struct CacheStats {
- 7: let totalBytes: Int64
- 8: let categoryBytes: [String: Int64]
Android (Kotlin)
android/app/src/main/java/com/speaktrue/features/stt/presentation/STTViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.stt.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import com.speaktrue.core.audio.AudioPlayerService
- 6:import com.speaktrue.core.audio.PlaybackMode
- 7:import com.speaktrue.core.audio.AudioRecorderService
- 8:import com.speaktrue.core.permissions.PermissionHandler
- 9:import com.speaktrue.core.reliability.BoundedRetryQueue
android/app/src/main/java/com/speaktrue/features/stt/data/SttLanguageOption.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.stt.data
- 3:import com.speaktrue.features.language.data.LanguageOption
android/app/src/main/java/com/speaktrue/features/stt/data/STTRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.stt.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import java.io.File
- 5:import javax.inject.Inject
- 6:import javax.inject.Singleton
- 7:import kotlinx.serialization.Serializable
- 8:import kotlinx.serialization.json.Json
- 11:data class STTRequest(
android/app/src/main/java/com/speaktrue/features/stt/ui/STTScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.stt.ui
- 3:import androidx.compose.foundation.background
- 4:import androidx.compose.foundation.layout.Arrangement
- 5:import androidx.compose.foundation.layout.Box
- 6:import androidx.compose.foundation.layout.Column
- 7:import androidx.compose.foundation.layout.Row
- 8:import androidx.compose.foundation.layout.fillMaxSize
- 9:import androidx.compose.foundation.layout.fillMaxWidth
android/app/src/main/java/com/speaktrue/features/sts/presentation/STSViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import android.content.Context
- 6:import android.net.Uri
- 7:import com.speaktrue.app.BuildConfig
- 8:import com.speaktrue.core.auth.SessionStore
- 9:import com.speaktrue.core.audio.AudioPlayerService
android/app/src/main/java/com/speaktrue/features/sts/data/LiveVoiceSTSRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.data
- 3:import android.media.AudioAttributes
- 4:import android.media.AudioFormat
- 5:import android.media.AudioTrack
- 6:import com.speaktrue.core.audio.PlaybackMode
- 7:import com.speaktrue.core.network.EdgeFunctionCaller
- 8:import java.net.URLEncoder
- 9:import java.util.Base64
android/app/src/main/java/com/speaktrue/features/sts/data/STSOrchestrator.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.data
- 3:import com.speaktrue.core.audio.PlaybackMode
- 4:import com.speaktrue.features.stt.data.STTRepository
- 5:import com.speaktrue.features.stt.data.STTResult
- 6:import com.speaktrue.features.tts.data.TTSRepository
- 7:import com.speaktrue.features.tts.data.TTSResult
- 8:import com.speaktrue.features.tts.data.GeneratedSpeechArtifact
- 9:import java.io.File
android/app/src/main/java/com/speaktrue/features/sts/data/RealtimeSTSAudioStreamer.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.data
- 3:import android.Manifest
- 4:import android.annotation.SuppressLint
- 5:import android.media.AudioFormat
- 6:import android.media.AudioRecord
- 7:import android.media.MediaRecorder
- 8:import androidx.annotation.RequiresPermission
- 9:import dagger.Binds
android/app/src/main/java/com/speaktrue/features/sts/data/RealtimeSTSRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.data
- 3:import com.speaktrue.core.audio.PlaybackMode
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import com.speaktrue.features.tts.data.GeneratedSpeechArtifact
- 6:import javax.inject.Inject
- 7:import javax.inject.Singleton
- 8:import kotlinx.coroutines.CoroutineDispatcher
- 9:import kotlinx.coroutines.withContext
android/app/src/main/java/com/speaktrue/features/sts/ui/STSScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.ui
- 3:import android.content.ClipData
- 4:import android.content.Intent
- 5:import androidx.compose.foundation.background
- 6:import androidx.compose.foundation.layout.Arrangement
- 7:import androidx.compose.foundation.layout.Box
- 8:import androidx.compose.foundation.layout.Column
- 9:import androidx.compose.foundation.layout.Row
android/app/src/main/java/com/speaktrue/features/presets/presentation/StylePresetViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.presets.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import com.speaktrue.features.presets.data.StylePreset
- 6:import com.speaktrue.features.presets.data.StylePresetRepository
- 7:import com.speaktrue.features.presets.data.StylePresetResult
- 8:import dagger.hilt.android.lifecycle.HiltViewModel
- 9:import javax.inject.Inject
android/app/src/main/java/com/speaktrue/features/presets/data/StylePresetRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.presets.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import com.speaktrue.features.settings.data.SettingsRepository
- 5:import javax.inject.Inject
- 6:import javax.inject.Singleton
- 7:import kotlinx.coroutines.flow.MutableStateFlow
- 8:import kotlinx.coroutines.flow.StateFlow
- 9:import kotlinx.coroutines.flow.asStateFlow
android/app/src/main/java/com/speaktrue/features/presets/ui/StylePresetScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.presets.ui
- 3:import androidx.compose.foundation.layout.Arrangement
- 4:import androidx.compose.foundation.layout.Column
- 5:import androidx.compose.foundation.layout.Row
- 6:import androidx.compose.foundation.layout.fillMaxSize
- 7:import androidx.compose.foundation.layout.fillMaxWidth
- 8:import androidx.compose.foundation.layout.padding
- 9:import androidx.compose.foundation.rememberScrollState
android/app/src/main/java/com/speaktrue/app/SpeakTrueApp.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.app
- 3:import android.app.Application
- 4:import android.os.StrictMode
- 5:import android.util.Log
- 6:import dagger.hilt.android.HiltAndroidApp
- 9:class SpeakTrueApp : Application() {
android/app/src/main/java/com/speaktrue/features/tts/presentation/TTSViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import android.content.Context
- 6:import android.net.Uri
- 7:import com.speaktrue.app.BuildConfig
- 8:import com.speaktrue.core.auth.SessionStore
- 9:import com.speaktrue.core.audio.AudioPlayerService
android/app/src/main/java/com/speaktrue/app/MainActivity.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.app
- 3:import android.content.Intent
- 4:import android.os.Bundle
- 5:import androidx.activity.ComponentActivity
- 6:import androidx.activity.compose.setContent
- 7:import androidx.compose.foundation.layout.fillMaxSize
- 8:import androidx.compose.material3.Surface
- 9:import androidx.compose.runtime.LaunchedEffect
android/app/src/main/java/com/speaktrue/ui/theme/Type.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.theme
- 3:import androidx.compose.material3.Typography
- 4:import androidx.compose.ui.text.TextStyle
- 5:import androidx.compose.ui.text.font.FontWeight
- 6:import androidx.compose.ui.unit.sp
- 8:val Typography = Typography(
android/app/src/main/java/com/speaktrue/ui/theme/Theme.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.theme
- 3:import androidx.compose.foundation.isSystemInDarkTheme
- 4:import androidx.compose.material3.ColorScheme
- 5:import androidx.compose.material3.MaterialTheme
- 6:import androidx.compose.material3.darkColorScheme
- 7:import androidx.compose.material3.lightColorScheme
- 8:import androidx.compose.runtime.Composable
- 9:import androidx.compose.ui.graphics.Color
android/app/src/main/java/com/speaktrue/ui/theme/Color.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.theme
- 3:import androidx.compose.ui.graphics.Color
- 5:val PearGreen = Color(0xFF8AA13C)
- 6:val MeadowGreen = Color(0xFF3F7A50)
- 7:val MossDeep = Color(0xFF1F3B2E)
- 8:val SkyMist = Color(0xFFDCEBE2)
- 9:val WarmPaper = Color(0xFFF8F6EE)
- 10:val CoralAccent = Color(0xFFE47E4B)
android/app/src/main/java/com/speaktrue/ui/theme/DesignTokens.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.theme
- 3:import androidx.compose.ui.unit.dp
- 5:object AppSpacing {
- 6: val xSmall = 4.dp
- 7: val small = 8.dp
- 8: val medium = 12.dp
- 9: val large = 16.dp
- 10: val xLarge = 20.dp
android/app/src/main/java/com/speaktrue/ui/theme/Shape.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.theme
- 3:import androidx.compose.foundation.shape.RoundedCornerShape
- 4:import androidx.compose.material3.Shapes
- 6:val SpeakTrueShapes = Shapes(
android/app/src/main/java/com/speaktrue/features/settings/presentation/SettingsViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import android.os.Build
- 6:import com.speaktrue.app.BuildConfig
- 7:import com.speaktrue.core.audio.PlaybackMode
- 8:import com.speaktrue.features.language.data.ElevenLabsTtsLanguages
- 9:import com.speaktrue.features.language.data.LanguageRecommendation
android/app/src/main/java/com/speaktrue/features/shared/AppScaffold.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import androidx.compose.foundation.gestures.awaitEachGesture
- 4:import androidx.compose.foundation.gestures.awaitFirstDown
- 5:import androidx.compose.foundation.layout.Arrangement
- 6:import androidx.compose.foundation.layout.Box
- 7:import androidx.compose.foundation.layout.Column
- 8:import androidx.compose.foundation.layout.Row
- 9:import androidx.compose.foundation.layout.fillMaxSize
android/app/src/main/java/com/speaktrue/features/tts/ui/TTSScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.ui
- 3:import android.content.ClipData
- 4:import android.content.Intent
- 5:import androidx.compose.material3.AlertDialog
- 6:import androidx.compose.foundation.BorderStroke
- 7:import androidx.compose.foundation.layout.Arrangement
- 8:import androidx.compose.foundation.layout.fillMaxSize
- 9:import androidx.compose.foundation.layout.heightIn
android/app/src/main/java/com/speaktrue/features/shared/ScreenHeader.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import androidx.compose.foundation.BorderStroke
- 4:import androidx.compose.foundation.background
- 5:import androidx.compose.foundation.layout.Arrangement
- 6:import androidx.compose.foundation.layout.Box
- 7:import androidx.compose.foundation.layout.Column
- 8:import androidx.compose.foundation.layout.fillMaxWidth
- 9:import androidx.compose.foundation.layout.height
android/app/src/main/java/com/speaktrue/features/shared/GenerationUiComponents.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import androidx.compose.foundation.BorderStroke
- 4:import androidx.compose.foundation.background
- 5:import androidx.compose.foundation.layout.Arrangement
- 6:import androidx.compose.foundation.layout.Box
- 7:import androidx.compose.foundation.layout.Column
- 8:import androidx.compose.foundation.layout.defaultMinSize
- 9:import androidx.compose.foundation.layout.fillMaxHeight
android/app/src/main/java/com/speaktrue/features/shared/GeneratedAudioSharePayload.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import java.io.File
- 5:data class GeneratedAudioSharePayload(
- 6: val file: File,
- 7: val displayName: String,
android/app/src/main/java/com/speaktrue/features/tts/data/VoiceCatalogRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import com.speaktrue.features.voiceclone.data.VoiceCloneRepository
- 5:import com.speaktrue.features.voiceclone.data.VoiceCloneResult
- 6:import javax.inject.Inject
- 7:import javax.inject.Singleton
- 8:import kotlinx.coroutines.flow.MutableStateFlow
- 9:import kotlinx.coroutines.flow.StateFlow
android/app/src/main/java/com/speaktrue/features/tts/data/ModelCatalogRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import com.speaktrue.features.language.data.ElevenLabsSttLanguages
- 5:import com.speaktrue.features.language.data.ElevenLabsTtsLanguages
- 6:import com.speaktrue.features.language.data.LanguageOption
- 7:import javax.inject.Inject
- 8:import javax.inject.Singleton
- 9:import kotlinx.coroutines.flow.MutableStateFlow
android/app/src/main/java/com/speaktrue/features/tts/data/TTSRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.data
- 3:import android.content.Context
- 4:import com.speaktrue.core.audio.PlaybackMode
- 5:import com.speaktrue.core.network.EdgeFunctionCaller
- 6:import com.speaktrue.core.network.RawFunctionResponse
- 7:import com.speaktrue.features.settings.data.SettingsRepository
- 8:import dagger.hilt.android.qualifiers.ApplicationContext
- 9:import java.io.File
android/app/src/main/java/com/speaktrue/features/voiceclone/presentation/VoiceCloneViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import com.speaktrue.core.audio.AudioRecorderService
- 6:import com.speaktrue.core.permissions.PermissionHandler
- 7:import com.speaktrue.features.tts.data.VoiceCatalogRepository
- 8:import com.speaktrue.features.voiceclone.data.ClonePreflight
- 9:import com.speaktrue.features.voiceclone.data.VoiceCloneCreateSample
android/app/src/main/java/com/speaktrue/features/voiceclone/presentation/VoiceCloneState.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.presentation
- 3:import com.speaktrue.features.voiceclone.data.ClonePreflight
- 4:import com.speaktrue.features.voiceclone.data.VoiceClone
- 5:import com.speaktrue.features.voiceclone.data.VoiceCloneCreateSample
- 10: data class Success(
- 11: val cloneId: String,
- 12: val voiceName: String,
- 13: val requiresVerification: Boolean,
android/app/src/main/java/com/speaktrue/ui/navigation/AppNavGraph.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.navigation
- 3:import androidx.compose.foundation.layout.padding
- 4:import androidx.compose.runtime.Composable
- 5:import androidx.compose.runtime.LaunchedEffect
- 6:import androidx.compose.runtime.getValue
- 7:import androidx.compose.runtime.remember
- 8:import androidx.hilt.navigation.compose.hiltViewModel
- 9:import androidx.lifecycle.compose.collectAsStateWithLifecycle
android/app/src/main/java/com/speaktrue/features/voiceclone/ui/VoiceCloneScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.ui
- 3:import android.content.Context
- 4:import android.media.MediaMetadataRetriever
- 5:import android.provider.OpenableColumns
- 6:import androidx.activity.compose.rememberLauncherForActivityResult
- 7:import androidx.activity.result.contract.ActivityResultContracts
- 8:import androidx.compose.foundation.layout.Arrangement
- 9:import androidx.compose.foundation.layout.Column
android/app/src/main/java/com/speaktrue/features/voiceclone/data/VoiceCloneMappers.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.data
- 3:data class VoiceClone(
- 4: val id: String,
- 5: val name: String,
- 6: val isOwned: Boolean,
- 7: val cloneCreatedAt: String? = null,
- 8: val cloneSampleCount: Int? = null,
- 11:data class ClonePreflight(
android/app/src/main/java/com/speaktrue/features/voiceclone/data/VoiceCloneRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import kotlin.jvm.JvmName
- 5:import javax.inject.Inject
- 6:import javax.inject.Singleton
- 7:import kotlinx.serialization.builtins.ListSerializer
- 8:import kotlinx.serialization.json.Json
- 14: data class OwnershipDenied(val message: String) : VoiceCloneFailure
android/app/src/main/java/com/speaktrue/features/voiceclone/data/VoiceCloneDtos.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.data
- 3:import kotlinx.serialization.SerialName
- 4:import kotlinx.serialization.Serializable
- 5:import kotlinx.serialization.Transient
- 8:data class VoiceClonePreflightRequest(
- 9: val samples: List,
- 30:data class VoiceCloneCreateSample(
- 31: val audioBase64: String,
android/app/src/main/java/com/speaktrue/features/voiceclone/ui/VoiceCloneComponents.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.ui
- 3:import androidx.compose.foundation.background
- 4:import androidx.compose.foundation.layout.Arrangement
- 5:import androidx.compose.foundation.layout.Box
- 6:import androidx.compose.foundation.layout.Column
- 7:import androidx.compose.foundation.layout.Row
- 8:import androidx.compose.foundation.layout.fillMaxWidth
- 9:import androidx.compose.foundation.layout.height
android/app/src/main/java/com/speaktrue/core/reliability/ReliabilityErrorMapper.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.reliability
- 3:data class ReliabilityMessage(
- 4: val text: String,
- 5: val isTransient: Boolean,
- 8:object ReliabilityErrorMapper {
- 25: fun map(actionLabel: String, rawMessage: String?): ReliabilityMessage {
- 26: val message = rawMessage?.trim().orEmpty()
- 27: val normalized = message.lowercase()
android/app/src/main/java/com/speaktrue/features/settings/data/SettingsRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.data
- 3:import com.speaktrue.core.audio.PlaybackMode
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import com.speaktrue.features.settings.ui.SettingsResetTarget
- 6:import com.speaktrue.features.settings.ui.SettingsSection
- 7:import javax.inject.Inject
- 8:import javax.inject.Singleton
- 9:import kotlinx.coroutines.Dispatchers
android/app/src/main/java/com/speaktrue/core/reliability/BoundedRetryQueue.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.reliability
- 3:import kotlinx.coroutines.CoroutineScope
- 4:import kotlinx.coroutines.Job
- 5:import kotlinx.coroutines.delay
- 6:import kotlinx.coroutines.launch
- 8:enum class RetryEligibility {
- 13:data class PendingRetry(
- 14: val key: String,
android/app/src/main/java/com/speaktrue/features/settings/data/SettingsStore.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.data
- 3:import android.content.Context
- 4:import androidx.security.crypto.EncryptedSharedPreferences
- 5:import androidx.security.crypto.MasterKey
- 6:import dagger.Binds
- 7:import dagger.Module
- 8:import dagger.hilt.InstallIn
- 9:import dagger.hilt.android.qualifiers.ApplicationContext
android/app/src/main/java/com/speaktrue/features/settings/data/BugReportRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import javax.inject.Inject
- 5:import javax.inject.Singleton
- 6:import kotlinx.serialization.Serializable
- 7:import kotlinx.serialization.json.Json
- 10:data class BugReportSubmitRequest(
- 11: val category: String,
android/app/src/test/java/com/speaktrue/navigation/AuthNavigationTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.navigation
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.ui.navigation.AppDestination
- 5:import com.speaktrue.ui.navigation.isProtectedDestination
- 6:import com.speaktrue.ui.navigation.resolveDesiredRoute
- 7:import com.speaktrue.ui.navigation.shouldShowProtectedShell
- 8:import org.junit.Test
- 10:class AuthNavigationTest {
android/app/src/main/java/com/speaktrue/features/dictionary/presentation/PronunciationDictionaryViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.dictionary.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import com.speaktrue.features.dictionary.data.PronunciationEntry
- 6:import com.speaktrue.features.dictionary.data.PronunciationRepository
- 7:import com.speaktrue.features.dictionary.data.PronunciationResult
- 8:import com.speaktrue.features.settings.data.SettingsRepository
- 9:import dagger.hilt.android.lifecycle.HiltViewModel
android/app/src/main/java/com/speaktrue/features/dictionary/ui/PronunciationDictionaryScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.dictionary.ui
- 3:import androidx.compose.foundation.layout.Arrangement
- 4:import androidx.compose.foundation.layout.Column
- 5:import androidx.compose.foundation.layout.Row
- 6:import androidx.compose.foundation.layout.fillMaxSize
- 7:import androidx.compose.foundation.layout.fillMaxWidth
- 8:import androidx.compose.foundation.layout.padding
- 9:import androidx.compose.foundation.rememberScrollState
android/app/src/main/java/com/speaktrue/features/language/data/ElevenLabsLanguageOptions.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.language.data
- 3:object ElevenLabsSttLanguages {
- 6: fun fallback(): List = fallbackLanguages
- 8: fun labelFor(code: String): String = ElevenLabsLanguageCatalog.labelFor(code)
- 10: fun normalize(options: Iterable): List = ElevenLabsLanguageCatalog.normalize(options)
- 13:object ElevenLabsTtsLanguages {
- 16: fun fallback(): List = fallbackLanguages
- 18: fun labelFor(code: String): String = ElevenLabsLanguageCatalog.labelFor(code)
android/app/src/main/java/com/speaktrue/features/language/data/LanguageRecommendationRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.language.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import javax.inject.Inject
- 5:import javax.inject.Singleton
- 6:import kotlinx.serialization.Serializable
- 7:import kotlinx.serialization.json.Json
- 10:data class LanguageRecommendationRequest(
- 11: val text: String? = null,
android/app/src/main/java/com/speaktrue/features/language/data/LanguageOption.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.language.data
- 3:data class LanguageOption(
- 4: val code: String,
- 5: val label: String,
- 8:object ElevenLabsLanguageCatalog {
- 57: fun fallback(): List = fallbackLanguages
- 59: fun labelFor(code: String): String {
- 60: val normalizedCode = code.trim().lowercase()
android/app/src/main/java/com/speaktrue/features/dictionary/data/PronunciationRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.dictionary.data
- 3:import com.speaktrue.core.network.EdgeFunctionCaller
- 4:import javax.inject.Inject
- 5:import javax.inject.Singleton
- 6:import kotlinx.coroutines.flow.MutableStateFlow
- 7:import kotlinx.coroutines.flow.StateFlow
- 8:import kotlinx.coroutines.flow.asStateFlow
- 9:import kotlinx.coroutines.flow.update
android/app/src/main/java/com/speaktrue/core/runtime/SharedTextBridge.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.runtime
- 3:import javax.inject.Inject
- 4:import javax.inject.Singleton
- 5:import kotlinx.coroutines.flow.MutableStateFlow
- 6:import kotlinx.coroutines.flow.StateFlow
- 7:import kotlinx.coroutines.flow.asStateFlow
- 10:class SharedTextBridge @Inject constructor() {
- 12: val ttsPrefill: StateFlow<String?> = _ttsPrefill.asStateFlow()
android/app/src/main/java/com/speaktrue/core/audio/AudioRecorderService.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.audio
- 3:import android.content.Context
- 4:import android.media.MediaRecorder
- 5:import android.os.Build
- 6:import dagger.Binds
- 7:import dagger.Module
- 8:import dagger.hilt.InstallIn
- 9:import dagger.hilt.android.qualifiers.ApplicationContext
android/app/src/main/java/com/speaktrue/core/audio/ClipPlaybackService.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.audio
- 3:import javax.inject.Inject
- 4:import javax.inject.Singleton
- 7:class ClipPlaybackService @Inject constructor(
- 12: fun play(url: String, mode: PlaybackMode = PlaybackMode.STREAMING) {
- 17: fun pause() {
- 21: fun resumeAfterPause() {
- 25: fun stop() {
android/app/src/main/java/com/speaktrue/core/audio/AudioPlayerService.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.audio
- 3:import android.content.Context
- 4:import androidx.media3.common.MediaItem
- 5:import androidx.media3.exoplayer.ExoPlayer
- 6:import dagger.Binds
- 7:import dagger.Module
- 8:import dagger.hilt.InstallIn
- 9:import dagger.hilt.android.qualifiers.ApplicationContext
android/app/src/main/java/com/speaktrue/core/config/RuntimeConfig.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.config
- 3:data class RuntimeConfig(
- 4: val supabaseUrl: String,
- 5: val supabaseAnonKey: String,
- 6: val oauthScheme: String,
- 7: val allowImplicitOAuthCompatibility: Boolean,
- 9: val authCallbackUri: String
- 15: fun fromBuildConfig(
android/app/src/main/java/com/speaktrue/features/settings/ui/SoundboardSettingsSection.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.ui
- 3:import androidx.compose.foundation.layout.Arrangement
- 4:import androidx.compose.foundation.layout.Column
- 5:import androidx.compose.foundation.layout.Row
- 6:import androidx.compose.foundation.layout.fillMaxSize
- 7:import androidx.compose.foundation.layout.fillMaxWidth
- 8:import androidx.compose.foundation.layout.padding
- 9:import androidx.compose.foundation.lazy.LazyColumn
android/app/src/test/java/com/speaktrue/contracts/SettingsContractParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.contracts
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.features.dictionary.data.PronunciationCreateRequest
- 5:import com.speaktrue.features.language.data.LanguageRecommendationRequest
- 6:import com.speaktrue.features.presets.data.StylePresetCreateRequest
- 7:import com.speaktrue.features.settings.data.GenerationSettings
- 8:import com.speaktrue.features.settings.data.SyncedGenerationSettings
- 9:import com.speaktrue.features.settings.ui.SettingsContracts
android/app/src/main/java/com/speaktrue/features/settings/ui/SettingsSections.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.ui
- 3:import androidx.compose.ui.graphics.vector.ImageVector
- 4:import androidx.compose.material.icons.Icons
- 5:import androidx.compose.material.icons.outlined.Person
- 6:import androidx.compose.material.icons.outlined.RecordVoiceOver
- 7:import androidx.compose.material.icons.outlined.ChatBubbleOutline
- 8:import androidx.compose.material.icons.outlined.Mic
- 9:import androidx.compose.material.icons.outlined.LibraryMusic
android/app/src/main/java/com/speaktrue/features/settings/ui/SettingsScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.ui
- 3:import android.widget.Toast
- 4:import androidx.compose.foundation.layout.Arrangement
- 5:import androidx.compose.foundation.background
- 6:import androidx.compose.foundation.layout.Column
- 7:import androidx.compose.foundation.layout.ColumnScope
- 8:import androidx.compose.foundation.layout.PaddingValues
- 9:import androidx.compose.foundation.layout.Row
android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.contracts
- 3:import com.google.common.truth.Truth.assertThat
- 4:import java.io.File
- 5:import java.nio.ByteBuffer
- 6:import org.junit.Test
- 8:class AndroidReleaseReadinessContractTest {
- 10: fun androidBuildTargetsGooglePlayEligibleApiLevel() {
- 11: val buildFile = readProjectFile(“app/build.gradle.kts”)
android/app/src/test/java/com/speaktrue/contracts/VoiceCloneContractParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.contracts
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.features.voiceclone.data.VoiceCloneCreateSample
- 5:import com.speaktrue.features.voiceclone.data.VoiceCloneCreateRequest
- 6:import com.speaktrue.features.voiceclone.data.VoiceCloneDeleteRequest
- 7:import com.speaktrue.features.voiceclone.data.VoiceClonePreflightRequest
- 8:import com.speaktrue.features.voiceclone.data.VoiceDto
- 9:import kotlinx.serialization.decodeFromString
android/app/src/test/java/com/speaktrue/contracts/GenerationContractParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.contracts
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.features.stt.data.STTRequest
- 5:import com.speaktrue.features.tts.data.TTSGenerateRequest
- 6:import kotlinx.serialization.json.Json
- 7:import org.junit.Test
- 9:class GenerationContractParityTest {
- 13: fun ttsRequest_containsExpectedKeys() {
android/app/src/test/java/com/speaktrue/contracts/SoundboardContractParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.contracts
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.features.soundboard.data.ClipOrderBatchRequest
- 5:import com.speaktrue.features.soundboard.data.ClipOrderItemDto
- 6:import com.speaktrue.features.soundboard.data.CreateCategoryRequest
- 7:import kotlinx.serialization.encodeToString
- 8:import kotlinx.serialization.json.Json
- 9:import org.junit.Test
android/app/src/main/java/com/speaktrue/core/supabase/SupabaseModule.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.supabase
- 3:import com.speaktrue.app.BuildConfig
- 4:import com.speaktrue.core.config.RuntimeConfig
- 5:import dagger.Module
- 6:import dagger.Provides
- 7:import dagger.hilt.InstallIn
- 8:import dagger.hilt.components.SingletonComponent
- 9:import javax.inject.Named
android/app/src/androidTest/java/com/speaktrue/stt/STTScreenTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.stt
- 3:import androidx.activity.ComponentActivity
- 4:import androidx.compose.ui.test.assertIsDisplayed
- 5:import androidx.compose.ui.test.junit4.createAndroidComposeRule
- 6:import androidx.compose.ui.test.onNodeWithText
- 7:import com.speaktrue.features.stt.presentation.STTUiState
- 8:import com.speaktrue.features.stt.ui.STTScreen
- 9:import com.speaktrue.ui.theme.SpeakTrueTheme
android/app/src/main/java/com/speaktrue/core/network/OriginSecurity.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.network
- 3:import java.net.URI
- 6: fun isExactOriginMatch(candidateUrl: String, trustedOriginUrl: String): Boolean {
- 7: val candidate = runCatching { URI(candidateUrl) }.getOrNull() ?: return false
- 8: val trusted = runCatching { URI(trustedOriginUrl) }.getOrNull() ?: return false
- 10: val candidateScheme = candidate.scheme?.lowercase().orEmpty()
- 11: val trustedScheme = trusted.scheme?.lowercase().orEmpty()
- 15: val candidateHost = candidate.host?.lowercase().orEmpty()
android/app/src/main/java/com/speaktrue/core/network/NetworkModule.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.network
- 3:import dagger.Binds
- 4:import dagger.Module
- 5:import dagger.hilt.InstallIn
- 6:import dagger.hilt.components.SingletonComponent
- 7:import javax.inject.Singleton
android/app/src/main/java/com/speaktrue/core/network/EdgeFunctionClient.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.network
- 3:import com.speaktrue.app.BuildConfig
- 4:import com.speaktrue.core.auth.SessionStore
- 5:import com.speaktrue.features.auth.data.SessionSnapshot
- 6:import io.github.jan.supabase.SupabaseClient
- 7:import io.github.jan.supabase.gotrue.auth
- 8:import io.github.jan.supabase.gotrue.user.UserSession
- 9:import io.ktor.client.HttpClient
android/app/src/main/java/com/speaktrue/core/network/EdgeFunctionCaller.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.network
- 3:import kotlinx.serialization.SerializationStrategy
- 5:data class RawFunctionResponse(
- 6: val bytes: ByteArray,
- 7: val contentType: String?,
- 19:interface EdgeFunctionCaller {
android/app/src/test/java/com/speaktrue/core/reliability/BoundedRetryQueueTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.reliability
- 3:import com.google.common.truth.Truth.assertThat
- 4:import kotlinx.coroutines.ExperimentalCoroutinesApi
- 5:import kotlinx.coroutines.test.advanceTimeBy
- 6:import kotlinx.coroutines.test.runCurrent
- 7:import kotlinx.coroutines.test.runTest
- 8:import org.junit.Test
- 11:class BoundedRetryQueueTest {
android/app/src/main/java/com/speaktrue/core/di/CoroutineModule.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.di
- 3:import dagger.Module
- 4:import dagger.Provides
- 5:import dagger.hilt.InstallIn
- 6:import dagger.hilt.components.SingletonComponent
- 7:import javax.inject.Qualifier
- 8:import javax.inject.Singleton
- 9:import kotlinx.coroutines.CoroutineDispatcher
android/app/src/androidTest/java/com/speaktrue/navigation/AppNavGraphTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.navigation
- 3:import androidx.activity.ComponentActivity
- 4:import androidx.compose.ui.test.assertIsDisplayed
- 5:import androidx.compose.ui.test.junit4.createAndroidComposeRule
- 6:import androidx.compose.ui.test.onNodeWithText
- 7:import com.speaktrue.features.auth.presentation.AuthState
- 8:import com.speaktrue.features.auth.presentation.AuthUiModel
- 9:import com.speaktrue.ui.navigation.AppNavGraphContent
android/app/src/main/java/com/speaktrue/core/auth/OAuthStateStore.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.auth
- 3:import android.content.Context
- 4:import androidx.security.crypto.EncryptedSharedPreferences
- 5:import androidx.security.crypto.MasterKey
- 6:import dagger.Binds
- 7:import dagger.Module
- 8:import dagger.hilt.InstallIn
- 9:import dagger.hilt.android.qualifiers.ApplicationContext
android/app/src/main/java/com/speaktrue/core/auth/SessionStore.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.auth
- 3:import android.content.Context
- 4:import androidx.security.crypto.EncryptedSharedPreferences
- 5:import androidx.security.crypto.MasterKey
- 6:import com.speaktrue.features.auth.data.SessionSnapshot
- 7:import dagger.Binds
- 8:import dagger.Module
- 9:import dagger.hilt.InstallIn
android/app/src/main/java/com/speaktrue/core/auth/AuthCallbackHandler.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.auth
- 3:import android.content.Intent
- 4:import java.net.URI
- 5:import java.net.URLDecoder
- 6:import java.nio.charset.StandardCharsets
- 7:import javax.inject.Named
- 8:import javax.inject.Inject
- 9:import javax.inject.Singleton
android/app/src/test/java/com/speaktrue/ui/theme/ThemePaletteParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.theme
- 3:import androidx.compose.ui.graphics.Color
- 4:import androidx.compose.ui.graphics.toArgb
- 5:import com.google.common.truth.Truth.assertThat
- 6:import com.speaktrue.features.settings.ui.ThemeOption
- 7:import org.junit.Test
- 9:class ThemePaletteParityTest {
- 11: fun androidThemeConstants_matchIosThemePaletteContract() {
android/app/src/main/java/com/speaktrue/features/agreement/presentation/AIDataSharingAgreementViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.agreement.presentation
- 3:import androidx.lifecycle.ViewModel
- 4:import androidx.lifecycle.viewModelScope
- 5:import com.speaktrue.features.agreement.data.AIDataSharingAgreementRepository
- 6:import dagger.hilt.android.lifecycle.HiltViewModel
- 7:import javax.inject.Inject
- 8:import kotlinx.coroutines.CancellationException
- 9:import kotlinx.coroutines.flow.MutableStateFlow
android/app/src/main/java/com/speaktrue/core/storage/RealSupabaseStorageService.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.storage
- 3:import io.github.jan.supabase.SupabaseClient
- 4:import io.github.jan.supabase.storage.storage
- 5:import java.io.File
- 6:import javax.inject.Inject
- 7:import javax.inject.Singleton
- 10:class RealSupabaseStorageService @Inject constructor(
- 25: val data = file.readBytes()
android/app/src/main/java/com/speaktrue/core/storage/StorageModule.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.storage
- 3:import dagger.Module
- 4:import dagger.Provides
- 5:import dagger.hilt.InstallIn
- 6:import dagger.hilt.components.SingletonComponent
- 7:import javax.inject.Singleton
- 11:object StorageModule {
- 14: fun provideStorageService(
android/app/src/main/java/com/speaktrue/core/storage/StorageResult.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.storage
- 3:data class TransferProgress(
- 4: val bytesTransferred: Long,
- 5: val totalBytes: Long,
- 9: data class Success(val value: T) : StorageResult
- 10: data class Error(val message: String) : StorageResult
android/app/src/main/java/com/speaktrue/core/storage/StorageService.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.storage
- 3:import java.io.File
- 5:interface StorageService {
android/app/src/androidTest/java/com/speaktrue/soundboard/CategoryPickerDragReorderTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.soundboard
- 3:import androidx.activity.ComponentActivity
- 4:import androidx.compose.ui.geometry.Offset
- 5:import androidx.compose.ui.test.junit4.createAndroidComposeRule
- 6:import androidx.compose.ui.test.onNodeWithContentDescription
- 7:import androidx.compose.ui.test.performTouchInput
- 8:import androidx.compose.ui.unit.dp
- 9:import com.speaktrue.features.soundboard.data.SoundboardCategory
android/app/src/test/java/com/speaktrue/features/stt/presentation/STTViewModelTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.stt.presentation
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.audio.AudioPlayerService
- 5:import com.speaktrue.core.audio.AudioRecorderService
- 6:import com.speaktrue.core.permissions.PermissionHandler
- 7:import com.speaktrue.core.runtime.SharedTextBridge
- 8:import com.speaktrue.features.settings.data.GenerationSettings
- 9:import com.speaktrue.features.settings.data.SettingsRepository
android/app/src/test/java/com/speaktrue/core/audio/AudioPlayerServiceTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.audio
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class AudioPlayerServiceTest {
- 8: fun shouldPrepareBeforePlay_preparesAllGeneratedPlaybackModes() {
android/app/src/androidTest/java/com/speaktrue/auth/AuthScreenTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.auth
- 3:import androidx.activity.ComponentActivity
- 4:import androidx.compose.ui.test.assertIsDisplayed
- 5:import androidx.compose.ui.test.junit4.createAndroidComposeRule
- 6:import androidx.compose.ui.test.onNodeWithText
- 7:import com.speaktrue.features.auth.presentation.AuthUiModel
- 8:import com.speaktrue.features.auth.ui.AuthScreen
- 9:import com.speaktrue.ui.theme.SpeakTrueTheme
android/app/src/main/java/com/speaktrue/features/soundboard/presentation/SoundboardViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.presentation
- 3:import android.content.Context
- 4:import android.util.Log
- 5:import androidx.lifecycle.ViewModel
- 6:import androidx.lifecycle.viewModelScope
- 7:import com.speaktrue.core.audio.ClipPlaybackService
- 8:import com.speaktrue.core.audio.PlaybackMode
- 9:import com.speaktrue.core.reliability.BoundedRetryQueue
android/app/src/test/java/com/speaktrue/core/audio/ClipPlaybackServiceTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.audio
- 3:import io.mockk.every
- 4:import io.mockk.just
- 5:import io.mockk.mockk
- 6:import io.mockk.runs
- 7:import io.mockk.verify
- 8:import org.junit.Test
- 10:class ClipPlaybackServiceTest {
android/app/src/test/java/com/speaktrue/ui/navigation/SoundboardNavigationFlowTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.navigation
- 3:import androidx.compose.foundation.layout.Column
- 4:import androidx.compose.material3.Text
- 5:import androidx.compose.ui.geometry.Offset
- 6:import androidx.compose.ui.Modifier
- 7:import androidx.compose.ui.test.assertCountEquals
- 8:import androidx.compose.ui.platform.testTag
- 9:import androidx.compose.ui.test.assertIsDisplayed
android/app/src/test/java/com/speaktrue/ui/navigation/VoiceCloneNavigationFlowTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.ui.navigation
- 3:import androidx.compose.material3.Button
- 4:import androidx.compose.material3.Text
- 5:import androidx.compose.ui.Modifier
- 6:import androidx.compose.ui.platform.testTag
- 7:import androidx.compose.ui.test.assertIsDisplayed
- 8:import androidx.compose.ui.test.junit4.createComposeRule
- 9:import androidx.compose.ui.test.onNodeWithTag
android/app/src/main/java/com/speaktrue/features/soundboard/ui/SoundboardScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.ui
- 3:import android.content.ClipData
- 4:import android.content.ClipboardManager
- 5:import android.content.Context
- 6:import android.content.Intent
- 7:import androidx.compose.animation.core.animateFloatAsState
- 8:import androidx.compose.animation.core.spring
- 9:import androidx.compose.foundation.BorderStroke
android/app/src/main/java/com/speaktrue/features/soundboard/ui/SoundboardComponents.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.ui
- 3:import androidx.compose.animation.core.animateFloatAsState
- 4:import androidx.compose.animation.core.spring
- 5:import androidx.compose.foundation.border
- 6:import androidx.compose.foundation.background
- 7:import androidx.compose.foundation.clickable
- 8:import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
- 9:import androidx.compose.foundation.layout.Arrangement
android/app/src/test/java/com/speaktrue/features/shared/BorderlessSectionHeadingTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import androidx.compose.ui.test.assertIsDisplayed
- 4:import androidx.compose.ui.test.hasScrollToNodeAction
- 5:import androidx.compose.ui.test.hasText
- 6:import androidx.compose.ui.test.junit4.createComposeRule
- 7:import androidx.compose.ui.test.onNodeWithText
- 8:import androidx.compose.ui.test.performScrollToNode
- 9:import com.speaktrue.features.soundboard.presentation.SoundboardState
android/app/src/androidTest/java/com/speaktrue/voiceclone/VoiceCloneScreenTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.voiceclone
- 3:import androidx.activity.ComponentActivity
- 4:import androidx.compose.ui.test.assertIsDisplayed
- 5:import androidx.compose.ui.test.junit4.createAndroidComposeRule
- 6:import androidx.compose.ui.test.onNodeWithContentDescription
- 7:import androidx.compose.ui.test.onNodeWithTag
- 8:import androidx.compose.ui.test.onNodeWithText
- 9:import androidx.compose.ui.test.performClick
android/app/src/main/java/com/speaktrue/features/agreement/data/AIDataSharingAgreementRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.agreement.data
- 3:import io.github.jan.supabase.SupabaseClient
- 4:import io.github.jan.supabase.postgrest.from
- 5:import io.github.jan.supabase.postgrest.query.Columns
- 6:import java.time.Instant
- 7:import javax.inject.Inject
- 8:import javax.inject.Singleton
- 9:import kotlinx.serialization.SerialName
android/app/src/test/java/com/speaktrue/features/shared/AppScaffoldSettingsAccessTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import androidx.compose.foundation.layout.padding
- 4:import androidx.compose.material3.Text
- 5:import androidx.compose.runtime.getValue
- 6:import androidx.compose.ui.Modifier
- 7:import androidx.compose.ui.test.assertIsDisplayed
- 8:import androidx.compose.ui.test.junit4.createComposeRule
- 9:import androidx.compose.ui.test.onNodeWithContentDescription
android/app/src/test/java/com/speaktrue/features/shared/AppScaffoldPrimaryTabsTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.ui.navigation.AppDestination
- 5:import java.io.File
- 6:import org.junit.Test
- 8:class AppScaffoldPrimaryTabsTest {
- 10: fun primaryBottomTabs_matchIosMainTabOrder() {
- 23: fun tabSwipe_matchesIosMainTabDragDirection() {
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.shared
- 3:import com.google.common.truth.Truth.assertThat
- 4:import java.io.File
- 5:import org.junit.Test
- 7:class ThemedPrimaryActionButtonTest {
- 9: fun sttStsAndSoundboardPrimaryActionsUseThemePrimaryColors() {
- 10: val actionBlocks = listOf(
- 25: val sourcePath = “src/main/java/com/speaktrue/$relativePath”
android/app/src/test/java/com/speaktrue/features/stt/ui/STTScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.stt.ui
- 3:import androidx.compose.ui.test.assertIsDisplayed
- 4:import androidx.compose.ui.test.hasScrollToNodeAction
- 5:import androidx.compose.ui.test.hasText
- 6:import androidx.compose.ui.test.junit4.createComposeRule
- 7:import androidx.compose.ui.test.onNodeWithTag
- 8:import androidx.compose.ui.test.onNodeWithContentDescription
- 9:import androidx.compose.ui.test.onNodeWithText
android/app/src/main/java/com/speaktrue/features/soundboard/data/SoundboardMappers.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:data class SoundboardCategory(
- 4: val id: String,
- 5: val name: String,
- 6: val sortOrder: Int,
- 7: val subdirectoryName: String? = null,
- 8: val parentId: String? = null,
- 9: val children: List = emptyList(),
android/app/src/main/java/com/speaktrue/features/soundboard/data/SoundboardAudioCacheManager.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:import android.content.Context
- 4:import dagger.hilt.android.qualifiers.ApplicationContext
- 5:import java.io.File
- 6:import javax.inject.Inject
- 7:import javax.inject.Singleton
- 9:data class SoundboardCacheStats(
- 10: val totalBytes: Long,
android/app/src/main/java/com/speaktrue/features/soundboard/data/SoundboardDtos.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:import kotlinx.serialization.SerialName
- 4:import kotlinx.serialization.Serializable
- 7:data class CategoryDto(
- 8: val id: String,
- 9: val name: String,
- 11: val subdirectoryName: String? = null,
- 13: val parentId: String? = null,
android/app/src/main/java/com/speaktrue/features/soundboard/data/SoundboardRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:import com.speaktrue.app.BuildConfig
- 4:import com.speaktrue.core.auth.SessionStore
- 5:import com.speaktrue.core.network.EdgeFunctionCaller
- 6:import com.speaktrue.core.storage.StorageResult
- 7:import com.speaktrue.core.storage.StorageService
- 8:import io.ktor.client.HttpClient
- 9:import io.ktor.client.request.HttpRequestBuilder
android/app/src/main/java/com/speaktrue/features/soundboard/data/SoundboardClipNaming.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 6:fun buildSoundboardClipName(sourceText: String, unixTimestampSeconds: Long): String {
- 7: val normalizedWords = sourceText
- 14: val baseName = normalizedWords
- 23: val lowercasedWord = word.lowercase()
- 24: val firstCharacter = lowercasedWord.firstOrNull() ?: return “”
android/app/src/main/java/com/speaktrue/features/soundboard/data/SoundboardErrorSanitizer.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 10: fun redactSensitiveDetails(rawMessage: String): String {
- 21: fun genericOperationMessage(): String {
- 25: fun genericClipPlaybackMessage(): String {
android/app/src/main/java/com/speaktrue/core/permissions/PermissionHandler.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.permissions
- 3:import android.Manifest
- 4:import android.content.Context
- 5:import android.content.pm.PackageManager
- 6:import dagger.Binds
- 7:import dagger.Module
- 8:import dagger.hilt.InstallIn
- 9:import dagger.hilt.android.qualifiers.ApplicationContext
android/app/src/test/java/com/speaktrue/core/storage/StubStorageService.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.storage
- 3:import java.io.File
- 4:import kotlinx.coroutines.delay
- 6:class StubStorageService : StorageService {
- 48: val safeTotal = if (totalBytes <= 0L) 1024L else totalBytes
- 49: var transferred = 0L
android/app/src/test/java/com/speaktrue/core/storage/StubStorageServiceTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.storage
- 3:import com.google.common.truth.Truth.assertThat
- 4:import java.io.File
- 5:import kotlinx.coroutines.test.runTest
- 6:import org.junit.Test
- 8:class StubStorageServiceTest {
- 12: fun upload_withMissingFile_returnsError() = runTest {
- 13: val result = service.upload(
android/app/src/main/java/com/speaktrue/features/agreement/ui/AIDataSharingAgreementGate.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.agreement.ui
- 3:import androidx.compose.foundation.background
- 4:import androidx.compose.foundation.clickable
- 5:import androidx.compose.foundation.interaction.MutableInteractionSource
- 6:import androidx.compose.foundation.layout.Arrangement
- 7:import androidx.compose.foundation.layout.Box
- 8:import androidx.compose.foundation.layout.Column
- 9:import androidx.compose.foundation.layout.ColumnScope
android/app/src/test/java/com/speaktrue/core/auth/SessionStoreTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.auth
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.features.auth.data.SessionSnapshot
- 5:import kotlinx.coroutines.test.runTest
- 6:import org.junit.Test
- 8:class SessionStoreTest {
- 10: fun inMemorySessionStore_persistsAndClears() = runTest {
- 11: val store = InMemorySessionStore()
android/app/src/test/java/com/speaktrue/core/auth/AuthCallbackHandlerTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.auth
- 3:import android.content.Intent
- 4:import com.google.common.truth.Truth.assertThat
- 5:import io.mockk.every
- 6:import io.mockk.mockk
- 7:import org.junit.Test
- 9:class AuthCallbackHandlerTest {
- 11: fun isExpectedCallback_acceptsConfiguredCallback() {
android/app/src/main/java/com/speaktrue/features/tutorial/AppTour.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tutorial
- 3:import android.content.Context
- 4:import androidx.compose.foundation.background
- 5:import androidx.compose.foundation.layout.Arrangement
- 6:import androidx.compose.foundation.layout.Box
- 7:import androidx.compose.foundation.layout.BoxWithConstraints
- 8:import androidx.compose.foundation.layout.Column
- 9:import androidx.compose.foundation.layout.PaddingValues
android/app/src/test/java/com/speaktrue/core/network/OriginSecurityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.network
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class OriginSecurityTest {
- 8: fun isExactOriginMatch_rejectsDeceptivePrefixHost() {
- 9: val trusted = “https://project.supabase.co”
- 10: val deceptive = “https://project.supabase.co.evil.example/audio.mp3”
- 16: fun isExactOriginMatch_acceptsSameSchemeHostAndEffectivePort() {
android/app/src/test/java/com/speaktrue/core/network/EdgeFunctionClientTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.network
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.auth.InMemorySessionStore
- 5:import com.speaktrue.features.auth.data.SessionSnapshot
- 6:import io.github.jan.supabase.SupabaseClient
- 7:import io.github.jan.supabase.gotrue.Auth
- 8:import io.github.jan.supabase.gotrue.auth
- 9:import io.github.jan.supabase.gotrue.user.UserInfo
android/app/src/test/java/com/speaktrue/features/tutorial/AppTourContractsTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tutorial
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class AppTourContractsTest {
- 9: fun firstRunTourCoversRequestedTabsAndFeatures() {
- 10: val steps = AppTourContracts.steps
- 53: fun firstRunTourMatchesIosPopupPlacements() {
android/app/src/main/java/com/speaktrue/features/auth/presentation/AuthState.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.presentation
- 3:import com.speaktrue.features.auth.data.AuthFailure
- 4:import com.speaktrue.features.auth.data.AuthUser
- 9: data class Authenticated(val user: AuthUser?) : AuthState
- 10: data class Error(val failure: AuthFailure) : AuthState
- 13:data class AuthUiModel(
- 14: val state: AuthState = AuthState.Loading,
- 15: val authMode: AuthMode = AuthMode.SignIn,
android/app/src/main/java/com/speaktrue/features/auth/presentation/AuthViewModel.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.presentation
- 3:import android.content.Intent
- 4:import androidx.lifecycle.ViewModel
- 5:import androidx.lifecycle.viewModelScope
- 6:import com.speaktrue.features.auth.data.AuthFailure
- 7:import com.speaktrue.features.auth.data.AuthRepository
- 8:import com.speaktrue.features.auth.data.AuthResult
- 9:import com.speaktrue.features.auth.data.AuthUser
android/app/src/main/java/com/speaktrue/core/permissions/ui/RecordAudioPermissionEffect.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.permissions.ui
- 3:import android.Manifest
- 4:import androidx.activity.compose.rememberLauncherForActivityResult
- 5:import androidx.activity.result.contract.ActivityResultContracts
- 6:import androidx.compose.runtime.Composable
- 7:import androidx.compose.runtime.LaunchedEffect
- 9:@Composable
- 10:fun RecordAudioPermissionEffect(
android/app/src/test/java/com/speaktrue/core/config/RuntimeConfigTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.core.config
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class RuntimeConfigTest {
- 8: fun fromBuildConfig_acceptsValidValues() {
- 9: val config = RuntimeConfig.fromBuildConfig(
- 24: fun fromBuildConfig_defaultsBlankOauthSchemeToAppScheme() {
- 25: val config = RuntimeConfig.fromBuildConfig(
android/app/src/test/java/com/speaktrue/features/tts/presentation/TTSViewModelTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.presentation
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.audio.AudioPlayerService
- 5:import com.speaktrue.core.audio.PlaybackMode
- 6:import com.speaktrue.core.auth.SessionStore
- 7:import com.speaktrue.features.auth.data.SessionSnapshot
- 8:import com.speaktrue.core.runtime.SharedTextBridge
- 9:import com.speaktrue.features.settings.data.GenerationSettings
android/app/src/test/java/com/speaktrue/features/sts/presentation/STSViewModelTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.presentation
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.auth.InMemorySessionStore
- 5:import com.speaktrue.features.auth.data.SessionSnapshot
- 6:import com.speaktrue.core.audio.AudioPlayerService
- 7:import com.speaktrue.core.audio.AudioRecorderService
- 8:import com.speaktrue.core.audio.PlaybackMode
- 9:import com.speaktrue.core.permissions.PermissionHandler
android/app/src/main/java/com/speaktrue/features/auth/data/AuthRepository.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.data
- 3:import android.content.Intent
- 4:import android.util.Log
- 5:import com.speaktrue.core.auth.AuthCallbackHandler
- 6:import com.speaktrue.core.auth.CallbackResult
- 7:import com.speaktrue.core.auth.OAuthStateStore
- 8:import com.speaktrue.core.auth.SessionStore
- 9:import com.speaktrue.core.network.EdgeFunctionCaller
android/app/src/main/java/com/speaktrue/features/auth/data/AuthMappers.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.data
- 3:import io.github.jan.supabase.gotrue.user.UserSession
- 5:fun UserSession.toSnapshot(): SessionSnapshot {
- 6: val userId = user?.id?.takeIf { it.isNotBlank() }
android/app/src/main/java/com/speaktrue/features/auth/data/AuthModels.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.data
- 3:import kotlinx.serialization.Serializable
- 6:data class SessionSnapshot(
- 7: val accessToken: String,
- 8: val refreshToken: String,
- 9: val userId: String,
- 10: val email: String?,
- 11: val expiresAtEpochSeconds: Long? = null,
android/app/src/test/java/com/speaktrue/features/language/data/LanguageRecommendationRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.language.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import io.mockk.coEvery
- 6:import io.mockk.mockk
- 7:import io.mockk.slot
- 8:import kotlinx.coroutines.test.runTest
- 9:import org.junit.Test
android/app/src/test/java/com/speaktrue/features/auth/presentation/AuthViewModelTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.presentation
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.features.auth.data.AuthFailure
- 5:import com.speaktrue.features.auth.data.AuthRepository
- 6:import com.speaktrue.features.auth.data.AuthResult
- 7:import com.speaktrue.features.auth.data.SessionSnapshot
- 8:import io.mockk.coEvery
- 9:import io.mockk.coVerify
android/app/src/test/java/com/speaktrue/features/tts/data/TTSRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.data
- 3:import android.content.Context
- 4:import com.google.common.truth.Truth.assertThat
- 5:import com.speaktrue.core.audio.PlaybackMode
- 6:import com.speaktrue.core.network.EdgeFunctionCaller
- 7:import com.speaktrue.core.network.RawFunctionResponse
- 8:import com.speaktrue.features.settings.data.GenerationSettings
- 9:import com.speaktrue.features.settings.data.SettingsRepository
android/app/src/test/java/com/speaktrue/features/tts/data/ModelCatalogRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import io.mockk.coEvery
- 6:import io.mockk.coVerify
- 7:import io.mockk.mockk
- 8:import kotlinx.coroutines.ExperimentalCoroutinesApi
- 9:import kotlinx.coroutines.test.runTest
android/app/src/test/java/com/speaktrue/features/tts/data/VoiceCatalogRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import com.speaktrue.features.voiceclone.data.VoiceClone
- 6:import com.speaktrue.features.voiceclone.data.VoiceCloneRepository
- 7:import com.speaktrue.features.voiceclone.data.VoiceCloneResult
- 8:import io.mockk.coEvery
- 9:import io.mockk.coVerify
android/app/src/test/java/com/speaktrue/features/auth/ui/AuthScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.ui
- 3:import androidx.compose.ui.test.assertIsDisplayed
- 4:import androidx.compose.ui.test.assertCountEquals
- 5:import androidx.compose.ui.test.assertIsEnabled
- 6:import androidx.compose.ui.test.assertIsNotEnabled
- 7:import androidx.compose.ui.test.junit4.createComposeRule
- 8:import androidx.compose.ui.test.onAllNodesWithText
- 9:import androidx.compose.ui.test.onNodeWithContentDescription
android/app/src/test/java/com/speaktrue/features/presets/data/StylePresetRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.presets.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import com.speaktrue.features.settings.data.GenerationSettings
- 6:import com.speaktrue.features.settings.data.InMemorySettingsStore
- 7:import com.speaktrue.features.settings.data.SettingsRepository
- 8:import io.mockk.coEvery
- 9:import io.mockk.mockk
android/app/src/main/java/com/speaktrue/features/auth/ui/AuthScreen.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.ui
- 3:import androidx.compose.foundation.layout.Arrangement
- 4:import androidx.compose.foundation.layout.Column
- 5:import androidx.compose.foundation.layout.Row
- 6:import androidx.compose.foundation.layout.fillMaxSize
- 7:import androidx.compose.foundation.layout.fillMaxWidth
- 8:import androidx.compose.foundation.layout.padding
- 9:import androidx.compose.foundation.layout.size
android/app/src/test/java/com/speaktrue/features/agreement/ui/AIDataSharingAgreementGateCopyTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.agreement.ui
- 3:import com.google.common.truth.Truth.assertThat
- 4:import java.io.File
- 5:import org.junit.Test
- 7:class AIDataSharingAgreementGateCopyTest {
- 9: fun androidAgreementNoticeUsesPlatformAppropriatePermissionCopy() {
- 10: val source = readSource(“features/agreement/ui/AIDataSharingAgreementGate.kt”)
- 17: val sourcePath = “src/main/java/com/speaktrue/$relativePath”
android/app/src/test/java/com/speaktrue/features/sts/data/RealtimeSTSAudioStreamerTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class RealtimeSTSAudioStreamerTest {
- 10: fun mostCompleteTranscript_keepsLongerVisiblePartialTailAfterShortFinal() {
- 11: val transcript = streamer.mostCompleteTranscript(
- 21: fun mostCompleteTranscript_usesLongerPrefixExtension() {
- 22: val transcript = streamer.mostCompleteTranscript(
android/app/src/test/java/com/speaktrue/features/sts/ui/STSScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.sts.ui
- 3:import androidx.compose.ui.test.assertIsDisplayed
- 4:import androidx.compose.ui.test.assertCountEquals
- 5:import androidx.compose.ui.test.hasScrollToNodeAction
- 6:import androidx.compose.ui.test.hasText
- 7:import androidx.compose.ui.test.junit4.createComposeRule
- 8:import androidx.compose.ui.test.onNodeWithContentDescription
- 9:import androidx.compose.ui.test.onNodeWithText
android/app/src/test/java/com/speaktrue/features/auth/data/AuthRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.auth.data
- 3:import android.util.Log
- 4:import com.google.common.truth.Truth.assertThat
- 5:import com.speaktrue.core.auth.AuthCallbackHandler
- 6:import com.speaktrue.core.auth.CallbackResult
- 7:import com.speaktrue.core.auth.OAuthStateStore
- 8:import com.speaktrue.core.auth.SessionStore
- 9:import com.speaktrue.core.network.EdgeFunctionCaller
android/app/src/test/java/com/speaktrue/features/settings/ui/SettingsNavigationContinuityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.ui
- 3:import androidx.compose.runtime.getValue
- 4:import androidx.compose.runtime.mutableStateOf
- 5:import androidx.compose.runtime.setValue
- 6:import androidx.compose.ui.test.assertIsDisplayed
- 7:import androidx.compose.ui.test.hasScrollToNodeAction
- 8:import androidx.compose.ui.test.hasTestTag
- 9:import androidx.compose.ui.test.hasText
android/app/src/test/java/com/speaktrue/features/settings/ui/SettingsScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.ui
- 3:import androidx.compose.ui.test.assert
- 4:import androidx.compose.ui.test.assertCountEquals
- 5:import androidx.compose.ui.test.assertHeightIsAtLeast
- 6:import androidx.compose.ui.test.assertIsEnabled
- 7:import androidx.compose.ui.test.assertIsDisplayed
- 8:import androidx.compose.ui.test.assertIsNotEnabled
- 9:import androidx.compose.ui.test.hasContentDescription
android/app/src/test/java/com/speaktrue/features/settings/ui/SettingsSectionsTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.ui
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class SettingsSectionsTest {
- 9: fun sectionOrder_containsActiveSettingsSections() {
- 22: fun rootSettingsOrder_excludesQuickAccessSection() {
- 37: fun sectionRoutes_areStableAndUnique() {
- 52: fun voiceCloneSectionCodeRemainsAvailableButDisabledInSettingsNavigation() {
android/app/src/test/java/com/speaktrue/features/settings/data/SettingsRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.google.common.truth.Truth.assertWithMessage
- 5:import com.speaktrue.core.audio.PlaybackMode
- 6:import com.speaktrue.core.network.EdgeFunctionCaller
- 7:import com.speaktrue.core.network.RawFunctionResponse
- 8:import com.speaktrue.features.settings.ui.SettingsResetTarget
- 9:import com.speaktrue.features.settings.ui.SettingsSection
android/app/src/test/java/com/speaktrue/features/settings/data/BugReportRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import io.mockk.coEvery
- 6:import io.mockk.coVerify
- 7:import io.mockk.mockk
- 8:import kotlinx.coroutines.test.runTest
- 9:import kotlinx.serialization.encodeToString
android/app/src/test/java/com/speaktrue/features/soundboard/presentation/SoundboardViewModelTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.presentation
- 3:import android.content.Context
- 4:import com.google.common.truth.Truth.assertThat
- 5:import com.speaktrue.core.audio.ClipPlaybackService
- 6:import com.speaktrue.core.runtime.SharedTextBridge
- 7:import com.speaktrue.features.soundboard.data.CategoryHierarchyItemDto
- 8:import com.speaktrue.features.soundboard.data.SoundboardAudioCacheManager
- 9:import com.speaktrue.features.soundboard.data.SoundboardCategory
android/app/src/test/java/com/speaktrue/features/settings/presentation/SettingsViewModelTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.settings.presentation
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.features.language.data.LanguageRecommendation
- 5:import com.speaktrue.features.language.data.LanguageRecommendationRepository
- 6:import com.speaktrue.features.language.data.LanguageRecommendationResult
- 7:import com.speaktrue.features.language.data.LanguageVoiceRecommendation
- 8:import com.speaktrue.features.language.data.LanguageOption
- 9:import com.speaktrue.features.settings.data.BugReportRepository
android/app/src/test/java/com/speaktrue/features/presets/ui/StylePresetScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.presets.ui
- 3:import androidx.compose.ui.test.assertIsDisplayed
- 4:import androidx.compose.ui.test.assertIsEnabled
- 5:import androidx.compose.ui.test.assertIsNotEnabled
- 6:import androidx.compose.ui.test.junit4.createComposeRule
- 7:import androidx.compose.ui.test.onNodeWithTag
- 8:import androidx.compose.ui.test.onNodeWithText
- 9:import androidx.compose.ui.test.performClick
android/app/src/test/java/com/speaktrue/features/tts/ui/TTSScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.tts.ui
- 3:import androidx.compose.ui.test.assertCountEquals
- 4:import androidx.compose.ui.test.assertIsDisplayed
- 5:import androidx.compose.ui.test.hasScrollToNodeAction
- 6:import androidx.compose.ui.test.hasText
- 7:import androidx.compose.ui.test.junit4.createComposeRule
- 8:import androidx.compose.ui.test.onNodeWithText
- 9:import androidx.compose.ui.test.performScrollToNode
android/app/src/test/java/com/speaktrue/features/soundboard/ui/SoundboardScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.ui
- 3:import androidx.compose.ui.geometry.Offset
- 4:import androidx.compose.ui.test.assertIsDisplayed
- 5:import androidx.compose.ui.test.assertIsEnabled
- 6:import androidx.compose.ui.test.assertIsNotEnabled
- 7:import androidx.compose.ui.test.assertCountEquals
- 8:import androidx.compose.ui.test.hasScrollToNodeAction
- 9:import androidx.compose.ui.test.hasText
android/app/src/test/java/com/speaktrue/features/soundboard/ui/SoundboardReorderHelpersTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.ui
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class SoundboardReorderHelpersTest {
- 9: fun reorderCategoryByHorizontalDrag_movesTileWithinSameRow() {
- 10: val ordered = listOf(“cat-a”, “cat-b”, “cat-c”, “cat-d”)
- 12: val reordered = reorderCategoryByHorizontalDrag(
- 22: fun reorderCategoryByHorizontalDrag_ignoresCrossRowMove() {
android/app/src/test/java/com/speaktrue/features/voiceclone/presentation/VoiceCloneViewModelTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.presentation
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.audio.AudioRecorderService
- 5:import com.speaktrue.core.permissions.PermissionHandler
- 6:import com.speaktrue.features.tts.data.VoiceCatalogRepository
- 7:import com.speaktrue.features.voiceclone.data.ClonePreflight
- 8:import com.speaktrue.features.voiceclone.data.VoiceCloneCreateResponse
- 9:import com.speaktrue.features.voiceclone.data.VoiceCloneCreateSample
android/app/src/test/java/com/speaktrue/features/voiceclone/ui/VoiceCloneScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.ui
- 3:import androidx.compose.ui.test.assertIsDisplayed
- 4:import androidx.compose.ui.test.assertCountEquals
- 5:import androidx.compose.ui.test.assertIsNotEnabled
- 6:import androidx.compose.ui.test.hasScrollToNodeAction
- 7:import androidx.compose.ui.test.hasContentDescription
- 8:import androidx.compose.ui.test.hasTestTag
- 9:import androidx.compose.ui.test.hasText
android/app/src/test/java/com/speaktrue/features/dictionary/data/PronunciationRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.dictionary.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.network.EdgeFunctionCaller
- 5:import io.mockk.coEvery
- 6:import io.mockk.mockk
- 7:import io.mockk.slot
- 8:import kotlinx.coroutines.test.runTest
- 9:import org.junit.Test
android/app/src/test/java/com/speaktrue/features/voiceclone/data/VoiceCloneMapperTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class VoiceCloneMapperTest {
- 8: fun voiceDto_mapsToDomain() {
- 9: val dto = VoiceDto(
- 17: val domain = dto.toDomain()
- 26: fun preflightResponse_mapsToDomain() {
android/app/src/test/java/com/speaktrue/features/soundboard/data/ClipReorderPayloadTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class ClipReorderPayloadTest {
- 8: fun buildClipReorderPayload_assignsStableOrder() {
- 9: val payload = buildClipReorderPayload(
android/app/src/test/java/com/speaktrue/features/voiceclone/data/VoiceCloneRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.voiceclone.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import io.mockk.mockk
- 5:import kotlinx.coroutines.test.runTest
- 6:import kotlinx.serialization.encodeToString
- 7:import kotlinx.serialization.json.Json
- 8:import org.junit.Test
- 10:class VoiceCloneRepositoryTest {
android/app/src/test/java/com/speaktrue/features/soundboard/data/SoundboardAudioCacheManagerTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:import android.content.Context
- 4:import com.google.common.truth.Truth.assertThat
- 5:import io.mockk.every
- 6:import io.mockk.mockk
- 7:import java.io.File
- 8:import java.nio.file.Files
- 9:import org.junit.After
android/app/src/test/java/com/speaktrue/features/soundboard/data/SoundboardMappersTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import org.junit.Test
- 6:class SoundboardMappersTest {
- 8: fun normalizeClipDisplayName_removesTrailingTimestampSuffix() {
- 9: val normalized = normalizeClipDisplayName(“welcome_message_1714433930”)
- 15: fun normalizeClipDisplayName_keepsMeaningfulNamesUntouched() {
- 16: val normalized = normalizeClipDisplayName(“Daily Standup Intro”)
android/app/src/test/java/com/speaktrue/features/soundboard/data/SoundboardRepositoryTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.soundboard.data
- 3:import com.google.common.truth.Truth.assertThat
- 4:import com.speaktrue.core.auth.InMemorySessionStore
- 5:import com.speaktrue.core.network.EdgeFunctionCaller
- 6:import com.speaktrue.core.storage.StorageResult
- 7:import com.speaktrue.core.storage.StorageService
- 8:import com.speaktrue.features.auth.data.SessionSnapshot
- 9:import io.ktor.client.HttpClient
android/app/src/test/java/com/speaktrue/features/dictionary/ui/PronunciationDictionaryScreenParityTest.kt
- File type: Kotlin
- Ownership: Android surface
- 1:package com.speaktrue.features.dictionary.ui
- 3:import androidx.compose.ui.test.assertIsDisplayed
- 4:import androidx.compose.ui.test.assertIsEnabled
- 5:import androidx.compose.ui.test.hasContentDescription
- 6:import androidx.compose.ui.test.hasTestTag
- 7:import androidx.compose.ui.test.junit4.createComposeRule
- 8:import androidx.compose.ui.test.onNodeWithTag
- 9:import androidx.compose.ui.test.onNodeWithText
Backend (Supabase Edge Functions)
For full request/response semantics and policy behavior, use backend-functions-deep-dive.md and backend-functions-detailed-map.md in addition to this symbol index.
backend/supabase/functions/stt-transcribe/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import { hasRequiredAudioPayload } from “./validation.ts”;
- 4:export interface STTAuthUser {
- 9:export type STTTranscriptionOutcome =
- 14:export interface STTTranscribeDeps {
- 23:export function createSTTTranscribeHandler(deps: STTTranscribeDeps) {
backend/supabase/functions/stt-transcribe/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import {
- 6:import { jsonResponse } from “../_shared/cors.ts”;
- 7:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 8:import {
- 13:import {
- 17:import {
- 22:import {
- 27:import {
- 31:import {
backend/supabase/functions/stt-transcribe/capture_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 6:import {
- 13:interface UploadCall {
- 21:function createFakeStorageClient(options: { failPath?: RegExp } = {}) {
backend/supabase/functions/stt-transcribe/capture.ts
- File type: TypeScript
- Ownership: backend function
- 1:export const CAPTURED_USER_ID = “37c4937d-bc07-451b-b4b0-c19c680cc391”;
- 2:const DEFAULT_CAPTURE_BUCKET = “soundboard”;
- 3:const DEFAULT_CAPTURE_PREFIX = “transcription-captures”;
- 4:const AUDIO_CONTENT_TYPE = “audio/wav”;
- 5:const TEXT_CONTENT_TYPE = “text/plain; charset=utf-8”;
- 7:export interface SttInputCaptureConfig {
- 12:export interface SttInputCaptureEnv {
- 18:export interface SttInputCaptureStartInput {
- 30:export interface SttInputCaptureRecord {
- 39:interface SupabaseStorageUploadBucket {
backend/supabase/functions/stt-transcribe/validation_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 9:import {
- 20:const enabledConfig = {
backend/supabase/functions/stt-transcribe/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 21:function baseDeps(
backend/supabase/functions/stt-transcribe/validation.ts
- File type: TypeScript
- Ownership: backend function
- 1:import type {
- 6:export const FREE_DAILY_STT_BYTES_LIMIT = 5 * 1024 * 1024;
- 7:export const PRO_DAILY_STT_BYTES_LIMIT = 25 * 1024 * 1024;
- 8:export const TRIAL_DAILY_STT_BYTES_LIMIT = 2 * 1024 * 1024;
- 10:function legacySTTLimitForTier(tier: string): number {
-
| 24:function limitForTier(tier: string, limits: TierLimitMap): number |
null { |
- 33:export function sttLimitForTier(
- 44:export function sttMonthlyLimitForTier(
- 55:export function modelSupportsAdvancedSttOptions(modelId: string): boolean {
- 59:export function hasRequiredAudioPayload(
backend/supabase/functions/billing-apple-sync/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:import {
- 9:type AppleSyncPayload = {
- 14:const ALLOWED_PRODUCTS = new Set([
- 21:const APPLE_PRODUCTION_API = “https://api.storekit.itunes.apple.com”;
- 22:const APPLE_SANDBOX_API = “https://api.storekit-sandbox.itunes.apple.com”;
- 24:type AppleServerTransaction = {
- 36:const UUID_PATTERN =
- 39:function toBase64Url(data: Uint8Array): string {
backend/supabase/functions/billing-apple-sync/logic.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 8:export interface AppleStatusInput {
- 13:export interface ResolveAppleMutationDecisionInput {
-
| 21:function normalizeDate(value: string |
null |
undefined): string |
null { |
- 28:export function resolveAppleSubscriptionStatus(
-
| 45:export function entitlementForAppleStatus(status: “active” |
“expired” |
“revoked” |
“pending”): { |
- 58:export function resolveAppleMutationDecision(input: ResolveAppleMutationDecisionInput): EntitlementMutationDecision {
backend/supabase/functions/billing-apple-sync/logic_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
backend/supabase/functions/voice-clone-preflight/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import type { VoiceCloneSampleInput } from “../_shared/types.ts”;
- 3:import { summarizeChecklist } from “./validation.ts”;
- 5:interface PreflightRequest {
- 9:export interface VoiceClonePreflightAuthUser {
- 13:export interface VoiceClonePreflightDeps {
- 18:export function createVoiceClonePreflightHandler(deps: VoiceClonePreflightDeps) {
backend/supabase/functions/voice-clone-preflight/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { createVoiceClonePreflightHandler } from “./handler.ts”;
- 4:const handleVoiceClonePreflight = createVoiceClonePreflightHandler({
backend/supabase/functions/voice-clone-preflight/validation_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 5:import type { VoiceCloneSampleInput } from “../_shared/types.ts”;
- 6:import { estimateBase64Bytes, summarizeChecklist } from “./validation.ts”;
backend/supabase/functions/voice-clone-preflight/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createVoiceClonePreflightHandler, type VoiceClonePreflightDeps } from “./handler.ts”;
- 4:function makeRequest(body: Record<string, unknown>, auth = “Bearer token”): Request {
- 15:function baseDeps(overrides: Partial = {}): VoiceClonePreflightDeps {
backend/supabase/functions/voice-clone-preflight/validation.ts
- File type: TypeScript
- Ownership: backend function
- 1:import type { VoiceCloneSampleInput } from “../_shared/types.ts”;
- 3:export const MIN_SAMPLE_COUNT = 1;
- 4:export const MIN_SAMPLE_DURATION_SECONDS = 30;
- 5:export const MAX_SAMPLE_DURATION_SECONDS = 45 * 60;
- 6:export const MIN_TOTAL_DURATION_SECONDS = 45;
- 7:export const MAX_SAMPLE_BYTES = 25 * 1024 * 1024;
- 8:export const MAX_TOTAL_SAMPLE_BYTES = 80 * 1024 * 1024;
- 9:export const ALLOWED_SAMPLE_MIME_TYPES = new Set([
- 17:export interface ChecklistItem {
- 26:export function estimateBase64Bytes(base64: string): number {
backend/supabase/functions/soundboard-delete/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
-
| 3:type DeleteTargetType = “clip” |
“category”; |
- 5:interface DeleteRequestBody {
- 12:interface DeleteArtifact {
- 19:interface DeleteArtifactFailure {
- 24:interface DeleteArtifactFailureRecord {
- 29:export interface SoundboardDeleteDeps {
- 47:const UUID_REGEX =
-
| 49:type CategoryDeleteMode = “delete_contents” |
“move_contents”; |
- 51:function parseDeleteBody(
backend/supabase/functions/soundboard-delete/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { normalizeStorageDeleteFailure } from “./delete_storage_error.ts”;
- 3:import { createSoundboardDeleteHandler } from “./handler.ts”;
- 5:const handleSoundboardDelete = createSoundboardDeleteHandler({
backend/supabase/functions/soundboard-delete/delete_storage_error.ts
- File type: TypeScript
- Ownership: backend function
- 1:interface StorageDeleteError {
- 6:export interface StorageDeleteFailure {
- 11:export function normalizeStorageDeleteFailure(error: StorageDeleteError | null): StorageDeleteFailure | null {
backend/supabase/functions/soundboard-delete/delete_storage_error_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { normalizeStorageDeleteFailure } from “./delete_storage_error.ts”;
backend/supabase/functions/soundboard-delete/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 21:function baseDeps(
backend/supabase/functions/soundboard-save-generated/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:interface SaveGeneratedBody {
- 16:interface ParsedSaveGeneratedBody {
- 29:interface SoundboardCategory {
- 34:interface StorageFailure {
- 39:interface StoredAudioTarget {
- 45:interface InsertClipRecord {
- 57:export interface SoundboardSaveGeneratedDeps {
- 82:const UUID_REGEX =
- 85:function workflowError(
backend/supabase/functions/soundboard-save-generated/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { createSoundboardSaveGeneratedHandler } from “./handler.ts”;
- 4:const SOUNDBOARD_BUCKET = “soundboard”;
- 6:function serviceClient() {
- 15:const handleSoundboardSaveGenerated = createSoundboardSaveGeneratedHandler({
backend/supabase/functions/soundboard-save-generated/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 5:import {
- 10:const userId = “aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa”;
- 11:const categoryId = “bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb”;
- 13:function makeRequest(body: Record<string, unknown>, auth = “Bearer token”): Request {
- 24:function validBody(overrides: Record<string, unknown> = {}) {
- 52:function baseDeps(overrides: Partial = {}): SoundboardSaveGeneratedDeps {
- 67:async function expectWorkflowError(
backend/supabase/functions/tts-generate/policy_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
backend/supabase/functions/tts-generate/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import { validateTTSInputText } from “./policy.ts”;
- 4:export interface TTSAuthUser {
- 9:export type TTSGenerationOutcome =
- 15:export interface TTSGenerateDeps {
- 26:type TTSErrorCode =
- 37:function ttsErrorResponse(
- 56:function sanitizeProviderDetails(details: string): string {
- 67:export function createTTSGenerateHandler(deps: TTSGenerateDeps) {
backend/supabase/functions/tts-generate/pronunciation.ts
- File type: TypeScript
- Ownership: backend function
- 1:const PRONUNCIATION_DICTIONARY_SUPPORTED_MODEL_IDS = new Set([
- 6:export function modelSupportsPronunciationDictionary(
backend/supabase/functions/tts-generate/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import type { SupabaseClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 3:import {
- 7:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 8:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 9:import { resolvePrivateVoiceAccess } from “../_shared/private-voice-access.ts”;
- 10:import {
- 19:import {
- 23:import type { TTSRequest } from “../_shared/types.ts”;
- 24:import {
backend/supabase/functions/tts-generate/pronunciation_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { modelSupportsPronunciationDictionary } from “./pronunciation.ts”;
backend/supabase/functions/tts-generate/policy.ts
- File type: TypeScript
- Ownership: backend function
- 1:export const MAX_TTS_TEXT_LENGTH = 5000;
- 3:export function validateTTSInputText(
- 22:export function isTTSQuotaExceeded(
- 30:export function evaluateRestrictedVoiceAccess(
backend/supabase/functions/tts-generate/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 5:import { createTTSGenerateHandler, type TTSGenerateDeps } from “./handler.ts”;
- 7:function makeRequest(
- 21:function makeRawRequest(
- 36:function baseDeps(overrides: Partial = {}): TTSGenerateDeps {
- 48:function speechError(
backend/supabase/functions/sts-live-interpreter-session/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import {
- 6:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 7:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 8:import {
- 13:import {
- 16:import { getUsageCounter, getUsageTotal } from “../_shared/usage.ts”;
- 17:import {
- 21:import {
- 27:const STT_TOKEN_URL =
backend/supabase/functions/sts-live-interpreter-tts-session/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import {
- 6:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 7:import {
- 12:const TTS_TOKEN_URL =
- 14:const TOKEN_EXPIRY_SECONDS = 15 * 60;
- 16:const supabaseUrl = Deno.env.get(“SUPABASE_URL”) ?? “”;
- 17:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”) ?? “”;
- 18:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”) ?? “”;
- 19:const liveInterpreterSTSEnabled =
backend/supabase/functions/voices-list/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import type { PlanTier } from “../_shared/types.ts”;
- 4:const DEFAULT_PROVIDER_CATEGORIES = new Set([””, “premade”, “professional”]);
- 6:export interface VoicesListAuthUser {
- 11:export interface PrivateVoiceAccessPayload {
- 16:export interface OwnedVoiceMetadata {
- 22:export interface ProviderCatalogResult {
- 29:export interface VoicesListDeps {
- 39:function extractVoiceId(voice: unknown): string {
- 46:function extractVoiceCategory(voice: unknown): string {
backend/supabase/functions/voices-list/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { getPlatformElevenLabsKey } from “../_shared/byok.ts”;
- 3:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 4:import { resolvePrivateVoiceAccess } from “../_shared/private-voice-access.ts”;
- 5:import { periodKeyForTier } from “../_shared/quotas.ts”;
- 6:import { recordUsage } from “../_shared/usage.ts”;
- 7:import { createVoicesListHandler } from “./handler.ts”;
- 9:const ELEVENLABS_VOICES_URL = “https://api.elevenlabs.io/v1/voices”;
- 10:const PROVIDER = “elevenlabs”;
- 12:interface OwnedVoiceRow {
backend/supabase/functions/voices-list/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createVoicesListHandler, type VoicesListDeps } from “./handler.ts”;
- 4:function makeRequest(auth = “Bearer token”): Request {
- 11:function baseDeps(overrides: Partial = {}): VoicesListDeps {
backend/supabase/functions/billing-apple-notifications/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export type NotificationEnvelope = {
- 7:export type AppleServerTransaction = {
- 19:export type ApplyMutationResult = {
- 29:export type BillingAppleNotificationsDeps = {
- 47:export function createBillingAppleNotificationsHandler(deps: BillingAppleNotificationsDeps) {
backend/supabase/functions/sts-near-realtime-session/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
-
| 3:export type STSNearRealtimeClientPlatform = “ios” |
“android” |
“web”; |
- 4:export type STSNearRealtimeAudioFormat = “pcm_16000”;
-
| 5:export type STSRealtimeWorkflowMode = “near_realtime” |
“live_interpreter”; |
- 7:export interface STSNearRealtimeAuthUser {
- 12:export interface STSNearRealtimeSessionRequest {
- 31:export type STSNearRealtimeSessionOutcome =
- 49:export interface STSNearRealtimeSessionDeps {
- 60:export interface STSNearRealtimeSessionHandlerOptions {
- 65:const DEFAULT_DURATION_MS = 30_000;
backend/supabase/functions/billing-apple-notifications/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import {
- 7:import { createBillingAppleNotificationsHandler } from “./handler.ts”;
- 9:const APPLE_PRODUCTION_API = “https://api.storekit.itunes.apple.com”;
- 10:const APPLE_SANDBOX_API = “https://api.storekit-sandbox.itunes.apple.com”;
- 12:const ALLOWED_PRODUCTS = new Set([
- 19:const UUID_PATTERN =
- 22:type AppleServerTransaction = {
- 34:function toBase64Url(data: Uint8Array): string {
- 39:function utf8ToBase64Url(value: string): string {
backend/supabase/functions/billing-apple-notifications/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:const transaction = {
- 19:function request(body: unknown): Request {
- 27:const baseDeps: BillingAppleNotificationsDeps = {
backend/supabase/functions/_shared/billing-entitlement-policy_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { shouldApplyEntitlementMutation } from “./billing-entitlement-policy.ts”;
backend/supabase/functions/_shared/user_defaults.ts
- File type: TypeScript
- Ownership: backend function
- 6:export const DEFAULT_MODEL_ID = “eleven_v3”;
backend/supabase/functions/_shared/billing-entitlement-policy.ts
- File type: TypeScript
- Ownership: backend function
- 1:export type BillingEntitlementSource =
-
| 9:export type MutationDecision = “apply” |
“ignore” |
“duplicate”; |
- 11:export type MutationDecisionReason =
- 16:export interface EntitlementSnapshot {
- 22:export interface IncomingEntitlementMutation {
- 29:export interface ShouldApplyEntitlementMutationInput {
- 37:export interface EntitlementMutationDecision {
- 46:const SOURCE_PRECEDENCE: Record<string, number> = {
- 54:const ACTIVE_STATUSES = new Set([“active”, “trialing”, “past_due”, “pending”]);
- 56:function sourcePrecedence(source: BillingEntitlementSource): number {
backend/supabase/functions/_shared/byok_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { fetchByokStatus, resolveElevenLabsApiKey } from “./byok.ts”;
- 4:type QueryResult = { data: unknown; error: unknown };
- 6:type SelectCall = {
- 12:function createFakeClient(selectQueue: Record<string, QueryResult[]>) {
backend/supabase/functions/_shared/auth-context_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { resolveAuthenticatedUser } from “./auth-context.ts”;
backend/supabase/functions/_shared/cors.ts
- File type: TypeScript
- Ownership: backend function
- 1:export const corsHeaders = {
- 6:export function jsonResponse(body: unknown, status = 200): Response {
backend/supabase/functions/_shared/theme.ts
- File type: TypeScript
- Ownership: backend function
- 1:export const DEFAULT_THEME_ID = “pear_meadow”;
- 3:export const IOS_THEME_IDS = [
- 17:const VALID_THEME_IDS = new Set(IOS_THEME_IDS);
- 19:export function normalizeThemeId(themeId: unknown): string {
backend/supabase/functions/_shared/byok.ts
- File type: TypeScript
- Ownership: backend function
- 1:const BYOK_PROVIDER = “elevenlabs”;
-
| 3:type KeySource = “byok” |
“platform”; |
- 5:type ByokServiceClient = {
- 9:interface ByokRow {
- 15:export interface ResolvedProviderKey {
- 21:function bytesToBase64(bytes: Uint8Array): string {
- 29:function base64ToBytes(base64: string): Uint8Array {
- 38:function cloneBytes(bytes: Uint8Array): Uint8Array {
- 44:function bytesToArrayBuffer(bytes: Uint8Array): ArrayBuffer {
- 49:async function deriveAesKey(secret: string): Promise {
backend/supabase/functions/_shared/entitlements_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { resolveEntitlement } from “./entitlements.ts”;
- 4:type QueryResult = { data: unknown; error: unknown };
- 6:type SelectCall = {
- 12:type UpsertCall = {
- 17:function createFakeClient(options: {
backend/supabase/functions/_shared/subscription-gating-config_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 16:type QueryResult = { data: unknown; error: unknown };
- 18:type SelectCall = {
- 24:function createFakeClient(result: QueryResult) {
backend/supabase/functions/_shared/types.ts
- File type: TypeScript
- Ownership: backend function
-
| 1:export type PlanTier = “free” |
“pro” |
“trial” |
“admin”; |
- 3:export interface Entitlement {
- 9:export interface TTSRequest {
- 23:export interface QuotaDecision {
-
| 30:export type VoiceCloneSampleSource = “recorded” |
“uploaded”; |
- 32:export interface VoiceCloneSampleInput {
- 40:export interface VoiceCloneCreateRequest {
- 47:export interface VoiceCloneCreateResponse {
- 55:export interface VoiceCloneDeleteRequest {
- 59:export interface VoiceCloneDeleteResponse {
backend/supabase/functions/_shared/entitlements.ts
- File type: TypeScript
- Ownership: backend function
- 1:import type { Entitlement } from “./types.ts”;
- 3:type EntitlementServiceClient = {
- 7:const ACTIVE_STATUSES = new Set([“active”, “trialing”]);
- 9:type AppleSubscriptionRow = {
-
| 16:function isFutureDate(value: string |
null): boolean { |
-
| 23:function hasActiveAppleSubscription(subscription: AppleSubscriptionRow |
null): boolean { |
- 35:export async function resolveEntitlement(
backend/supabase/functions/_shared/auth-context.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 3:export interface AuthenticatedUser {
- 8:interface AuthUserLike {
- 13:interface AuthResultLike {
- 20:interface AuthClientLike {
- 26:interface ResolveAuthenticatedUserArgs {
- 37:export async function resolveAuthenticatedUser(
backend/supabase/functions/_shared/private-voice-access_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals, assertRejects } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { resolvePrivateVoiceAccess } from “./private-voice-access.ts”;
- 4:type QueryResult = { data: unknown; error: unknown };
- 6:type QueryCall = {
- 12:function createFakeClient(queueByTable: Record<string, QueryResult[]>) {
backend/supabase/functions/sts-near-realtime-session/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import {
- 6:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 7:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 8:import {
- 13:import {
- 16:import { getUsageCounter, getUsageTotal } from “../_shared/usage.ts”;
- 17:import {
- 21:import {
- 27:const STT_TOKEN_URL =
backend/supabase/functions/_shared/private-voice-access.ts
- File type: TypeScript
- Ownership: backend function
- 1:type PrivateVoiceAccessClient = {
- 5:type PrivateVoiceControlRow = {
- 9:type PrivateVoiceUserAccessRow = {
- 13:export type PrivateVoiceAccess = {
- 18:export async function resolvePrivateVoiceAccess(
backend/supabase/functions/sts-near-realtime-session/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 24:function makeRawRequest(
- 45:function validBody(overrides: Record<string, unknown> = {}) {
- 66:function baseDeps(
backend/supabase/functions/_shared/usage.ts
- File type: TypeScript
- Ownership: backend function
- 1:type UsageServiceClient = {
- 6:interface CounterRow {
- 11:export async function getUsageCounter(
- 34:export async function getUsageTotal(
- 49:export async function incrementUsageCounter(
- 67:export async function recordUsage(
- 89:export async function recordUsageAcrossPeriods(
- 120:export async function recordUsageEvent(
- 138:export async function recordStreamEvent(
backend/supabase/functions/_shared/subscription-gating-config.ts
- File type: TypeScript
- Ownership: backend function
- 1:import type { PlanTier } from “./types.ts”;
-
| 3:export type SubscriptionGatingMode = “disabled” |
“enabled”; |
-
| 4:export type SubscriptionGateDiagnosticSeverity = “info” |
“error”; |
-
| 5:export type TierLimitMap = Record<PlanTier, number |
null>; |
- 7:export interface SubscriptionGateDiagnostic {
- 12:export interface SubscriptionGatingConfig {
- 34:export interface SubscriptionGatingConfigError {
- 42:export type SubscriptionGatingConfigResult =
- 46:type SubscriptionGatingServiceClient = {
- 58:export const SUBSCRIPTION_GATING_CONFIG_TABLE = “subscription_gating_config”;
backend/supabase/functions/_shared/usage_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 11:type QueryResult = { data: unknown; error: unknown };
- 13:type SelectCall = {
- 19:type InsertCall = {
- 24:type RpcCall = {
- 29:function createFakeClient(options: {
backend/supabase/functions/_shared/quotas_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 10:import {
- 20:function enabledConfig(
backend/supabase/functions/_shared/quotas.ts
- File type: TypeScript
- Ownership: backend function
- 1:import type {
- 5:import type { PlanTier, QuotaDecision } from “./types.ts”;
- 7:const FREE_DAILY_TTS_CHAR_LIMIT = 1_000;
- 8:const PRO_DAILY_TTS_CHAR_LIMIT = 5_000;
- 9:const TRIAL_DAILY_TTS_CHAR_LIMIT = 2_000;
- 10:const ADMIN_TTS_CHAR_LIMIT = Number.MAX_SAFE_INTEGER;
- 12:export function periodKeyForTier(_tier: PlanTier, now = new Date()): string {
- 19:export function monthlyPeriodKey(now = new Date()): string {
- 25:function legacyTTSLimitForTier(tier: PlanTier): number {
- 39:function limitForTier(tier: PlanTier, limits: TierLimitMap): number | null {
backend/supabase/functions/sts-realtime-finalize/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface STSRealtimeFinalizeAuthUser {
- 8:export interface STSRealtimeFinalizeRequest {
- 28:export type STSRealtimeFinalizeOutcome =
- 49:export interface STSRealtimeFinalizeDeps {
- 61:const UUID_PATTERN =
- 63:const MAX_TRANSCRIPT_LENGTH = 5000;
- 64:const MAX_AUDIO_BYTES = 20 * 1024 * 1024;
- 65:const MAX_DURATION_MS = 300_000;
- 66:const MAX_LIVE_SEGMENT_COUNT = 1000;
backend/supabase/functions/voice-clone-create/telemetry_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { voiceCloneAttemptEvent, voiceCloneFailureEvent, voiceCloneSuccessEvent } from “./telemetry.ts”;
backend/supabase/functions/voice-clone-delete/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import {
- 7:export interface AuthUser {
- 12:export interface OwnedVoice {
- 16:export interface ProviderDeleteResult {
- 22:export interface VoiceCloneDeleteDeps {
- 37:const PROVIDER = “elevenlabs”;
- 39:export function createVoiceCloneDeleteHandler(deps: VoiceCloneDeleteDeps) {
backend/supabase/functions/sts-realtime-finalize/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 3:import { getPlatformElevenLabsKey } from “../_shared/byok.ts”;
- 4:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 5:import {
- 10:import { resolveSubscriptionGatingConfig } from “../_shared/subscription-gating-config.ts”;
- 11:import {
- 16:import {
- 20:import {
- 26:const supabaseUrl = Deno.env.get(“SUPABASE_URL”) ?? “”;
backend/supabase/functions/sts-realtime-finalize/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:const VALID_SESSION_ID = “11111111-1111-4111-8111-111111111111”;
- 9:function validBody(
- 28:function makeRequest(
- 42:function makeRawRequest(
- 60:function baseDeps(
backend/supabase/functions/sts-live-voice-tts-session/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface STSLiveVoiceTTSAuthUser {
- 8:export interface STSLiveVoiceTTSSessionRequest {
- 23:export type STSLiveVoiceTTSSessionOutcome =
- 35:export interface STSLiveVoiceTTSSessionDeps {
- 46:export interface STSLiveVoiceTTSSessionHandlerOptions {
- 50:const UUID_PATTERN =
- 52:const TTS_WS_BASE_URL = “wss://api.elevenlabs.io/v1/text-to-speech”;
- 54:function sanitizeProviderDetails(details: string): string {
- 65:function normalizeLanguageCode(value: unknown): string | null {
backend/supabase/functions/byok-upsert/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:interface ByokUpsertPayload {
- 8:export interface ByokUpsertAuthUser {
- 13:export interface ByokUpsertDeps {
- 20:export function createByokUpsertHandler(deps: ByokUpsertDeps) {
backend/supabase/functions/sts-live-voice-tts-session/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import {
- 6:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 7:import {
- 12:const TTS_TOKEN_URL =
- 14:const TOKEN_EXPIRY_SECONDS = 15 * 60;
- 16:const supabaseUrl = Deno.env.get(“SUPABASE_URL”) ?? “”;
- 17:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”) ?? “”;
- 18:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”) ?? “”;
- 19:const nearRealtimeSTSEnabled =
backend/supabase/functions/byok-upsert/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { setByokEnabled, upsertByokCredential } from “../_shared/byok.ts”;
- 3:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 4:import { createByokUpsertHandler } from “./handler.ts”;
- 6:const handleByokUpsert = createByokUpsertHandler({
backend/supabase/functions/sts-live-voice-tts-session/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 24:function makeRawRequest(
- 45:function validBody(overrides: Record<string, unknown> = {}) {
- 63:function baseDeps(
backend/supabase/functions/byok-upsert/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createByokUpsertHandler, type ByokUpsertDeps } from “./handler.ts”;
- 4:function makeRequest(body: Record<string, unknown>, auth = “Bearer token”): Request {
- 15:function baseDeps(overrides: Partial = {}): ByokUpsertDeps {
backend/supabase/functions/voice-clone-create/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import type { VoiceCloneCreateRequest } from “../_shared/types.ts”;
- 4:export interface VoiceCloneCreateAuthUser {
- 9:export type VoiceCloneCreateOutcome =
- 14:export interface VoiceCloneCreateDeps {
- 24:export function createVoiceCloneCreateHandler(deps: VoiceCloneCreateDeps) {
backend/supabase/functions/voice-clone-create/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { getPlatformElevenLabsKey } from “../_shared/byok.ts”;
- 3:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 4:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 5:import type {
- 9:import { recordUsageEvent } from “../_shared/usage.ts”;
- 10:import {
- 14:import {
- 22:import {
- 28:const ELEVENLABS_CLONE_CREATE_URL = “https://api.elevenlabs.io/v1/voices/add”;
backend/supabase/functions/voice-clone-create/telemetry.ts
- File type: TypeScript
- Ownership: backend function
- 1:export function voiceCloneAttemptEvent(voiceName: string, sampleCount: number): Record<string, unknown> {
- 9:export function voiceCloneFailureEvent(
- 20:export function voiceCloneSuccessEvent(
backend/supabase/functions/voice-clone-create/validation_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 5:import type { VoiceCloneSampleInput } from “../_shared/types.ts”;
- 6:import {
backend/supabase/functions/voice-clone-create/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 21:function baseDeps(
backend/supabase/functions/voice-clone-create/validation.ts
- File type: TypeScript
- Ownership: backend function
- 1:import type { VoiceCloneSampleInput, VoiceCloneSampleSource } from “../_shared/types.ts”;
- 3:export const MIN_SAMPLE_COUNT = 1;
- 4:export const MAX_SAMPLE_COUNT = 20;
- 5:export const MIN_SAMPLE_DURATION_SECONDS = 30;
- 6:export const MAX_SAMPLE_DURATION_SECONDS = 45 * 60;
- 7:export const MAX_SAMPLE_BYTES = 25 * 1024 * 1024;
- 8:export const MAX_TOTAL_SAMPLE_BYTES = 80 * 1024 * 1024;
- 9:export const ALLOWED_SAMPLE_MIME_TYPES = new Set([
- 17:export type NormalizeSampleResult =
- 27:function base64ToBytes(base64: string): Uint8Array {
backend/supabase/functions/style-presets/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { SupabaseClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 5:interface StylePresetRow {
- 19:interface CreatePresetBody {
- 29:interface UpdatePresetBody extends CreatePresetBody {
- 33:interface DeletePresetBody {
- 38:function toClientPreset(row: StylePresetRow) {
- 53:function parseJson(input: string): T | null {
-
| 61:function assertRange(value: number, min: number, max: number, field: string): string |
null { |
- 68:export type SupabaseClientFactory = (token: string) => SupabaseClient;
backend/supabase/functions/billing-google-play-sync/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import {
- 6:import type { GoogleVerificationResult } from “./google-play-verifier.ts”;
- 8:export type GooglePlaySyncPayload = {
- 18:type GoogleSyncEntitlementStatus = {
- 25:export interface GooglePlaySyncHandlerDeps {
- 52:const ALLOWED_PRODUCTS = new Set([
-
| 59:function parsePayload(value: unknown): GooglePlaySyncPayload |
null { |
- 87:function entitlementFromVerification(result: Extract<GoogleVerificationResult, { ok: true }>): GoogleSyncEntitlementStatus {
- 114:function sourceEventId(payload: GooglePlaySyncPayload): string {
backend/supabase/functions/user-settings-get/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface UserSettingsGetDeps {
-
| 38:function optionalText(value: unknown): string |
null { |
- 42:export function createUserSettingsGetHandler(deps: UserSettingsGetDeps) {
backend/supabase/functions/user-settings-get/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 3:import { normalizeThemeId } from “../_shared/theme.ts”;
- 4:import { createUserSettingsGetHandler } from “./handler.ts”;
- 6:const supabaseUrl = Deno.env.get(“SUPABASE_URL”) ?? “”;
- 7:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”) ?? “”;
- 8:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”) ?? “”;
- 10:const adminClient = createClient(supabaseUrl, supabaseServiceRoleKey);
- 12:const handleUserSettingsGet = createUserSettingsGetHandler({
backend/supabase/functions/user-settings-get/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(auth = “Bearer token”): Request {
- 14:function baseDeps(
- 30:const STS_OVERRIDE_NULLS = {
backend/supabase/functions/billing-google-play-sync/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createGooglePlaySyncHandler, type GooglePlaySyncHandlerDeps } from “./handler.ts”;
- 4:function makeRequest(body: Record<string, unknown>): Request {
- 15:function validBody(overrides: Record<string, unknown> = {}): Record<string, unknown> {
- 28:function baseDeps(overrides: Partial = {}): GooglePlaySyncHandlerDeps {
backend/supabase/functions/voice-clone-delete/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { getPlatformElevenLabsKey } from “../_shared/byok.ts”;
- 3:import { recordUsageEvent } from “../_shared/usage.ts”;
- 4:import { createVoiceCloneDeleteHandler } from “./handler.ts”;
- 6:const PROVIDER = “elevenlabs”;
- 8:const handleVoiceCloneDelete = createVoiceCloneDeleteHandler({
backend/supabase/functions/voice-clone-delete/validation_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
backend/supabase/functions/voice-clone-delete/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 21:function baseDeps(
backend/supabase/functions/voice-clone-delete/validation.ts
- File type: TypeScript
- Ownership: backend function
-
| 1:export function normalizeVoiceId(payload: { voiceId?: string |
null }): string { |
- 5:export function classifyProviderDeleteResult(status: number): “ok” | “provider_error” {
backend/supabase/functions/billing-google-play-sync/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 3:import { createGooglePlayVerifier } from “./google-play-verifier.ts”;
- 4:import { createGooglePlaySyncHandler } from “./handler.ts”;
- 6:const handleGooglePlaySync = createGooglePlaySyncHandler({
backend/supabase/functions/billing-google-play-sync/google-play-verifier.ts
- File type: TypeScript
- Ownership: backend function
-
| 1:export type GoogleVerificationState = “active” |
“expired” |
“pending” |
“canceled”; |
- 3:export type GoogleVerificationFailureReason =
- 10:export type GoogleVerificationResult =
- 25:interface VerifySubscriptionPurchaseTokenInput {
- 31:interface GooglePlayVerifier {
- 35:interface GooglePlayVerifierDeps {
- 40:function toBase64Url(data: Uint8Array): string {
- 45:function utf8ToBase64Url(value: string): string {
- 49:function parsePrivateKey(raw: string): string {
- 53:function parsePkcs8(pemKey: string): ArrayBuffer {
backend/supabase/functions/billing-google-play-sync/google-play-verifier_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createGooglePlayVerifier } from “./google-play-verifier.ts”;
- 4:function okJson(body: unknown): Response {
backend/supabase/functions/style-presets/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { createStylePresetsHandler } from “./handler.ts”;
- 4:const supabaseUrl = Deno.env.get(“SUPABASE_URL”);
- 5:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”);
- 6:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”);
- 14:const createUserServiceClient = (token: string) => {
- 20:const createAdminServiceClient = () => {
- 24:const handleStylePresets = createStylePresetsHandler(
backend/supabase/functions/style-presets/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.177.0/testing/asserts.ts”;
- 2:import { SupabaseClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 3:import { createStylePresetsHandler } from “./handler.ts”;
- 5:const MOCK_USER = { id: “user-123”, email: “test@example.com” };
- 6:const MOCK_AUTH_HEADER = “Bearer mock-token”;
- 10:const createMockSupabaseClient = (config: {
backend/supabase/functions/byok-resolve/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface ByokResolveAuthUser {
- 8:export interface ByokResolveStatus {
- 13:export interface ByokResolveDeps {
- 19:export function createByokResolveHandler(deps: ByokResolveDeps) {
backend/supabase/functions/byok-resolve/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { fetchByokStatus } from “../_shared/byok.ts”;
- 3:import { createByokResolveHandler } from “./handler.ts”;
- 5:const handleByokResolve = createByokResolveHandler({
backend/supabase/functions/byok-resolve/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createByokResolveHandler, type ByokResolveDeps } from “./handler.ts”;
- 4:function makeRequest(auth = “Bearer token”): Request {
- 11:function baseDeps(overrides: Partial = {}): ByokResolveDeps {
backend/supabase/functions/pronunciation-dictionary/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { SupabaseClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 4:interface DictionaryRow {
- 16:interface CreateEntryBody {
- 24:interface UpdateEntryBody extends CreateEntryBody {
- 28:interface DeleteEntryBody {
- 32:const MAX_ENTRIES_PER_USER = 500;
- 33:const MAX_TERM_LENGTH = 120;
- 34:const MAX_REPLACEMENT_LENGTH = 300;
- 36:function toClientEntry(row: DictionaryRow) {
backend/supabase/functions/pronunciation-dictionary/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { createPronunciationDictionaryHandler } from “./handler.ts”;
- 4:const supabaseUrl = Deno.env.get(“SUPABASE_URL”);
- 5:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”);
- 6:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”);
- 12:const createUserServiceClient = (token: string) => {
- 18:const createAdminServiceClient = () => {
- 22:const handlePronunciationDictionary = createPronunciationDictionaryHandler(
backend/supabase/functions/pronunciation-dictionary/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.177.0/testing/asserts.ts”;
- 2:import { SupabaseClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 3:import { createPronunciationDictionaryHandler } from “./handler.ts”;
- 5:const MOCK_USER = { id: “user-123”, email: “test@example.com” };
- 6:const MOCK_AUTH_HEADER = “Bearer mock-token”;
- 8:const createMockSupabaseClient = (config: {
backend/supabase/functions/models-list/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import type { PlanTier } from “../_shared/types.ts”;
- 4:export interface ModelsListAuthUser {
- 9:export interface ProviderModelsResult {
- 16:export interface ModelsListDeps {
- 24:export function createModelsListHandler(deps: ModelsListDeps) {
backend/supabase/functions/models-list/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 3:import { periodKeyForTier } from “../_shared/quotas.ts”;
- 4:import { recordUsage } from “../_shared/usage.ts”;
- 5:import { createModelsListHandler } from “./handler.ts”;
- 7:const ELEVENLABS_MODELS_URL = “https://api.elevenlabs.io/v1/models”;
- 9:const handleModelsList = createModelsListHandler({
backend/supabase/functions/models-list/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createModelsListHandler, type ModelsListDeps } from “./handler.ts”;
- 4:function makeRequest(auth = “Bearer token”): Request {
- 11:function baseDeps(overrides: Partial = {}): ModelsListDeps {
backend/supabase/functions/billing-stripe-webhook/persistence.ts
- File type: TypeScript
- Ownership: backend function
- 1:export interface EventInsertErrorLike {
- 6:export function isDuplicateEventInsertError(error: EventInsertErrorLike): boolean {
backend/supabase/functions/billing-stripe-webhook/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient, type SupabaseClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:import {
- 8:import { shouldApplyEntitlementMutation } from “../_shared/billing-entitlement-policy.ts”;
- 9:import {
- 13:import { verifyStripeSignature } from “./signature.ts”;
- 14:import { routeStripeEventType } from “./dispatch.ts”;
- 15:import { isDuplicateEventInsertError } from “./persistence.ts”;
-
| 17:type BillingEventStatus = “received” |
“processed” |
“ignored” |
“failed”; |
- 19:interface StripeEvent {
backend/supabase/functions/billing-stripe-webhook/dispatch_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { routeStripeEventType } from “./dispatch.ts”;
backend/supabase/functions/billing-stripe-webhook/dispatch.ts
- File type: TypeScript
- Ownership: backend function
- 1:export const SUPPORTED_EVENTS = new Set([
-
| 8:export type StripeEventRoute = “checkout” |
“subscription” |
“unsupported”; |
- 10:export function routeStripeEventType(eventType: string): StripeEventRoute {
backend/supabase/functions/billing-stripe-webhook/persistence_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { isDuplicateEventInsertError } from “./persistence.ts”;
backend/supabase/functions/billing-stripe-webhook/logic.ts
- File type: TypeScript
- Ownership: backend function
- 1:export interface ExistingEntitlementLike {
- 7:const SOURCE_PRECEDENCE: Record<string, number> = {
- 15:export function isIncomingEventOutOfOrder(
- 28:export function hasActiveHigherPrecedenceEntitlementAt(
- 45:export function hasActiveAppleEntitlementAt(
- 52:export function resolveStripeEventResult(args: {
backend/supabase/functions/billing-stripe-webhook/logic_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 5:import {
backend/supabase/functions/billing-stripe-webhook/signature_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
backend/supabase/functions/billing-stripe-webhook/validation_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
backend/supabase/functions/billing-stripe-webhook/signature.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { parseStripeSignatureHeader } from “./validation.ts”;
- 3:export function timingSafeEqualHex(a: string, b: string): boolean {
- 12:export async function hmacSha256Hex(secret: string, payload: string): Promise {
- 26:export async function verifyStripeSignature(
backend/supabase/functions/billing-stripe-webhook/validation.ts
- File type: TypeScript
- Ownership: backend function
- 1:export interface StripeEventLike {
-
| 10:export function parseStripeSignatureHeader(signatureHeader: string): { timestamp: string; signatures: string[] } |
null { |
-
| 24:export function asDateFromUnixSeconds(value: unknown): string |
null { |
- 29:export function validateStripeEventPayload(
backend/supabase/functions/bug-report-submit/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface BugReportInsertInput {
- 16:export interface StoredBugReport {
- 21:export interface EmailInput {
- 29:export interface EmailSendResult {
- 33:export interface BugReportSubmitDeps {
- 48:interface BugReportBody {
- 58:const EMAIL_REGEX = /^[^\s@]+@[^\s@]+.[^\s@]+$/;
- 60:function trimString(value: unknown): string {
- 64:function nullableTrimmedString(value: unknown, maxLength: number): string | null {
backend/supabase/functions/bug-report-submit/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 3:import { createBugReportSubmitHandler } from “./handler.ts”;
- 5:const supabaseUrl = Deno.env.get(“SUPABASE_URL”) ?? “”;
- 6:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”) ?? “”;
- 7:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”) ?? “”;
- 8:const mailtrapApiToken = Deno.env.get(“MAILTRAP_API_TOKEN”) ?? “”;
- 10:const adminClient = createClient(supabaseUrl, supabaseServiceRoleKey);
- 12:function parseRecipients(): string[] {
- 19:async function sendMailtrapEmail(input: {
backend/supabase/functions/bug-report-submit/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 21:function baseDeps(
backend/supabase/functions/account-delete/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import {
- 5:import { createAccountDeleteHandler } from “./handler.ts”;
- 7:function createRequest(authHeader?: string | null): Request {
backend/supabase/functions/waitlist-signup/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createWaitlistSignupHandler, type WaitlistSignupDeps } from “./handler.ts”;
- 4:function makeRequest(body: Record<string, unknown>): Request {
- 15:function baseDeps(overrides: Partial = {}): WaitlistSignupDeps {
backend/supabase/functions/waitlist-signup/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient, SupabaseClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 4:const EMAIL_REGEX = /^[^\s@]+@[^\s@]+.[^\s@]+$/;
- 6:export interface WaitlistInsertInput {
- 15:export interface WaitlistSignupDeps {
- 20:interface WaitlistBody {
- 27:function normalizeEmail(input: string): string {
- 31:function safeObject(value: unknown): Record<string, unknown> {
-
| 38:async function hashUserAgent(userAgent: string): Promise<string |
null> { |
- 49:async function getUserIdFromAuth(
backend/supabase/functions/account-delete/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface AccountDeleteAuthUser {
- 8:export interface AccountDeleteDeps {
- 14:export function createAccountDeleteHandler(deps: AccountDeleteDeps) {
backend/supabase/functions/waitlist-signup/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { createWaitlistSignupHandler } from “./handler.ts”;
- 4:const handleWaitlistSignup = createWaitlistSignupHandler({
backend/supabase/functions/account-delete/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { createAccountDeleteHandler } from “./handler.ts”;
- 4:const handleAccountDelete = createAccountDeleteHandler({
backend/supabase/functions/sts-realtime-session/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
-
| 3:export type STSRealtimeClientPlatform = “ios” |
“android” |
“web”; |
- 4:export type STSRealtimeAudioFormat = “pcm_16000”;
- 6:export interface STSRealtimeAuthUser {
- 11:export interface STSRealtimeSessionRequest {
- 18:export type STSRealtimeSessionOutcome =
- 30:export interface STSRealtimeSessionDeps {
- 41:const DEFAULT_DURATION_MS = 30_000;
- 42:const MAX_DURATION_MS = 300_000;
- 43:const REALTIME_MODEL_ID = “scribe_v2_realtime”;
backend/supabase/functions/sts-realtime-session/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import {
- 6:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 7:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 8:import {
- 13:import {
- 16:import { getUsageCounter, getUsageTotal } from “../_shared/usage.ts”;
- 17:import {
- 21:import {
- 27:const REALTIME_TOKEN_URL =
backend/supabase/functions/sts-realtime-session/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 21:function makeRawRequest(
- 39:function baseDeps(
backend/supabase/functions/clip-order-batch/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { createClipOrderBatchHandler, type ClipOrderItem, type FolderOrderItem } from “./handler.ts”;
- 4:const supabaseUrl = Deno.env.get(“SUPABASE_URL”);
- 5:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”);
- 6:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”);
backend/supabase/functions/clip-order-batch/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createClipOrderBatchHandler } from “./handler.ts”;
- 4:type OwnershipRow = { id: string };
-
| 6:function createRequest(body: unknown, authHeader?: string |
null): Request { |
- 19:const validIdA = “11111111-1111-4111-8111-111111111111”;
- 20:const validIdB = “22222222-2222-4222-8222-222222222222”;
backend/supabase/functions/clip-order-batch/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface ClipOrderItem {
- 9:export interface FolderOrderItem {
- 15:export interface ClipOrderBatchAuthUser {
- 19:export interface ClipOrderBatchDeps {
- 37:function isUUID(value: string): boolean {
- 41:export function createClipOrderBatchHandler(deps: ClipOrderBatchDeps) {
backend/supabase/functions/quota-status/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:export interface QuotaStatusAuthUser {
- 8:export interface FeatureQuotaStatus {
- 15:export interface QuotaStatusDeps {
- 27:export function createQuotaStatusHandler(deps: QuotaStatusDeps) {
backend/supabase/functions/language-recommend/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 3:const DEFAULT_PROVIDER_CATEGORIES = new Set([””, “premade”, “professional”]);
- 4:const PROVIDER = “elevenlabs”;
- 6:type RecommendRequest = {
- 11:type RecommendAuthUser = {
- 15:type ProviderResponse = {
- 21:type PrivateVoiceAccess = {
- 26:export type LanguageRecommendDeps = {
- 33:function detectLanguage(text: string): string {
- 48:function extractVoiceId(voice: unknown): string {
backend/supabase/functions/user-settings-update/handler.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { corsHeaders, jsonResponse } from “../_shared/cors.ts”;
- 2:import { normalizeThemeId } from “../_shared/theme.ts”;
- 4:interface UserSettingsPatch {
- 34:export interface UserSettingsUpdateDeps {
- 70:function readOptionalNumber(
- 89:function readOptionalBoolean(
- 112:function readOptionalNullableString(
- 134:function readOptionalNullableNumber(
- 156:function readOptionalNullableBoolean(
- 182:function optionalText(value: unknown): string | null {
backend/supabase/functions/quota-status/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { resolveEntitlement } from “../_shared/entitlements.ts”;
- 3:import { periodKeyForTier, ttsLimitForTier } from “../_shared/quotas.ts”;
- 4:import { resolveSubscriptionGatingConfig } from “../_shared/subscription-gating-config.ts”;
- 5:import { getUsageCounter } from “../_shared/usage.ts”;
- 6:import { sttLimitForTier } from “../stt-transcribe/validation.ts”;
- 7:import { createQuotaStatusHandler } from “./handler.ts”;
- 9:const handleQuotaStatus = createQuotaStatusHandler({
backend/supabase/functions/user-settings-update/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { resolveAuthenticatedUser } from “../_shared/auth-context.ts”;
- 3:import { DEFAULT_MODEL_ID } from “../_shared/user_defaults.ts”;
- 4:import { normalizeThemeId } from “../_shared/theme.ts”;
- 5:import { createUserSettingsUpdateHandler } from “./handler.ts”;
- 7:const supabaseUrl = Deno.env.get(“SUPABASE_URL”) ?? “”;
- 8:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”) ?? “”;
- 9:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”) ?? “”;
- 11:const adminClient = createClient(supabaseUrl, supabaseServiceRoleKey);
- 13:function patchHas(patch: object, key: string): boolean {
backend/supabase/functions/quota-status/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createQuotaStatusHandler, type QuotaStatusDeps } from “./handler.ts”;
- 4:function makeRequest(auth = “Bearer token”): Request {
- 11:function baseDeps(overrides: Partial = {}): QuotaStatusDeps {
backend/supabase/functions/user-settings-update/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import {
- 7:function makeRequest(
- 21:function makeRawRequest(
- 40:function baseDeps(
- 56:const STS_OVERRIDE_NULLS = {
backend/supabase/functions/language-recommend/handler_test.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { assertEquals } from “https://deno.land/std@0.224.0/assert/mod.ts”;
- 2:import { createLanguageRecommendHandler } from “./handler.ts”;
-
| 4:function jsonRequest(body: unknown, authHeader?: string |
null): Request { |
- 17:const baseDeps = {
backend/supabase/functions/language-recommend/index.ts
- File type: TypeScript
- Ownership: backend function
- 1:import { createClient } from “https://esm.sh/@supabase/supabase-js@2”;
- 2:import { getPlatformElevenLabsKey } from “../_shared/byok.ts”;
- 3:import { resolvePrivateVoiceAccess } from “../_shared/private-voice-access.ts”;
- 4:import { createLanguageRecommendHandler } from “./handler.ts”;
- 6:const ELEVENLABS_VOICES_URL = “https://api.elevenlabs.io/v1/voices”;
- 7:const PROVIDER = “elevenlabs”;
- 9:const supabaseUrl = Deno.env.get(“SUPABASE_URL”);
- 10:const supabaseAnonKey = Deno.env.get(“SUPABASE_ANON_KEY”);
- 11:const supabaseServiceRoleKey = Deno.env.get(“SUPABASE_SERVICE_ROLE_KEY”);
- 12:const elevenLabsApiKey = getPlatformElevenLabsKey();
Web (Marketing + legacy Python runtime)
For legacy runtime behavior beyond this declaration index, consult web/python-web-app/docs and repository-onboarding-reference.md.
web/python-web-app/docs/SOUNDBOARD_CATEGORY_AND_ORDERING.md
- File type: Other
web/python-web-app/docs/SUPABASE_EDGE_ROLLOUT.md
- File type: Other
web/python-web-app/docs/SUPABASE_MIGRATION_CONTRACT.md
- File type: Other
web/python-web-app/docs/SUPABASE_STRICT_TEST_PLAN.md
- File type: Other
web/python-web-app/pytest.ini
- File type: Other
web/python-web-app/Dockerfile
- File type: Other
web/python-web-app/gb_tts_app.py
- File type: Python
- 9:import sys
- 12:if name == “main”:
- 13: from src import legacy_runtime as _legacy_runtime
- 24: from src import legacy_runtime as _legacy_runtime
web/python-web-app/requirements.txt
- File type: Other
web/python-web-app/import_glossary.py
- File type: Python
- 9:import os
- 10:import csv
- 11:import logging
- 12:import psycopg2
- 13:from psycopg2 import sql
- 14:from dotenv import load_dotenv
- 33:def create_table_if_not_exists(conn):
- 60:def import_data_from_csv(conn, csv_path):
web/python-web-app/static/js/index_speech.js
- File type: JavaScript
- 1: function updateSelectedModel(sourceType) {
- 25: function updatePronunciationStatus(isEnabled) {
- 53: function flattenSoundboardCategoryTargets(nodes, targets = [], depth = 0) {
- 81: function setCategoryDropdownOptions(categoryDropdown, options, emptyLabel) {
- 105: async function refreshSaveCategoryOptions({
- 150: function exposeTTSSoundboardWorkflowState() {
- 164: function clearLatestArtifact(reason) {
- 170: function setLatestArtifact(artifact) {
- 176: function soundboardToast(message, type, duration) {
- 186: function mergeAuthHeaders(extra) {
web/python-web-app/static/js/index_sts_live_voice.js
- File type: JavaScript
- 7: function decodeBase64ToBytes(base64) {
- 16: function pcm16Base64ToFloat32(base64) {
- 26: function openSocket(url) {
- 61: function buildSocketUrl(tts) {
- 78: function voiceSettingsFromSession(tts) {
- 88: async function createSTSLiveVoiceTTSPlayer(session, callbacks) {
- 111: function currentStats(status) {
- 123: function emitState(status) {
- 129: function wait(ms) {
- 133: function playAudioBase64(base64) {
web/python-web-app/static/js/index_voice_cloning.js
- File type: JavaScript
- 1: function initializeVoiceCloningTab() {
- 9: function mergeVoiceCloneAuthHeaders(extra) {
- 16: function resolveVoiceCloneAuthHeaders(extra) {
- 38: function getVoiceClonePreflightState() {
- 49: function computeUploadFingerprint() {
- 57: function invalidateVoiceClonePreflight(reasonText) {
- 73: function renderVoiceClonePreflightResult(result) {
- 100: function runVoiceClonePreflight() {
- 170: function customVoicesAuthKey(headers) {
- 177: function loadCustomVoices(options) {
web/python-web-app/static/js/deploy_refresh.js
- File type: JavaScript
- 14: function readCurrentVersion() {
- 24: function storageGet(storage, key) {
- 32: function storageSet(storage, key, value) {
- 40: function isStableDeployVersion(version) {
- 48: function currentUrlHasRefreshMarker(version) {
- 57: function samePathReload(version) {
- 73: function reloadForVersion(version) {
- 83: function rememberCurrentVersion(version) {
- 88: function readManifestVersion(payload) {
- 92: function pollManifest(manifestUrl, currentVersion) {
web/python-web-app/static/js/theme_boot.js
- File type: JavaScript
- 31: function normalizeThemeId(themeId) {
web/python-web-app/static/js/theme_catalog.js
- File type: JavaScript
- 24: function normalizeThemeId(themeId) {
- 35: function resolveEffectiveTheme(options) {
- 49: function readThemeFromLocalStorage() {
- 57: function attemptThemeLocalStorageWrite(themeId) {
- 67: function writeThemeToLocalStorage(themeId) {
- 71: function readAuthHeader() {
- 82: function isSignedIn() {
- 86: function parseHexColor(hexColor) {
- 98: function mixColors(hexA, hexB, ratio) {
- 108: function withAlpha(hexColor, alpha) {
web/python-web-app/static/js/email_sign_in.js
- File type: JavaScript
- 19: function getModal() {
- 22: function getForm() {
- 25: function getErrorEl() {
- 28: function getStatusEl() {
- 31: function getConfirmationEl() {
- 34: function getPasswordConfirmEl() {
- 37: function getPasswordRequirementsEl() {
- 40: function evaluateEmailPasswordRequirements(password) {
- 49: function findFirstMissingEmailPasswordRequirement(password) {
- 53: function updateEmailPasswordRequirements(password) {
web/python-web-app/static/js/index_core.js
- File type: JavaScript
- 1:function mergeSupabaseAuthHeaders(extra) {
- 11: function themeColor(variableName, fallback) {
- 51: function resolveThemeToken(tokenKey) {
- 79: function refreshUiThemeTokens() {
- 151: function initAIDataSharingAgreementGate() {
- 174: function setError(message) {
- 180: function setGateMode(mode) {
- 192: function updateSettingsAccessClass() {
- 198: function openSettingsTab() {
- 206: function resetNoticeScroll() {
web/python-web-app/static/js/index_settings.js
- File type: JavaScript
- 14: function isWebSubscriptionUIEnabled() {
- 18: function readSupabaseJwtEmail() {
- 40: function _resolveSignedInUserLabelFromSessionUser(user) {
- 53: function refreshAllSessionUI() {
- 54: function updateSettingsHubAccountSubtitle(signedInLabel) {
- 64: function applySignedInState(label) {
- 145: function refreshSettingsAccountPanel() {
- 154: function showSettingsHub() {
- 167: function openSettingsSection(sectionId) {
- 208: function loadProSubscriptionStatusForSettings() {
web/python-web-app/static/js/index_soundboard.js
- File type: JavaScript
- 28: function getClipControlsPinnedPreference() {
- 36: function setClipControlsPinnedPreference(isPinned) {
- 46: function syncClipControlsPinnedState(isPinned) {
- 64: function initializeClipControlsPinToggle() {
- 78: function soundboardMediaCacheKey(categoryId, kind, filename) {
- 82: function soundboardDurationCacheKeys(audioUrl, filename = null) {
- 93: function rememberSoundboardDuration(audioUrl, filename, durationText) {
- 104: function getRememberedSoundboardDuration(audioUrl, filename = null) {
- 112: function rememberSoundboardDurationSeconds(audioUrl, filename, seconds) {
- 119: function getRememberedSoundboardDurationSeconds(audioUrl, filename = null) {
web/python-web-app/Implementation
- File type: Other
Plans/soundboard-clip-regeneration-implementation-plan.md
- File type: Other
web/python-web-app/Implementation
- File type: Other
Plans/voice-cloning-implementation-plan.md
- File type: Other
web/python-web-app/Implementation
- File type: Other
Plans/ARCHIVED-PLANS.md
- File type: Other
web/python-web-app/Implementation
- File type: Other
Plans/background
- File type: Other
workers
- File type: Other
implementation-plan.md
- File type: Other
web/python-web-app/Implementation
- File type: Other
Plans/README.md
- File type: Other
web/python-web-app/docker-compose.yml
- File type: Other
web/python-web-app/src/legacy_runtime.py
- File type: Python
- 6:import os # Operating system interface
- 7:import sys # Module registry for strict-mode auth helpers
- 8:import json # JSON data handling
- 9:import time # Time-related functions
- 10:import shutil # High-level file operations
- 11:import logging # Logging system
- 12:import subprocess # Process management for ffmpeg
- 13:import datetime # Date/time handling for signed URLs
web/python-web-app/tests/test_clips_provider_flow.py
- File type: Python
- 1:from src.services.clips_service import load_clips_by_path_with_provider
- 2:from src.services.combined_service import upload_combined_outputs
- 3:from src.services.voice_clone_service import store_voice_clone_in_db
- 4:import pytest
- 5:from unittest.mock import MagicMock
- 8:class FakeStorageProvider:
- 9: def init(self, paths=None, backend=”supabase”, configured=True):
- 32: def is_configured(self):
web/python-web-app/tests/test_settings_billing_web_only.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_pro_subscription_section_hidden_by_default(app_client, monkeypatch):
- 17:def test_pro_subscription_section_uses_web_manage_subscription_cta_only_when_reenabled(
web/python-web-app/tests/test_drafts_routes.py
- File type: Python
- 1:import datetime
- 3:import src.legacy_runtime as legacy_runtime
- 6:class _FakeCursor:
- 7: def init(self, responses, statements, execute_error=None):
- 12: def enter(self):
- 15: def exit(self, exc_type, exc, tb):
- 18: def execute(self, sql, params=None):
- 23: def fetchone(self):
web/python-web-app/tests/test_web_subscription_ui_disabled.py
- File type: Python
- 1:import importlib.util
- 2:import sys
- 3:import pytest
- 4:from pathlib import Path
- 6:import src.legacy_runtime as legacy_runtime
- 24:def _html(app_client):
- 31:def test_web_subscription_ui_flag_false_like_values_disable(raw_value, monkeypatch):
- 41:def test_web_subscription_ui_flag_true_like_values_enable(raw_value, monkeypatch):
web/python-web-app/tests/test_voice_clone_consent_checkbox.py
- File type: Python
- 1:def test_voice_clone_template_includes_consent_checkbox(app_client):
web/python-web-app/tests/test_marketing_auth_pages.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 6:def _marketing_root() -> Path:
- 10:def _python_web_root() -> Path:
- 14:def test_auth_callback_page_forwards_oauth_session_to_web_app():
- 27:def test_cloudflare_redirects_file_removes_invalid_spa_loop_rule():
- 36:def test_app_sign_out_requests_marketing_origin_sign_out():
- 44:def test_marketing_sign_out_request_is_consumed_before_auth_ui_render():
web/python-web-app/tests/test_deploy_version.py
- File type: Python
- 1:from future import annotations
- 4:def test_deploy_version_endpoint_is_no_store(app_client, monkeypatch):
web/python-web-app/tests/test_soundboard_order_update.py
- File type: Python
- 1:from src.services.soundboard_service import _remove_filename_from_clip_order
- 4:class _ConfiguredProvider:
- 5: def init(self):
- 8: def is_configured(self):
- 11: def read_json(self, blob_path, default):
- 15: def write_json(self, blob_path, data):
- 20:class _CtxWithProvider:
- 21: def init(self):
web/python-web-app/tests/test_settings_pro_subscription_status_api.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_pro_subscription_status_reads_supabase_entitlements(app_client, monkeypatch):
- 9: def _edge_call(_name, **_kwargs):
- 32:def test_pro_subscription_status_strict_mode_fails_closed_when_edge_unavailable(
- 55:def test_pro_subscription_status_defaults_free_when_no_entitlement_sources(
web/python-web-app/src/legacy_runtime.py
- File type: Python
- 6:import os # Operating system interface
- 7:import sys # Module registry for strict-mode auth helpers
- 8:import json # JSON data handling
- 9:import time # Time-related functions
- 10:import shutil # High-level file operations
- 11:import logging # Logging system
- 12:import subprocess # Process management for ffmpeg
- 13:import datetime # Date/time handling for signed URLs
web/python-web-app/tests/api/test_speech_contract_hardening.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _SpeechContractProvider:
- 7: def init(self, *, fail_audio_upload=False):
- 15: def is_configured(self):
- 18: def upload_from_filename(self, blob_path, source_path, content_type=None):
- 25: def upload_text(self, blob_path, text, content_type=”text/plain; charset=utf-8”):
- 30: def generate_download_url(self, blob_path, download_filename=None, expiration_hours=1):
- 34: def list_paths(self, prefix):
web/python-web-app/tests/api/test_soundboard_supabase_mode.py
- File type: Python
- 1:from unittest.mock import MagicMock
- 3:import src.legacy_runtime as legacy_runtime
- 6:class _FakeCursor:
- 7: def init(self, responses, statements):
- 11: def enter(self):
- 14: def exit(self, exc_type, exc, tb):
- 17: def execute(self, sql, params=None):
- 20: def fetchone(self):
web/python-web-app/tests/api/test_tts_soundboard_workflow_target.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _WorkflowStorageProvider:
- 7: def init(self, *, fail_audio_upload=False):
- 15: def is_configured(self):
- 18: def upload_from_filename(self, blob_path, source_path, content_type=None):
- 25: def upload_text(self, blob_path, text, content_type=”text/plain; charset=utf-8”):
- 30: def generate_download_url(
- 36: def list_paths(self, prefix):
web/python-web-app/tests/api/test_pronunciations.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _PronunciationRowCursor:
- 5: def init(self, rows=None, row=None):
- 10: def enter(self):
- 13: def exit(self, *_args):
- 16: def execute(self, statement, params=None):
- 19: def fetchall(self):
- 22: def fetchone(self):
web/python-web-app/tests/api/test_health.py
- File type: Python
- 1:def test_health_endpoint(app_client):
web/python-web-app/tests/api/test_stt.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import io
- 3:from pathlib import Path
- 5:from src.services.audio_preprocessing import empty_capabilities
- 8:def test_speech_to_text_requires_api_key(app_client, monkeypatch):
- 16:def test_speech_to_text_requires_audio_file(app_client, monkeypatch):
- 24:def test_speech_to_text_rejects_conflicting_model_ids(app_client, monkeypatch):
- 40:def test_speech_to_text_strict_preprocessing_rejection_exposes_error_metadata_and_cleans_temp_files(
web/python-web-app/tests/api/test_models.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _SettingsCursor:
- 5: def init(self, rows=None):
- 9: def enter(self):
- 12: def exit(self, *_args):
- 15: def execute(self, statement, params=None):
- 18: def fetchall(self):
- 22:class _SettingsConn:
web/python-web-app/tests/api/test_soundboard_clip_audio_mode_regression.py
- File type: Python
- 1:from unittest.mock import MagicMock
- 3:import src.legacy_runtime as legacy_runtime
- 6:def _strict_auth_headers():
- 10:def test_strict_mode_tree_policy_denial_keeps_clip_load_contract(
- 57:def test_non_strict_mode_tree_policy_denial_keeps_provider_clip_load_contract(
- 65: class _Provider:
- 66: def is_configured(self):
- 107:def test_strict_mode_tree_policy_denial_remains_deterministic_for_malformed_tree_payload(
web/python-web-app/tests/api/test_categories.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import src.routes.categories as category_routes
- 5:def _enable_strict_mode_with_user(monkeypatch, user_id=”user-1”):
- 10:def _strict_auth_headers():
- 14:def test_category_create_respects_feature_flag(app_client, monkeypatch):
- 24:def test_category_update_respects_feature_flag(app_client, monkeypatch):
- 34:def test_category_reorder_respects_feature_flag(app_client, monkeypatch):
- 45:def test_category_delete_respects_feature_flag(app_client, monkeypatch):
web/python-web-app/tests/api/test_combined_endpoints.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _FakeCursor:
- 5: def init(self, responses, statements):
- 9: def enter(self):
- 12: def exit(self, exc_type, exc, tb):
- 15: def execute(self, sql, params=None):
- 18: def fetchall(self):
- 23: def fetchone(self):
web/python-web-app/tests/api/test_download_combined.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_download_combined_missing_file_returns_404(app_client, monkeypatch):
- 12:def test_download_combined_blocks_path_traversal(app_client, monkeypatch):
web/python-web-app/tests/api/test_soundboard_path_clips.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:from unittest.mock import MagicMock
- 5:def test_soundboard_path_clips_requires_configured_storage_provider(
- 11: class _Provider:
- 12: def is_configured(self):
- 22:def test_soundboard_path_clips_calls_service_with_correct_params(
- 30: class _Provider:
- 31: def is_configured(self):
web/python-web-app/tests/api/test_runtime_speech_isolation.py
- File type: Python
- 1:import io
- 2:from concurrent.futures import ThreadPoolExecutor
- 3:from pathlib import Path
- 5:import src.legacy_runtime as legacy_runtime
- 8:def _extract_relative_audio_path(payload):
- 12:def _run_tts_request(index):
- 18:def _run_sts_request(index):
- 31:def test_parallel_tts_requests_return_unique_artifacts(monkeypatch, tmp_path):
web/python-web-app/tests/api/test_regeneration_endpoints.py
- File type: Python
- 1:def test_commit_regeneration_requires_regen_id(app_client):
- 8:def test_discard_regeneration_missing_session_returns_404(app_client):
- 15:def test_preview_regeneration_missing_session_returns_404(app_client):
web/python-web-app/tests/api/test_settings_security.py
- File type: Python
- 1:def test_update_api_key_endpoint_disabled_by_default(app_client):
web/python-web-app/tests/api/test_voice_clone.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import io
- 5:def test_voice_clone_upload_requires_api_key(app_client, monkeypatch):
- 13:def test_voice_clone_upload_requires_audio_file(app_client, monkeypatch):
- 21:def test_voice_clone_upload_rejects_unsupported_file_type(app_client, monkeypatch):
- 33:def test_voice_clone_create_requires_api_key(app_client, monkeypatch):
- 44:def test_voice_clone_create_requires_database(app_client, monkeypatch):
- 58:def test_voice_clone_create_requires_json_payload(app_client, monkeypatch):
web/python-web-app/tests/api/test_soundboard.py
- File type: Python
- 1:def test_unknown_job_returns_404(app_client):
- 8:def test_successful_memory_job_status_payload_shape(app_client, monkeypatch):
- 9: import src.legacy_runtime as legacy_runtime
- 29:def test_soundboard_clips_supabase_strict_mode_requires_auth(app_client, monkeypatch):
- 30: import src.legacy_runtime as legacy_runtime
web/python-web-app/tests/api/test_sts.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import io
- 5:def test_speech_to_speech_requires_api_key(app_client, monkeypatch):
- 13:def test_speech_to_speech_requires_audio_file(app_client, monkeypatch):
- 21:def test_speech_to_speech_requires_selected_file(app_client, monkeypatch):
- 33:def test_speech_to_speech_rejects_blank_transcription(app_client, monkeypatch):
- 37: def _fake_transcribe(*_args, **_kwargs):
- 52:def test_speech_to_speech_passes_through_transcription_errors(app_client, monkeypatch):
web/python-web-app/tests/api/test_user_settings.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 3:from src.routes.helpers import get_strict_user_id, get_user_scope_auth_context
- 6:def test_save_user_settings_requires_payload(app_client, monkeypatch):
- 16:def test_user_settings_requires_auth_in_strict_mode(app_client, monkeypatch):
- 17: import src.legacy_runtime as legacy_runtime
- 29:def test_user_settings_requires_auth_even_when_strict_flag_disabled(
- 43:class _RuntimeStub:
- 47: def resolve_request_user_id(_auth_header):
web/python-web-app/tests/api/test_cache_endpoints.py
- File type: Python
- 1:import pytest
- 3:import src.legacy_runtime as legacy_runtime
- 7:def _allow_cache_routes_in_strict_mode(monkeypatch):
- 11:def test_cache_status_requires_configuration(app_client):
- 18:def test_cache_clear_requires_configuration(app_client):
- 25:def test_cache_cleanup_requires_configuration(app_client):
- 32:def test_static_cache_route_rejects_traversal(app_client, monkeypatch, tmp_path):
web/python-web-app/tests/api/test_tts.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_text_to_speech_requires_text(app_client):
- 15:def test_text_to_speech_rejects_overlong_text(app_client):
- 26:def test_text_to_speech_handles_generation_failure(app_client, monkeypatch):
- 27: def _boom(*_args, **_kwargs):
- 45:def test_text_to_speech_returns_artifact_fields_without_mutating_runtime_global(
- 64:def test_download_audio_uses_explicit_artifact_reference(
- 81:def test_save_clip_to_soundboard_requires_explicit_artifact_or_text(
web/python-web-app/tests/api/test_runtime_entrypoint_closure.py
- File type: Python
- 3:from future import annotations
- 5:import importlib.util
- 6:import subprocess
- 7:import sys
- 8:from pathlib import Path
- 10:import src.legacy_runtime as legacy_runtime
- 11:import src.legacy_runtime as legacy_runtime
- 12:from src.app import create_app
web/python-web-app/tests/api/test_clip_convert_endpoints.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_convert_clip_requires_gcs(app_client, monkeypatch):
- 8: class _Provider:
- 9: def is_configured(self):
- 21:def test_convert_clip_validates_format(app_client, monkeypatch):
web/python-web-app/tests/api/test_voices.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_voices_requires_api_key(app_client, monkeypatch):
- 15:def test_voices_handles_upstream_exception(app_client, monkeypatch):
- 21: def _boom(*_args, **_kwargs):
- 31:def test_voices_requires_auth_in_strict_mode(app_client, monkeypatch):
- 42:def test_voices_rejects_spoofed_user_id_in_strict_mode(app_client, monkeypatch):
- 53:def test_voices_prefers_resolved_user_id_in_strict_mode(app_client, monkeypatch):
- 62: def mock_handler(user_id, *args, **kwargs):
web/python-web-app/tests/test_web_theme_defaults.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 4:import shutil
- 5:import subprocess
- 8:def _repo_root() -> Path:
- 12:def test_legacy_index_css_uses_ios_pear_meadow_defaults():
- 27:def test_marketing_tokens_match_ios_default_semantics():
- 41:def test_auth_callback_page_uses_pear_meadow_defaults():
web/python-web-app/tests/test_settings_routes.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_default_model_get_requires_auth_in_strict_mode(app_client, monkeypatch):
- 14:def test_default_model_get_returns_model_for_authorized_user_in_strict_mode(
- 40:def test_default_model_post_requires_auth_in_strict_mode(app_client, monkeypatch):
- 50:def test_default_model_post_updates_model_for_authorized_user_in_strict_mode(
- 77:def test_default_model_put_returns_deterministic_method_error_in_strict_mode(
web/python-web-app/tests/test_settings_cta_fallbacks.py
- File type: Python
- 1:def test_settings_parity_sections_render_required_non_subscription_ctas_and_readonly_summaries(
- 4: import src.legacy_runtime as legacy_runtime
- 37:def test_settings_pro_subscription_reenable_renders_web_manage_subscription_cta(
- 40: import src.legacy_runtime as legacy_runtime
web/python-web-app/tests/test_web_app_email_signup.py
- File type: Python
- 1:from future import annotations
- 3:from html.parser import HTMLParser
- 4:from pathlib import Path
- 5:import subprocess
- 7:import src.legacy_runtime as legacy_runtime
- 30:class ElementCollector(HTMLParser):
- 31: def init(self) -> None:
- 35: def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
web/python-web-app/tests/test_storage_provider.py
- File type: Python
- 1:from src.services.storage_provider import (
- 6:from src.services import storage_provider as storage_provider_module
- 7:import json
- 8:import requests
- 11:class FakeLogger:
- 12: def init(self):
- 17: def info(self, message, *args):
- 22: def warning(self, message, *args):
web/python-web-app/tests/test_user_settings_break_migration.py
- File type: Python
- 1:import json
- 3:import src.legacy_runtime as legacy_runtime
- 5:from src.services.user_settings_service import persist_user_settings
- 8:class _FakeCursor:
- 9: def init(self):
- 12: def enter(self):
- 15: def exit(self, exc_type, exc_val, exc_tb):
- 18: def execute(self, _query, params):
web/python-web-app/tests/test_settings_parity_matrix.py
- File type: Python
- 1:from pathlib import Path
- 4:def test_settings_categories_expose_deterministic_parity_modes(app_client):
- 35:def test_settings_advanced_section_implementation_is_preserved_for_reenable():
- 52:def test_settings_shared_sections_expose_ios_android_parity_controls(app_client):
- 85:def test_settings_speech_to_speech_section_exposes_override_controls(app_client):
- 112:def test_settings_soundboard_section_exposes_cache_and_offline_controls(app_client):
web/python-web-app/tests/test_voice_clone_subscription_ui_disabled.py
- File type: Python
- 1:import re
- 3:import src.legacy_runtime as legacy_runtime
- 6:def _root_html(app_client):
- 12:def _section(html, section_id):
- 31:def _assert_no_subscription_gating_copy(surface_name, section_html):
- 48:def test_speech_and_voice_clone_sections_hide_subscription_gating_copy_by_default(
web/python-web-app/tests/test_settings_feature_flags.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 3:from src.services.user_settings_service import persist_user_settings
- 6:def test_sectioned_ui_disabled_renders_legacy_layout_marker(app_client, monkeypatch):
- 19:def test_sectioned_ui_enabled_renders_hub(app_client, monkeypatch):
- 30:def test_structured_breaks_disabled_omits_default_break_settings_on_get(
- 40: def _fake_get_user_settings(_uid):
- 66:def test_structured_breaks_disabled_persist_skips_structured_column(monkeypatch):
- 71: class _Conn:
- File type: Python
- 1:def test_session_controls_render_in_app_header_not_tab_row(app_client):
web/python-web-app/tests/test_settings_strict_mode_readonly.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_settings_parity_sections_hide_subscription_status_in_strict_mode_by_default(
- 24:def test_settings_parity_sections_show_standard_readonly_status_when_not_strict(
- 42:def test_settings_parity_sections_show_subscription_status_when_reenabled(
web/python-web-app/tests/test_soundboard_session_cache_contract.py
- File type: Python
- 1:from pathlib import Path
- 19:def _source(path):
- 23:def test_soundboard_category_switch_uses_session_payload_cache():
- 33:def test_strict_path_loader_preserves_nested_category_paths():
- 44:def test_soundboard_reorder_save_updates_cache_without_refetching_category():
- 55:def test_soundboard_tab_switch_does_not_auto_refresh_after_ten_seconds():
- 64:def test_combine_success_appends_to_soundboard_session_cache_without_refetch():
web/python-web-app/tests/test_settings_strict_mode_contract.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_strict_post_break_only_does_not_call_edge_and_reports_unpersisted(
- 14: def _capture_edge(name, method=”GET”, auth_header=None, json_payload=None, **_kw):
- 41:def test_strict_post_mixed_supported_and_break_calls_edge_with_allowed_keys_only(
- 51: def _capture_edge(name, method=”GET”, auth_header=None, json_payload=None, **_kw):
- 99:def test_strict_post_soundboard_settings_calls_edge_without_unpersisted_warning(
- 109: def _capture_edge(name, method=”GET”, auth_header=None, json_payload=None, **_kw):
- 153:def test_strict_post_empty_body_still_invalid_when_no_unpersisted_fields(
web/python-web-app/tests/test_soundboard_routes.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_soundboard_combine_post_requires_auth_in_strict_mode(app_client, monkeypatch):
- 14:def test_soundboard_combine_post_routes_past_strict_policy_with_auth(
- 31:def test_soundboard_clip_convert_post_requires_auth_in_strict_mode(
- 46:def test_soundboard_clip_convert_post_routes_past_strict_policy_with_auth(
- 63:def test_soundboard_combined_convert_post_requires_auth_in_strict_mode(
- 78:def test_soundboard_combined_convert_post_routes_past_strict_policy_with_auth(
- 95:def test_soundboard_clips_put_returns_deterministic_method_error_in_strict_mode(
web/python-web-app/tests/test_soundboard_main_tab_surface.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 6:def _repo_root() -> Path:
- 10:def _soundboard_partial() -> str:
- 23:def _legacy_css() -> str:
- 28:def _soundboard_js() -> str:
- 33:def _speech_js() -> str:
- 38:def _voice_cloning_js() -> str:
web/python-web-app/tests/test_marketing_email_signup.py
- File type: Python
- 1:from future import annotations
- 3:from html.parser import HTMLParser
- 4:from pathlib import Path
- 7:class ElementCollector(HTMLParser):
- 8: def init(self) -> None:
-
| 12: def handle_starttag(self, tag: str, attrs: list[tuple[str, str |
None]]) -> None: |
- 16:class TextCollector(HTMLParser):
- 17: def init(self) -> None:
web/python-web-app/tests/test_settings_parity_additional_sections.py
- File type: Python
- 1:def test_settings_stt_model_uses_select_picker_for_ios_parity(app_client):
- 12:def test_settings_account_and_pro_sections_include_plan_and_legal_surfaces_when_reenabled(
- 15: import src.legacy_runtime as legacy_runtime
web/python-web-app/src/services/speech_service.py
- File type: Python
- 1:import os
- 2:import re
- 3:import time
- 5:from src.services.speech_runtime_service import build_speech_runtime_error
- 16:def model_supports_pronunciation_dictionary(model_id, supported_model_ids=None):
- 22:def model_uses_v3_pause_tags(model_id):
- 27:def _strip_v3_pause_tokens(text):
- 36:def _should_apply_text_details(settings):
web/python-web-app/src/services/elevenlabs_key_resolution.py
- File type: Python
- 12:from future import annotations
- 14:import logging
- 15:import os
- 16:import re
- 17:from typing import Any
- 19:import requests
-
| 31:def parse_supabase_project_ref_from_url(supabase_url: str |
None) -> str |
None: |
- 41:def fetch_elevenlabs_key_from_supabase_secrets(
web/python-web-app/src/services/storage_config_service.py
- File type: Python
- 1:from future import annotations
- 3:from dataclasses import dataclass
- 4:from typing import Any, Callable, Mapping, Protocol
- 6:from src.services.storage_provider import StorageProvider, build_storage_provider
- 10:class SupabaseStorageConfig:
- 17:class _Logger(Protocol):
- 18: def warning(self, message: str, *args: Any) -> None: …
- 25:def require_supabase_storage_backend(env: Mapping[str, str | None]) -> str:
web/python-web-app/src/services/soundboard_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import datetime
- 11:import logging
- 12:import os
- 13:import shutil
- 14:import subprocess as _subprocess
- 15:import sys
- 16:import tempfile
web/python-web-app/src/services/supabase_soundboard_categories_service.py
- File type: Python
- 9:from future import annotations
- 11:from concurrent.futures import ThreadPoolExecutor
- 12:import logging
- 13:import os
- 14:import re
- 15:import uuid
- 16:from typing import Any
- 25:class _ReorderMissingCategoryError(Exception):
web/python-web-app/src/services/legacy_runtime_state_service.py
- File type: Python
- 9:from future import annotations
- 11:import logging
- 12:from typing import Any
- 14:from src.services import legacy_runtime_bootstrap_service
- 19:def get_legacy_runtime_state(*, logger: Any = logging) -> legacy_runtime_bootstrap_service.LegacyRuntimeState:
web/python-web-app/src/services/persistent_job_service.py
- File type: Python
- 8:import json
- 9:import uuid
- 15:def json_dump_safe(value):
- 23:def json_load_safe(value, default=None):
- 33:def _putconn(connection_pool, conn):
- 38:def create_persistent_job(connection_pool, logger, job_id, initial_data=None):
- 63:def update_persistent_job(connection_pool, logger, job_id, **fields):
- 107:def get_persistent_job(connection_pool, logger, job_id):
web/python-web-app/src/services/regeneration_service.py
- File type: Python
- 1:import os
- 4:def parse_regeneration_request_payload(payload):
- 16:def build_regeneration_preview_response(result):
- 38:def parse_commit_payload(payload):
- 47:def validate_commit_session(session_snapshot, decision, gcs_available):
- 63:def resolve_regenerated_text_content(session_snapshot):
- 79:def build_commit_regeneration_response(
- 110:def validate_regen_identifier(regen_id):
web/python-web-app/src/services/pronunciation_service.py
- File type: Python
- 6:def _edge_pronunciation_failure_payload(edge_result):
- 13:def _edge_entries(edge_result):
- 19:def _legacy_entry_from_edge(entry):
- 27:def _find_edge_entry(entries, term):
- 36:def _unauthorized_payload():
- 40:def _log_local_failure(logger, *, operation, exc):
- 49:def list_local_pronunciations_for_endpoint(*, connection_pool, logger=None):
- 58:def get_local_pronunciation_for_endpoint(*, connection_pool, term, logger=None):
web/python-web-app/src/services/cache_service.py
- File type: Python
- 1:import os
- 2:import shutil
- 5:def build_category_stats(metadata):
- 20:def build_cache_status_payload(cache_dir, cache_size_mb, cache_max_size_mb, cleanup_threshold_mb, metadata):
- 32:def clear_cache_entries(cache_dir, metadata, categories_to_clear, init_cache_fn):
- 65:def build_cache_cleanup_payload(initial_size_mb, final_size_mb):
web/python-web-app/src/services/combined_service.py
- File type: Python
- 1:import json
- 2:import math
- 3:import os
- 4:import re
- 5:import subprocess
- 6:from datetime import datetime, timezone
- 9:def ensure_combined_delete_allowed(
- 17:def ensure_combined_convert_allowed(storage_available, ffmpeg_available):
web/python-web-app/src/services/supabase_edge_client.py
- File type: Python
- 1:from future import annotations
- 3:import os
- 4:import time
- 5:from typing import Any, Callable
- 7:import requests
- 9:from src.services.speech_runtime_service import build_speech_runtime_error
-
| 12:def _as_bool(value: str |
None, default: bool = False) -> bool: |
- 18:def is_supabase_edge_enabled() -> bool:
web/python-web-app/src/services/soundboard_migration_service.py
- File type: Python
- 1:from future import annotations
- 3:import json
- 4:import base64
- 5:import mimetypes
- 6:import os
- 7:import time
- 8:import uuid
- 9:from dataclasses import dataclass, field
web/python-web-app/src/services/page_bootstrap_service.py
- File type: Python
- 8:from future import annotations
- 10:import os
- 11:import time
- 12:from typing import Any, Callable, Iterable, Mapping
- 14:from src.services.cache_runtime_service import resolve_static_cache_file
- 15:from src.services.static_service import infer_download_mime_type, resolve_download_file_path
- 23:def resolve_public_supabase_credentials(env_get: EnvGetter) -> tuple[str, str]:
- 32:def resolve_asset_version(
web/python-web-app/src/services/api_key_service.py
- File type: Python
- 1:from pathlib import Path
- 4:def upsert_env_key(lines, key, value):
- 22:def update_env_api_key(base_dir, api_key):
web/python-web-app/src/services/regeneration_route_service.py
- File type: Python
- 10:from future import annotations
- 12:from dataclasses import dataclass
- 13:from types import ModuleType
- 14:from typing import Any
- 16:from src.services.regeneration_service import (
- 31:class RegenerationRouteDependencies:
- 36: def getattr(self, name: str) -> Any:
- 40:def regenerate_soundboard_clip(category_id, filename, deps):
- File type: Python
- 1:from future import annotations
- 3:import datetime as dt
- 4:import json
- 5:import os
- 6:import re
- 7:import uuid
- 8:from dataclasses import dataclass
- 9:from typing import Any, Mapping
web/python-web-app/src/services/user_settings_service.py
- File type: Python
- 1:import json
- 3:from src.db_table_names import FLASK_USER_SETTINGS_KV
- 4:from src.services.theme_service import DEFAULT_THEME_ID, normalize_theme_id
- 58:def _to_float_or_default(raw_value, default_value):
- 65:def normalize_break_settings(default_break_duration, raw_break_settings=None):
- 99:def resolve_web_settings_flag(raw_value, default=False):
- 112:def strict_mode_unpersisted_request_fields(settings_data):
- 122:def attach_theme_aliases(settings_payload):
web/python-web-app/src/services/static_service.py
- File type: Python
- 1:import mimetypes
- 2:import os
- 5:def build_download_filename(last_tts_text, generate_filename_fn):
- 11:def resolve_cache_file_path(cache_dir, cache_path):
- 21:def infer_cache_mime_type(cache_path, full_cache_path):
- 44:def resolve_download_file_path(static_dir, filename):
- 54:def infer_download_mime_type(filename, file_path):
web/python-web-app/src/services/default_model_service.py
- File type: Python
- 1:def default_model_payload(default_model_id):
- 5:def _strict_edge_failure_payload(edge_result):
- 13:def _resolve_local_default_model(get_user_settings_fn, user_id, default_model_id):
- 21:def get_default_model_for_endpoint(
- 64:def update_default_model_for_endpoint(
web/python-web-app/src/services/legacy_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import importlib
- 11:import logging
- 12:import os
- 13:import sys
- 15:import requests
- 16:from flask import request
- 18:from src.services.supabase_edge_client import resolve_supabase_user_id
web/python-web-app/src/services/auth_bootstrap_service.py
- File type: Python
- 1:from future import annotations
- 3:from collections.abc import Callable, Mapping, Sequence
- 4:from typing import Any
- 5:from urllib.parse import urljoin, urlparse
-
| 17:def _parse_oauth_providers(raw_value: str |
None) -> list[str]: |
-
| 33:def _parse_sign_in_url_candidate(raw_url: str |
None) -> str |
None: |
-
| 48:def _resolve_sign_in_url(env: Mapping[str, str |
None]) -> str: |
- 60:def _resolve_sign_out_redirect_url(env: Mapping[str, str | None]) -> str:
web/python-web-app/src/services/job_status_service.py
- File type: Python
- 1:def build_job_status_payload(job_id, job_lookup):
- 8:def build_job_status_response(job_id, job_lookup):
web/python-web-app/src/services/category_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import logging
- 11:import re
- 12:import sys
- 14:from src.db_table_names import FLASK_SOUNDBOARD_CATEGORIES
- 15:from src.services import cache_runtime_service, category_runtime_service
- 16:from src.services.supabase_edge_client import resolve_supabase_user_id
- 17:from src.storage.gcs import get_blob
web/python-web-app/src/services/__init__.py
- File type: Python
web/python-web-app/src/services/tts_service.py
- File type: Python
- 1:import json
- 2:import os
- 3:from urllib.parse import quote
- 5:from src.services.speech_runtime_service import (
- 9:from src.services.supabase_edge_client import (
-
| 16:def _normalize_bearer_auth_header(auth_header: str |
None) -> str |
None: |
- 26:def _generated_audio_download_name(text: str, extension: str) -> str:
- 39:def _strict_edge_failure_blocks_legacy_fallback(
web/python-web-app/src/services/storage_provider.py
- File type: Python
- 1:from future import annotations
- 3:from dataclasses import dataclass, field
- 4:from typing import Any, Callable, Protocol
- 5:import threading
- 6:import time
- 8:import requests
- 9:import json
- 12:class StorageProvider(Protocol):
web/python-web-app/src/services/audio_preprocessing.py
- File type: Python
- 3:from future import annotations
- 5:import os
- 6:import subprocess
- 7:import time
- 8:import uuid
- 9:from dataclasses import dataclass
- 15:class PreprocessCapabilities:
- 21:def empty_capabilities() -> PreprocessCapabilities:
web/python-web-app/src/services/draft_service.py
- File type: Python
- 8:def _isoformat(value):
- 12:def list_drafts_for_endpoint(*, connection_pool, query_args, logger=None):
- 21:def create_draft_for_endpoint(*, connection_pool, request_payload, logger=None):
- 31:def list_drafts(*, connection_pool, query_args, logger=None):
- 82:def create_draft(*, connection_pool, body, logger=None):
web/python-web-app/src/services/models_service.py
- File type: Python
- 1:def _dedupe_models(models):
- 12:def fetch_models(api_key, requests_get, timeout_seconds):
web/python-web-app/src/services/cache_runtime_service.py
- File type: Python
- 8:import json
- 9:import os
- 10:import shutil
- 11:import tempfile
- 12:import time
- 14:from src.services.cache_service import build_cache_cleanup_payload, build_cache_status_payload
- 15:from src.services.static_service import infer_cache_mime_type, resolve_cache_file_path
- 25:def init_cache(*, cache_dir=None, temp_dir_factory=tempfile.gettempdir, logger=None):
web/python-web-app/src/services/soundboard_service.py
- File type: Python
- 1:def handle_delete_combined_file(
- 62:def handle_get_soundboard_clips_by_path(
- 138:def _unique_requested_names(raw_values):
- 153:def _filter_resolved_media_payload(payload, requested_filenames, requested_combined):
- 183:def handle_resolve_soundboard_clips(category_id, request_payload, runtime):
- 205: from src.services.supabase_soundboard_categories_service import (
- 249:def handle_download_combined_file(
- 281:def handle_combine_preview(category_id, request_is_json, request_data, ctx):
web/python-web-app/src/services/voices_service.py
- File type: Python
- 1:import logging
- 4:def annotate_standard_voices(voices):
- 14:def fetch_standard_voices(api_key, requests_get, timeout_seconds):
- 31:def fetch_custom_voices_from_db(connection_pool, user_id):
- 74:def build_voices_response(
web/python-web-app/src/services/settings_service.py
- File type: Python
- 1:def mask_api_key(api_key):
- 9:def handle_save_user_settings(
- 31:def handle_update_api_key(
web/python-web-app/src/services/voice_clone_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import logging
- 11:import os
- 12:import sys
- 13:import time
- 15:import requests
- 17:from src.services.supabase_edge_client import resolve_supabase_user_id
- 29:def _cleanup_old_temp_voice_samples(temp_dir, max_age_seconds=24 * 3600):
web/python-web-app/src/services/voice_clone_service.py
- File type: Python
- 1:import io
- 2:import os
- 3:import re
- 4:import time
- 5:import hashlib
- 6:import base64
- 9:def parse_create_voice_clone_request(data):
- 39:def enforce_upload_rate_limit(
web/python-web-app/src/services/settings_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import logging
- 11:import os
- 12:import sys
- 14:from src.services.api_key_service import update_env_api_key
- 15:from src.services.settings_service import mask_api_key
- 16:from src.services.supabase_edge_client import resolve_supabase_user_id
- 17:from src.services.user_settings_service import build_default_settings, fetch_user_settings, persist_user_settings as _persist_user_settings
web/python-web-app/src/services/legacy_runtime_adapter.py
- File type: Python
- 12:from src import legacy_runtime as _legacy_runtime
- 15:def getattr(name):
- 19:def setattr(name, value):
web/python-web-app/src/services/category_runtime_service.py
- File type: Python
- 8:from src.db_table_names import FLASK_SOUNDBOARD_CATEGORIES
- 11:def category_mgmt_enabled(enable_category_management):
- 15:def ensure_category(
- 62:def seed_legacy_categories(
- 125:def provision_gcs_category(
- 172:def copy_gcs_prefix(
- 219:def move_gcs_prefix(
- 245:def is_descendant(
web/python-web-app/src/services/strict_soundboard_service.py
- File type: Python
- 7:from future import annotations
- 9:import os
- 10:import uuid
- 11:import json
- 12:from dataclasses import dataclass
- 13:from typing import Any, Protocol
- 16:class ClipTextFetchError(Exception):
- 19: def init(self, message: str, *, reason: str = “unknown”):
web/python-web-app/src/services/speech_route_dependencies.py
- File type: Python
- 9:from future import annotations
- 11:import logging
- 12:import os
- 13:import sys
- 15:import requests
- 17:from src.services.models_service import fetch_models
- 18:from src.services.speech_service import (
- 30:from src.services.stt_input_capture_service import (
web/python-web-app/src/services/theme_service.py
- File type: Python
- 20:def normalize_theme_id(theme_id):
- 34:def resolve_effective_theme(signed_in, account_theme_id, local_theme_id):
web/python-web-app/src/services/soundboard_route_service.py
- File type: Python
- 9:from future import annotations
- 11:from dataclasses import dataclass
- 12:from types import ModuleType
- 13:from typing import Any
- 17:class SoundboardRouteDependencies:
- 22: def getattr(self, name: str) -> Any:
- 26:def _smart_cache_covers_storage_order(category_id, cached_clip_count, deps):
- 54:def _coerce_metadata_number(value):
web/python-web-app/src/services/clips_service.py
- File type: Python
- 1:import os
- 4:def load_clips_by_path(
- 36: def build_clip(filename):
- 134:def load_clips_by_path_with_provider(
- 166: def build_clip(filename):
- 282:def _relative_path(full_path: str, prefix: str) -> str:
web/python-web-app/src/services/legacy_runtime_bootstrap_service.py
- File type: Python
- 10:from future import annotations
- 12:import logging
- 13:import os
- 14:import subprocess
- 15:import tempfile
- 16:import threading
- 17:from dataclasses import dataclass, field
- 18:from pathlib import Path
web/python-web-app/src/services/stt_service.py
- File type: Python
- 1:import base64
- 2:import os
- 3:from urllib.parse import quote
- 5:from src.services.audio_preprocessing import (
- 12:from src.services.speech_runtime_service import (
- 16:from src.services.speech_service import get_audio_mime_type, transcribe_audio_file_from_path
- 17:from src.services.supabase_edge_client import (
- 23:def _generated_audio_download_name(text: str, extension: str) -> str:
web/python-web-app/src/services/category_service.py
- File type: Python
- 1:import logging
- 3:from src.db_table_names import FLASK_SOUNDBOARD_CATEGORIES
- 9:def _normalize_optional_int(value, field_name):
- 18:def normalize_create_category_payload(payload):
- 32:def fetch_categories_tree(connection_pool, fetch_categories_fn, build_tree_fn):
- 47:def normalize_reorder_payload(payload):
- 54:def update_category(
- 179:def reorder_categories(
web/python-web-app/src/services/auth_service.py
- File type: Python
- 1:from future import annotations
- 3:from src.services.auth_bootstrap_service import ( # noqa: F401
web/python-web-app/src/services/speech_runtime_service.py
- File type: Python
- 1:from future import annotations
- 3:import os
- 4:import re
- 5:import uuid
- 6:from typing import Any
- 14:def _sanitize_detail_value(value: Any) -> Any:
-
| 30:def _sanitize_details(details: dict[str, Any] |
None) -> dict[str, Any] |
None: |
- 36:def _normalize_extension(extension: str) -> str:
web/python-web-app/src/services/combined_route_service.py
- File type: Python
- 9:from future import annotations
- 11:from dataclasses import dataclass
- 12:from types import ModuleType
- 13:from typing import Any
- 15:from src.routes.helpers import get_strict_user_id
- 19:class CombinedRouteDependencies:
- 24: def getattr(self, name: str) -> Any:
- 28:def resolve_combine_clip_filenames(
web/python-web-app/tests/test_clips_provider_flow.py
- File type: Python
- 1:from src.services.clips_service import load_clips_by_path_with_provider
- 2:from src.services.combined_service import upload_combined_outputs
- 3:from src.services.voice_clone_service import store_voice_clone_in_db
- 4:import pytest
- 5:from unittest.mock import MagicMock
- 8:class FakeStorageProvider:
- 9: def init(self, paths=None, backend=”supabase”, configured=True):
- 32: def is_configured(self):
web/python-web-app/tests/test_settings_billing_web_only.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_pro_subscription_section_hidden_by_default(app_client, monkeypatch):
- 17:def test_pro_subscription_section_uses_web_manage_subscription_cta_only_when_reenabled(
web/python-web-app/tests/test_drafts_routes.py
- File type: Python
- 1:import datetime
- 3:import src.legacy_runtime as legacy_runtime
- 6:class _FakeCursor:
- 7: def init(self, responses, statements, execute_error=None):
- 12: def enter(self):
- 15: def exit(self, exc_type, exc, tb):
- 18: def execute(self, sql, params=None):
- 23: def fetchone(self):
web/python-web-app/tests/test_web_subscription_ui_disabled.py
- File type: Python
- 1:import importlib.util
- 2:import sys
- 3:import pytest
- 4:from pathlib import Path
- 6:import src.legacy_runtime as legacy_runtime
- 24:def _html(app_client):
- 31:def test_web_subscription_ui_flag_false_like_values_disable(raw_value, monkeypatch):
- 41:def test_web_subscription_ui_flag_true_like_values_enable(raw_value, monkeypatch):
web/python-web-app/tests/test_voice_clone_consent_checkbox.py
- File type: Python
- 1:def test_voice_clone_template_includes_consent_checkbox(app_client):
web/python-web-app/tests/test_marketing_auth_pages.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 6:def _marketing_root() -> Path:
- 10:def _python_web_root() -> Path:
- 14:def test_auth_callback_page_forwards_oauth_session_to_web_app():
- 27:def test_cloudflare_redirects_file_removes_invalid_spa_loop_rule():
- 36:def test_app_sign_out_requests_marketing_origin_sign_out():
- 44:def test_marketing_sign_out_request_is_consumed_before_auth_ui_render():
web/python-web-app/tests/test_deploy_version.py
- File type: Python
- 1:from future import annotations
- 4:def test_deploy_version_endpoint_is_no_store(app_client, monkeypatch):
web/python-web-app/tests/test_soundboard_order_update.py
- File type: Python
- 1:from src.services.soundboard_service import _remove_filename_from_clip_order
- 4:class _ConfiguredProvider:
- 5: def init(self):
- 8: def is_configured(self):
- 11: def read_json(self, blob_path, default):
- 15: def write_json(self, blob_path, data):
- 20:class _CtxWithProvider:
- 21: def init(self):
web/python-web-app/tests/test_settings_pro_subscription_status_api.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_pro_subscription_status_reads_supabase_entitlements(app_client, monkeypatch):
- 9: def _edge_call(_name, **_kwargs):
- 32:def test_pro_subscription_status_strict_mode_fails_closed_when_edge_unavailable(
- 55:def test_pro_subscription_status_defaults_free_when_no_entitlement_sources(
web/python-web-app/deploy/PROXMOX.md
- File type: Other
web/python-web-app/deploy/HOMELAB-SSH-SETUP.md
- File type: Other
web/python-web-app/src/__init__.py
- File type: Python
web/python-web-app/src/create_voice_samples_table.sql
- File type: SQL
- 4:CREATE TABLE IF NOT EXISTS voice_samples (
- 16:CREATE INDEX IF NOT EXISTS idx_voice_samples_voice_id ON voice_samples (voice_id);
- 17:CREATE INDEX IF NOT EXISTS idx_voice_samples_upload_date ON voice_samples (upload_date);
web/python-web-app/src/create_background_jobs_table.sql
- File type: SQL
- 1:CREATE TABLE IF NOT EXISTS background_jobs (
- 11:CREATE INDEX IF NOT EXISTS idx_background_jobs_status ON background_jobs(status);
- 12:CREATE INDEX IF NOT EXISTS idx_background_jobs_updated_at ON background_jobs(updated_at);
web/python-web-app/src/create_custom_voices_table.sql
- File type: SQL
- 4:CREATE TABLE IF NOT EXISTS custom_voices (
- 18:CREATE INDEX IF NOT EXISTS idx_custom_voices_user_id ON custom_voices (user_id);
- 19:CREATE INDEX IF NOT EXISTS idx_custom_voices_elevenlabs_id ON custom_voices (elevenlabs_voice_id);
- 20:CREATE INDEX IF NOT EXISTS idx_custom_voices_active ON custom_voices (is_active);
- 23:CREATE OR REPLACE FUNCTION update_custom_voices_updated_at()
- 25:BEGIN
- 31:CREATE TRIGGER trigger_custom_voices_updated_at
web/python-web-app/src/create_soundboard_categories_table.sql
- File type: SQL
- 2:CREATE TABLE IF NOT EXISTS flask_soundboard_categories (
- 13:CREATE INDEX IF NOT EXISTS idx_flask_soundboard_categories_parent ON flask_soundboard_categories(parent_id);
- 14:CREATE INDEX IF NOT EXISTS idx_flask_soundboard_categories_parent_position ON flask_soundboard_categories(parent_id, position);
web/python-web-app/src/config.py
- File type: Python
- 1:from dataclasses import dataclass
- 2:import logging
- 3:import os
- 4:import sys
- 6:from src.services.elevenlabs_key_resolution import resolve_elevenlabs_api_key
- 10:class AppConfig:
-
| 19:def _as_bool(value: str |
None, default: bool) -> bool: |
- 25:def _get_optional(key: str, default: str | None = None) -> str | None:
web/python-web-app/wsgi.py
- File type: Python
- 1:from src.app import create_app
web/python-web-app/Procfile
- File type: Other
web/python-web-app/src/app.py
- File type: Python
- 1:from flask import Flask
- 3:from src.routes.categories import bp as categories_bp
- 4:from src.routes.health import bp as health_bp
- 5:from src.routes.legacy import bp as legacy_bp
- 6:from src.routes.soundboard import bp as soundboard_bp
- 7:from src.routes.settings import bp as settings_bp
- 8:from src.routes.stt import bp as stt_bp
- 9:from src.routes.tts import bp as tts_bp
web/python-web-app/src/create_drafts_table.sql
- File type: SQL
- 1:CREATE TABLE IF NOT EXISTS drafts (
- 10:CREATE INDEX IF NOT EXISTS idx_drafts_user_route_editor_created
web/python-web-app/src/create_table.sql
- File type: SQL
- 4:CREATE TABLE IF NOT EXISTS pronunciations (
- 11:CREATE INDEX IF NOT EXISTS idx_pronunciations_term_lower ON pronunciations (LOWER(Term));
- 14:CREATE TABLE IF NOT EXISTS clip_orders (
web/python-web-app/tests/test_seed_order_provider.py
- File type: Python
- 1:import json
- 3:import src.legacy_runtime as runtime
- 4:from flask import Flask
- 7:class _FakeProvider:
- 8: def init(self):
- 12: def is_configured(self):
- 15: def list_paths(self, prefix):
- 18: def read_json(self, blob_path, default):
web/python-web-app/tests/test_soundboard_download_contract.py
- File type: Python
- 1:from pathlib import Path
- 12:def test_soundboard_download_helper_fetches_blob_before_anchor_download():
- 21:def test_soundboard_download_helper_does_not_open_new_window_fallback():
web/python-web-app/tests/test_browser_auth_bootstrap.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_index_in_strict_mode_exposes_auth_bootstrap_contract(app_client, monkeypatch):
- 46:def test_index_in_strict_mode_renders_configurable_apple_oauth_buttons(app_client, monkeypatch):
- 78:def test_index_bootstrap_link_uses_configured_sign_in_url(app_client, monkeypatch):
- 106:def test_auth_callback_forwards_to_web_public_origin(app_client, monkeypatch):
- 128:def test_auth_callback_accepts_no_trailing_slash(app_client, monkeypatch):
- 142:def test_auth_login_returns_session_payload(app_client, monkeypatch):
- 143: class _Response:
web/python-web-app/tests/test_product_workflow_target_brief.py
- File type: Python
- 1:from pathlib import Path
- 3:import pytest
- 42:class BriefValidationError(AssertionError):
- 46:def _read_brief() -> str:
- 53:def _section(text: str, heading: str) -> str:
- 64:def _assert_brief_contract(text: str) -> None:
- 101:def test_product_workflow_target_brief_preserves_s02_contract():
- 142:def test_product_workflow_target_brief_guard_rejects_malformed_contracts(
web/python-web-app/tests/test_web_tutorial_copy.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 6:def _repo_root() -> Path:
- 10:def _partial(name: str) -> str:
- 23:def test_speech_instruction_copy_covers_current_save_share_and_settings_flows():
- 39:def test_soundboard_instruction_copy_covers_folder_and_clip_management():
- 50:def test_voice_clone_and_settings_instruction_copy_covers_current_guided_flow():
web/python-web-app/tests/test_web_defaults_race.py
- File type: Python
- 1:from pathlib import Path
- 7:def _static_js(name):
- 13:def _partial_template(name):
- 19:def test_post_auth_defaults_reload_forces_account_settings_refetch():
- 29:def test_user_settings_loader_rejects_stale_pre_auth_responses():
- 42:def test_settings_tab_waits_for_catalog_dropdowns_before_applying_defaults():
- 79:def test_settings_tab_sliders_display_supabase_decimals_as_percent_values():
- 108:def test_settings_tts_language_uses_provider_model_dropdown():
web/python-web-app/tests/test_settings_style_presets_api.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_settings_tts_section_renders_style_preset_controls(app_client):
- 15:def test_style_presets_get_reads_from_edge_when_available(app_client, monkeypatch):
- 20: def _edge_call(_name, **_kwargs):
- 54:def test_style_presets_get_strict_mode_fails_closed_when_edge_unavailable(
- 77:def test_style_presets_create_routes_to_edge(app_client, monkeypatch):
- 84: def _edge_call(name, **kwargs):
web/python-web-app/tests/conftest.py
- File type: Python
- 1:import pytest
- 2:import sys
- 3:import os
- 4:from pathlib import Path
- 15:import src.legacy_runtime as legacy_runtime
- 19:def app_client():
web/python-web-app/src/routes/stt.py
- File type: Python
- 1:from flask import Blueprint, jsonify, request
- 3:from src.services import speech_route_dependencies as speech_deps
- 4:from src.services.stt_service import handle_speech_to_speech, handle_speech_to_text
- 10:def _log_realtime_edge_result(function_name, status, payload, edge_result):
- 27:def _proxy_realtime_edge_function(function_name, json_payload):
- 62:def speech_to_text():
- 93:def sts_realtime_session():
- 101:def sts_near_realtime_session():
web/python-web-app/src/routes/helpers.py
- File type: Python
- 1:import os
- 3:from flask import jsonify
- 5:from src.services.auth_bootstrap_service import (
- 12:def _jsonify_error_response(error_response):
- 19:def get_user_scope_auth_context(runtime, auth_header, requested_user_id=None):
- 44:def get_strict_user_id(runtime, auth_header):
web/python-web-app/src/routes/soundboard.py
- File type: Python
- 1:from flask import Blueprint, g, jsonify, request
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services.soundboard_service import (
- 14:from src.services.soundboard_route_service import (
- 17:from src.services.supabase_soundboard_categories_service import move_clip_for_user
- 24:def block_soundboard_routes_in_strict_mode():
- 25: from src.services import soundboard_route_dependencies as runtime
- 62:def convert_soundboard_clip(category_id, filename):
web/python-web-app/src/routes/settings.py
- File type: Python
- 1:from flask import Blueprint, jsonify, render_template, request
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services.settings_service import (
- 8:from src.services.user_settings_service import (
- 12:from src.services.theme_service import normalize_theme_id
- 18:def _is_paid_plan_tier(plan_tier):
- 23:def _fetch_plan_tier_from_local_db(connection_pool, user_id):
- 68:def settings_page():
web/python-web-app/src/routes/__init__.py
- File type: Python
web/python-web-app/src/routes/tts.py
- File type: Python
- 1:from flask import Blueprint, Response, jsonify, request, stream_with_context
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services import speech_route_dependencies as speech_deps
- 5:from src.services.tts_service import (
- 16:def _is_dev_unauth_smoke_mode(_runtime_state, auth_header):
- 29:def get_models():
- 47:def text_to_speech():
- 83:def text_to_speech_stream():
web/python-web-app/src/routes/categories.py
- File type: Python
- 1:from flask import Blueprint, jsonify, request
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services.category_service import (
- 11:from src.services.supabase_soundboard_categories_service import (
- 26:def _strict_user_or_error(runtime):
- 34:def get_soundboard_categories_tree():
- 35: from src.services import category_route_dependencies as runtime
- 56:def create_soundboard_category():
web/python-web-app/src/routes/health.py
- File type: Python
- 1:from flask import Blueprint, jsonify, make_response
- 3:from src.services import page_bootstrap_service
- 10:def health():
- 15:def deploy_version():
web/python-web-app/src/routes/legacy.py
- File type: Python
- 1:from flask import Blueprint, jsonify, render_template, request
- 2:from werkzeug.exceptions import MethodNotAllowed
- 3:from urllib.parse import urlencode, urlparse
- 5:from src.routes.helpers import get_user_scope_auth_context
- 6:from src.services.auth_bootstrap_service import (
- 22:from src.services.default_model_service import (
- 26:from src.services.pronunciation_service import (
- 60:def _jsonify_error_response(error_response):
web/python-web-app/src/routes/voice_clone.py
- File type: Python
- 1:from flask import Blueprint, jsonify, request
- 2:import json
- 4:from src.routes.helpers import get_user_scope_auth_context
- 5:from src.services import voice_clone_route_dependencies as voice_deps
- 6:from src.services.voice_clone_service import (
- 20:def voice_clone_upload():
- 37:def voice_clone_preflight():
- 64:def voice_clone_create():
web/python-web-app/src/create_user_settings_table.sql
- File type: SQL
- 2:CREATE TABLE IF NOT EXISTS flask_user_settings (
- 11:CREATE UNIQUE INDEX IF NOT EXISTS idx_flask_user_settings_name_user ON flask_user_settings (setting_name, user_id);
web/python-web-app/src/storage/postgres.py
- File type: Python
- 1:from future import annotations
- 3:from typing import Any
- 5:from psycopg2 import OperationalError, extensions, pool
- 8:class _ValidatedConnectionPool:
- 11: def init(self, raw_pool: Any, logger: Any):
- 15: def getconn(self) -> Any:
- 28: def putconn(self, conn: Any, close: bool = False) -> None:
- 31: def closeall(self) -> None:
web/python-web-app/src/storage/__init__.py
- File type: Python
web/python-web-app/src/storage/gcs.py
- File type: Python
- 1:import os
- 2:import tempfile
- 3:import json
- 4:import datetime
- 6:from google.cloud import storage
- 9:def initialize_gcs(bucket_name, key_filename, logger):
- 75:def apply_gcs_billing_project(bucket, billing_project, logger):
- 85:def get_blob(bucket, blob_path):
web/python-web-app/templates/partials/index_slow/settings_legacy_flat.html
- File type: HTML
- 2:<div id=”settings-form” class=”tab-content theme-panel”
- 6: <div class="settings-section">
- 8: <div class="form-group" id="settingsAccountEmailGroup" style="display:none">
- 12: <div class="buttons">
- 19: <div class="settings-section">
- 21: <div class="form-group">
web/python-web-app/templates/partials/index_slow/settings.html
- File type: HTML
- 2:<div id=”settings-form” class=”tab-content theme-panel”
- 6: <div id="settingsHub" class="settings-hub" data-testid="settings-hub-root">
- 7: <div class="settings-group">
- 8: <div class="settings-group-header">Quick Access</div>
- 9: <div class="settings-card">
- 21: <div class="settings-group">
web/python-web-app/templates/partials/index_slow/modals.html
- File type: HTML
- 2: <div id="category-select-modal" class="modal">
- 3: <div class="modal-content">
- 4: <div class="modal-header">
- 9: <div class="category-select-container">
- 31: <div class="conversion-options" style="margin-top: 12px;">
- 32: <div style="display: flex; gap: 12px; align-items: center; flex-wrap: wrap;">
web/python-web-app/templates/partials/index_slow/tts.html
- File type: HTML
- 1:<div id="tts-form" class="tab-content" style="display: block;">
- 3: <div class="tts-form-content center-content" style="width: 100%; max-width: 1200px;">
- 8: <div class=”editor-toolbar”
- 11: <div style="display:flex; align-items:center; gap:10px;">
- 12: <div id="char-counter" style="font-size: 1.05em; font-weight: 600; color: var(--primary-color);">
- 25: <div class="model-selection-container center-content">
web/python-web-app/templates/partials/index_slow/voice_cloning.html
- File type: HTML
- 1:<div id=”voice-cloning-form” class=”tab-content theme-panel”
- 7: <div class="voice-cloning-section" style="margin-bottom: 30px;">
- 9: <div id="custom-voices-list" class="custom-voices-container">
- 10: <div class="loading-placeholder" style="text-align: center; padding: 20px; color: var(--text-secondary);">
- 17: <div class="voice-cloning-section">
- 21: <div class="cloning-step" id="step-1">
web/python-web-app/templates/partials/index_slow/sts.html
- File type: HTML
- 1:<div id="sts-form" class="tab-content" style="display: none;">
- 6: <div class="sts-form-content center-content" style="width: 100%; max-width: 1200px;">
- 8: <div class="stt-section upload-section">
- 10: <div class="upload-container">
- 16: <div class="stt-section record-section">
- 19: <div class="record-controls">
web/python-web-app/templates/partials/index_slow/stt.html
- File type: HTML
- 1:<div id="stt-form" class="tab-content" style="display: none;">
- 2: <div class="stt-form-content center-content" style="width: 100%; max-width: 1200px;">
- 6: <div class="stt-section upload-section">
- 8: <div class="upload-container">
- 10: <div class="file-input-row">
- 16: <div class="stt-section record-section">
web/python-web-app/templates/partials/index_slow/soundboard.html
- File type: HTML
- 1:<div id="soundboard-form" class="tab-content" style="display: none;">
- 2: <div style="display:flex; align-items:center; justify-content:center;">
- 6: <div id="soundboard-category-surface" data-testid="soundboard-category-surface">
- 11: <div id=”soundboard-category-management-toolbar” class=”soundboard-category-management-toolbar”
- 17: <div id="soundboard-category-management-create-row" class="soundboard-category-management-create-row" style="display:none;">
- 30: <div id=”soundboard-category-management-error” class=”soundboard-category-management-error”
web/python-web-app/templates/settings.html
- File type: HTML
- 4:
- 5:
- 7:
- 78:
- 80:<body>
- 81: <main class="card">
web/python-web-app/templates/auth_callback.html
- File type: HTML
- 4:
- 5:
- 6:
- 8:
- 62:
- 95: <body>
web/python-web-app/src/services/speech_service.py
- File type: Python
- 1:import os
- 2:import re
- 3:import time
- 5:from src.services.speech_runtime_service import build_speech_runtime_error
- 16:def model_supports_pronunciation_dictionary(model_id, supported_model_ids=None):
- 22:def model_uses_v3_pause_tags(model_id):
- 27:def _strip_v3_pause_tokens(text):
- 36:def _should_apply_text_details(settings):
web/python-web-app/src/services/elevenlabs_key_resolution.py
- File type: Python
- 12:from future import annotations
- 14:import logging
- 15:import os
- 16:import re
- 17:from typing import Any
- 19:import requests
-
| 31:def parse_supabase_project_ref_from_url(supabase_url: str |
None) -> str |
None: |
- 41:def fetch_elevenlabs_key_from_supabase_secrets(
web/python-web-app/src/services/storage_config_service.py
- File type: Python
- 1:from future import annotations
- 3:from dataclasses import dataclass
- 4:from typing import Any, Callable, Mapping, Protocol
- 6:from src.services.storage_provider import StorageProvider, build_storage_provider
- 10:class SupabaseStorageConfig:
- 17:class _Logger(Protocol):
- 18: def warning(self, message: str, *args: Any) -> None: …
- 25:def require_supabase_storage_backend(env: Mapping[str, str | None]) -> str:
web/python-web-app/src/services/soundboard_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import datetime
- 11:import logging
- 12:import os
- 13:import shutil
- 14:import subprocess as _subprocess
- 15:import sys
- 16:import tempfile
web/python-web-app/src/services/supabase_soundboard_categories_service.py
- File type: Python
- 9:from future import annotations
- 11:from concurrent.futures import ThreadPoolExecutor
- 12:import logging
- 13:import os
- 14:import re
- 15:import uuid
- 16:from typing import Any
- 25:class _ReorderMissingCategoryError(Exception):
web/python-web-app/src/services/legacy_runtime_state_service.py
- File type: Python
- 9:from future import annotations
- 11:import logging
- 12:from typing import Any
- 14:from src.services import legacy_runtime_bootstrap_service
- 19:def get_legacy_runtime_state(*, logger: Any = logging) -> legacy_runtime_bootstrap_service.LegacyRuntimeState:
web/python-web-app/src/services/persistent_job_service.py
- File type: Python
- 8:import json
- 9:import uuid
- 15:def json_dump_safe(value):
- 23:def json_load_safe(value, default=None):
- 33:def _putconn(connection_pool, conn):
- 38:def create_persistent_job(connection_pool, logger, job_id, initial_data=None):
- 63:def update_persistent_job(connection_pool, logger, job_id, **fields):
- 107:def get_persistent_job(connection_pool, logger, job_id):
web/python-web-app/src/services/regeneration_service.py
- File type: Python
- 1:import os
- 4:def parse_regeneration_request_payload(payload):
- 16:def build_regeneration_preview_response(result):
- 38:def parse_commit_payload(payload):
- 47:def validate_commit_session(session_snapshot, decision, gcs_available):
- 63:def resolve_regenerated_text_content(session_snapshot):
- 79:def build_commit_regeneration_response(
- 110:def validate_regen_identifier(regen_id):
web/python-web-app/src/services/pronunciation_service.py
- File type: Python
- 6:def _edge_pronunciation_failure_payload(edge_result):
- 13:def _edge_entries(edge_result):
- 19:def _legacy_entry_from_edge(entry):
- 27:def _find_edge_entry(entries, term):
- 36:def _unauthorized_payload():
- 40:def _log_local_failure(logger, *, operation, exc):
- 49:def list_local_pronunciations_for_endpoint(*, connection_pool, logger=None):
- 58:def get_local_pronunciation_for_endpoint(*, connection_pool, term, logger=None):
web/python-web-app/src/services/cache_service.py
- File type: Python
- 1:import os
- 2:import shutil
- 5:def build_category_stats(metadata):
- 20:def build_cache_status_payload(cache_dir, cache_size_mb, cache_max_size_mb, cleanup_threshold_mb, metadata):
- 32:def clear_cache_entries(cache_dir, metadata, categories_to_clear, init_cache_fn):
- 65:def build_cache_cleanup_payload(initial_size_mb, final_size_mb):
web/python-web-app/src/services/combined_service.py
- File type: Python
- 1:import json
- 2:import math
- 3:import os
- 4:import re
- 5:import subprocess
- 6:from datetime import datetime, timezone
- 9:def ensure_combined_delete_allowed(
- 17:def ensure_combined_convert_allowed(storage_available, ffmpeg_available):
web/python-web-app/src/services/supabase_edge_client.py
- File type: Python
- 1:from future import annotations
- 3:import os
- 4:import time
- 5:from typing import Any, Callable
- 7:import requests
- 9:from src.services.speech_runtime_service import build_speech_runtime_error
-
| 12:def _as_bool(value: str |
None, default: bool = False) -> bool: |
- 18:def is_supabase_edge_enabled() -> bool:
web/python-web-app/src/services/soundboard_migration_service.py
- File type: Python
- 1:from future import annotations
- 3:import json
- 4:import base64
- 5:import mimetypes
- 6:import os
- 7:import time
- 8:import uuid
- 9:from dataclasses import dataclass, field
web/python-web-app/src/services/page_bootstrap_service.py
- File type: Python
- 8:from future import annotations
- 10:import os
- 11:import time
- 12:from typing import Any, Callable, Iterable, Mapping
- 14:from src.services.cache_runtime_service import resolve_static_cache_file
- 15:from src.services.static_service import infer_download_mime_type, resolve_download_file_path
- 23:def resolve_public_supabase_credentials(env_get: EnvGetter) -> tuple[str, str]:
- 32:def resolve_asset_version(
web/python-web-app/src/services/api_key_service.py
- File type: Python
- 1:from pathlib import Path
- 4:def upsert_env_key(lines, key, value):
- 22:def update_env_api_key(base_dir, api_key):
web/python-web-app/src/services/regeneration_route_service.py
- File type: Python
- 10:from future import annotations
- 12:from dataclasses import dataclass
- 13:from types import ModuleType
- 14:from typing import Any
- 16:from src.services.regeneration_service import (
- 31:class RegenerationRouteDependencies:
- 36: def getattr(self, name: str) -> Any:
- 40:def regenerate_soundboard_clip(category_id, filename, deps):
- File type: Python
- 1:from future import annotations
- 3:import datetime as dt
- 4:import json
- 5:import os
- 6:import re
- 7:import uuid
- 8:from dataclasses import dataclass
- 9:from typing import Any, Mapping
web/python-web-app/src/services/user_settings_service.py
- File type: Python
- 1:import json
- 3:from src.db_table_names import FLASK_USER_SETTINGS_KV
- 4:from src.services.theme_service import DEFAULT_THEME_ID, normalize_theme_id
- 58:def _to_float_or_default(raw_value, default_value):
- 65:def normalize_break_settings(default_break_duration, raw_break_settings=None):
- 99:def resolve_web_settings_flag(raw_value, default=False):
- 112:def strict_mode_unpersisted_request_fields(settings_data):
- 122:def attach_theme_aliases(settings_payload):
web/python-web-app/src/services/static_service.py
- File type: Python
- 1:import mimetypes
- 2:import os
- 5:def build_download_filename(last_tts_text, generate_filename_fn):
- 11:def resolve_cache_file_path(cache_dir, cache_path):
- 21:def infer_cache_mime_type(cache_path, full_cache_path):
- 44:def resolve_download_file_path(static_dir, filename):
- 54:def infer_download_mime_type(filename, file_path):
web/python-web-app/src/services/default_model_service.py
- File type: Python
- 1:def default_model_payload(default_model_id):
- 5:def _strict_edge_failure_payload(edge_result):
- 13:def _resolve_local_default_model(get_user_settings_fn, user_id, default_model_id):
- 21:def get_default_model_for_endpoint(
- 64:def update_default_model_for_endpoint(
web/python-web-app/src/services/legacy_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import importlib
- 11:import logging
- 12:import os
- 13:import sys
- 15:import requests
- 16:from flask import request
- 18:from src.services.supabase_edge_client import resolve_supabase_user_id
web/python-web-app/src/services/auth_bootstrap_service.py
- File type: Python
- 1:from future import annotations
- 3:from collections.abc import Callable, Mapping, Sequence
- 4:from typing import Any
- 5:from urllib.parse import urljoin, urlparse
-
| 17:def _parse_oauth_providers(raw_value: str |
None) -> list[str]: |
-
| 33:def _parse_sign_in_url_candidate(raw_url: str |
None) -> str |
None: |
-
| 48:def _resolve_sign_in_url(env: Mapping[str, str |
None]) -> str: |
- 60:def _resolve_sign_out_redirect_url(env: Mapping[str, str | None]) -> str:
web/python-web-app/src/services/job_status_service.py
- File type: Python
- 1:def build_job_status_payload(job_id, job_lookup):
- 8:def build_job_status_response(job_id, job_lookup):
web/python-web-app/src/services/category_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import logging
- 11:import re
- 12:import sys
- 14:from src.db_table_names import FLASK_SOUNDBOARD_CATEGORIES
- 15:from src.services import cache_runtime_service, category_runtime_service
- 16:from src.services.supabase_edge_client import resolve_supabase_user_id
- 17:from src.storage.gcs import get_blob
web/python-web-app/src/services/__init__.py
- File type: Python
web/python-web-app/src/services/tts_service.py
- File type: Python
- 1:import json
- 2:import os
- 3:from urllib.parse import quote
- 5:from src.services.speech_runtime_service import (
- 9:from src.services.supabase_edge_client import (
-
| 16:def _normalize_bearer_auth_header(auth_header: str |
None) -> str |
None: |
- 26:def _generated_audio_download_name(text: str, extension: str) -> str:
- 39:def _strict_edge_failure_blocks_legacy_fallback(
web/python-web-app/src/services/storage_provider.py
- File type: Python
- 1:from future import annotations
- 3:from dataclasses import dataclass, field
- 4:from typing import Any, Callable, Protocol
- 5:import threading
- 6:import time
- 8:import requests
- 9:import json
- 12:class StorageProvider(Protocol):
web/python-web-app/src/services/audio_preprocessing.py
- File type: Python
- 3:from future import annotations
- 5:import os
- 6:import subprocess
- 7:import time
- 8:import uuid
- 9:from dataclasses import dataclass
- 15:class PreprocessCapabilities:
- 21:def empty_capabilities() -> PreprocessCapabilities:
web/python-web-app/src/services/draft_service.py
- File type: Python
- 8:def _isoformat(value):
- 12:def list_drafts_for_endpoint(*, connection_pool, query_args, logger=None):
- 21:def create_draft_for_endpoint(*, connection_pool, request_payload, logger=None):
- 31:def list_drafts(*, connection_pool, query_args, logger=None):
- 82:def create_draft(*, connection_pool, body, logger=None):
web/python-web-app/src/services/models_service.py
- File type: Python
- 1:def _dedupe_models(models):
- 12:def fetch_models(api_key, requests_get, timeout_seconds):
web/python-web-app/src/services/cache_runtime_service.py
- File type: Python
- 8:import json
- 9:import os
- 10:import shutil
- 11:import tempfile
- 12:import time
- 14:from src.services.cache_service import build_cache_cleanup_payload, build_cache_status_payload
- 15:from src.services.static_service import infer_cache_mime_type, resolve_cache_file_path
- 25:def init_cache(*, cache_dir=None, temp_dir_factory=tempfile.gettempdir, logger=None):
web/python-web-app/src/services/soundboard_service.py
- File type: Python
- 1:def handle_delete_combined_file(
- 62:def handle_get_soundboard_clips_by_path(
- 138:def _unique_requested_names(raw_values):
- 153:def _filter_resolved_media_payload(payload, requested_filenames, requested_combined):
- 183:def handle_resolve_soundboard_clips(category_id, request_payload, runtime):
- 205: from src.services.supabase_soundboard_categories_service import (
- 249:def handle_download_combined_file(
- 281:def handle_combine_preview(category_id, request_is_json, request_data, ctx):
web/python-web-app/src/services/voices_service.py
- File type: Python
- 1:import logging
- 4:def annotate_standard_voices(voices):
- 14:def fetch_standard_voices(api_key, requests_get, timeout_seconds):
- 31:def fetch_custom_voices_from_db(connection_pool, user_id):
- 74:def build_voices_response(
web/python-web-app/src/services/settings_service.py
- File type: Python
- 1:def mask_api_key(api_key):
- 9:def handle_save_user_settings(
- 31:def handle_update_api_key(
web/python-web-app/src/services/voice_clone_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import logging
- 11:import os
- 12:import sys
- 13:import time
- 15:import requests
- 17:from src.services.supabase_edge_client import resolve_supabase_user_id
- 29:def _cleanup_old_temp_voice_samples(temp_dir, max_age_seconds=24 * 3600):
web/python-web-app/src/services/voice_clone_service.py
- File type: Python
- 1:import io
- 2:import os
- 3:import re
- 4:import time
- 5:import hashlib
- 6:import base64
- 9:def parse_create_voice_clone_request(data):
- 39:def enforce_upload_rate_limit(
web/python-web-app/src/services/settings_route_dependencies.py
- File type: Python
- 8:from future import annotations
- 10:import logging
- 11:import os
- 12:import sys
- 14:from src.services.api_key_service import update_env_api_key
- 15:from src.services.settings_service import mask_api_key
- 16:from src.services.supabase_edge_client import resolve_supabase_user_id
- 17:from src.services.user_settings_service import build_default_settings, fetch_user_settings, persist_user_settings as _persist_user_settings
web/python-web-app/src/services/legacy_runtime_adapter.py
- File type: Python
- 12:from src import legacy_runtime as _legacy_runtime
- 15:def getattr(name):
- 19:def setattr(name, value):
web/python-web-app/src/services/category_runtime_service.py
- File type: Python
- 8:from src.db_table_names import FLASK_SOUNDBOARD_CATEGORIES
- 11:def category_mgmt_enabled(enable_category_management):
- 15:def ensure_category(
- 62:def seed_legacy_categories(
- 125:def provision_gcs_category(
- 172:def copy_gcs_prefix(
- 219:def move_gcs_prefix(
- 245:def is_descendant(
web/python-web-app/src/services/strict_soundboard_service.py
- File type: Python
- 7:from future import annotations
- 9:import os
- 10:import uuid
- 11:import json
- 12:from dataclasses import dataclass
- 13:from typing import Any, Protocol
- 16:class ClipTextFetchError(Exception):
- 19: def init(self, message: str, *, reason: str = “unknown”):
web/python-web-app/src/services/speech_route_dependencies.py
- File type: Python
- 9:from future import annotations
- 11:import logging
- 12:import os
- 13:import sys
- 15:import requests
- 17:from src.services.models_service import fetch_models
- 18:from src.services.speech_service import (
- 30:from src.services.stt_input_capture_service import (
web/python-web-app/src/services/theme_service.py
- File type: Python
- 20:def normalize_theme_id(theme_id):
- 34:def resolve_effective_theme(signed_in, account_theme_id, local_theme_id):
web/python-web-app/src/services/soundboard_route_service.py
- File type: Python
- 9:from future import annotations
- 11:from dataclasses import dataclass
- 12:from types import ModuleType
- 13:from typing import Any
- 17:class SoundboardRouteDependencies:
- 22: def getattr(self, name: str) -> Any:
- 26:def _smart_cache_covers_storage_order(category_id, cached_clip_count, deps):
- 54:def _coerce_metadata_number(value):
web/python-web-app/src/services/clips_service.py
- File type: Python
- 1:import os
- 4:def load_clips_by_path(
- 36: def build_clip(filename):
- 134:def load_clips_by_path_with_provider(
- 166: def build_clip(filename):
- 282:def _relative_path(full_path: str, prefix: str) -> str:
web/python-web-app/src/services/legacy_runtime_bootstrap_service.py
- File type: Python
- 10:from future import annotations
- 12:import logging
- 13:import os
- 14:import subprocess
- 15:import tempfile
- 16:import threading
- 17:from dataclasses import dataclass, field
- 18:from pathlib import Path
web/python-web-app/src/services/stt_service.py
- File type: Python
- 1:import base64
- 2:import os
- 3:from urllib.parse import quote
- 5:from src.services.audio_preprocessing import (
- 12:from src.services.speech_runtime_service import (
- 16:from src.services.speech_service import get_audio_mime_type, transcribe_audio_file_from_path
- 17:from src.services.supabase_edge_client import (
- 23:def _generated_audio_download_name(text: str, extension: str) -> str:
web/python-web-app/src/services/category_service.py
- File type: Python
- 1:import logging
- 3:from src.db_table_names import FLASK_SOUNDBOARD_CATEGORIES
- 9:def _normalize_optional_int(value, field_name):
- 18:def normalize_create_category_payload(payload):
- 32:def fetch_categories_tree(connection_pool, fetch_categories_fn, build_tree_fn):
- 47:def normalize_reorder_payload(payload):
- 54:def update_category(
- 179:def reorder_categories(
web/python-web-app/src/services/auth_service.py
- File type: Python
- 1:from future import annotations
- 3:from src.services.auth_bootstrap_service import ( # noqa: F401
web/python-web-app/src/services/speech_runtime_service.py
- File type: Python
- 1:from future import annotations
- 3:import os
- 4:import re
- 5:import uuid
- 6:from typing import Any
- 14:def _sanitize_detail_value(value: Any) -> Any:
-
| 30:def _sanitize_details(details: dict[str, Any] |
None) -> dict[str, Any] |
None: |
- 36:def _normalize_extension(extension: str) -> str:
web/python-web-app/src/services/combined_route_service.py
- File type: Python
- 9:from future import annotations
- 11:from dataclasses import dataclass
- 12:from types import ModuleType
- 13:from typing import Any
- 15:from src.routes.helpers import get_strict_user_id
- 19:class CombinedRouteDependencies:
- 24: def getattr(self, name: str) -> Any:
- 28:def resolve_combine_clip_filenames(
web/python-web-app/templates/partials/index_slow/settings_legacy_flat.html
- File type: HTML
- 2:<div id=”settings-form” class=”tab-content theme-panel”
- 6: <div class="settings-section">
- 8: <div class="form-group" id="settingsAccountEmailGroup" style="display:none">
- 12: <div class="buttons">
- 19: <div class="settings-section">
- 21: <div class="form-group">
web/python-web-app/templates/partials/index_slow/settings.html
- File type: HTML
- 2:<div id=”settings-form” class=”tab-content theme-panel”
- 6: <div id="settingsHub" class="settings-hub" data-testid="settings-hub-root">
- 7: <div class="settings-group">
- 8: <div class="settings-group-header">Quick Access</div>
- 9: <div class="settings-card">
- 21: <div class="settings-group">
web/python-web-app/templates/partials/index_slow/modals.html
- File type: HTML
- 2: <div id="category-select-modal" class="modal">
- 3: <div class="modal-content">
- 4: <div class="modal-header">
- 9: <div class="category-select-container">
- 31: <div class="conversion-options" style="margin-top: 12px;">
- 32: <div style="display: flex; gap: 12px; align-items: center; flex-wrap: wrap;">
web/python-web-app/templates/partials/index_slow/tts.html
- File type: HTML
- 1:<div id="tts-form" class="tab-content" style="display: block;">
- 3: <div class="tts-form-content center-content" style="width: 100%; max-width: 1200px;">
- 8: <div class=”editor-toolbar”
- 11: <div style="display:flex; align-items:center; gap:10px;">
- 12: <div id="char-counter" style="font-size: 1.05em; font-weight: 600; color: var(--primary-color);">
- 25: <div class="model-selection-container center-content">
web/python-web-app/templates/partials/index_slow/voice_cloning.html
- File type: HTML
- 1:<div id=”voice-cloning-form” class=”tab-content theme-panel”
- 7: <div class="voice-cloning-section" style="margin-bottom: 30px;">
- 9: <div id="custom-voices-list" class="custom-voices-container">
- 10: <div class="loading-placeholder" style="text-align: center; padding: 20px; color: var(--text-secondary);">
- 17: <div class="voice-cloning-section">
- 21: <div class="cloning-step" id="step-1">
web/python-web-app/templates/partials/index_slow/sts.html
- File type: HTML
- 1:<div id="sts-form" class="tab-content" style="display: none;">
- 6: <div class="sts-form-content center-content" style="width: 100%; max-width: 1200px;">
- 8: <div class="stt-section upload-section">
- 10: <div class="upload-container">
- 16: <div class="stt-section record-section">
- 19: <div class="record-controls">
web/python-web-app/templates/partials/index_slow/stt.html
- File type: HTML
- 1:<div id="stt-form" class="tab-content" style="display: none;">
- 2: <div class="stt-form-content center-content" style="width: 100%; max-width: 1200px;">
- 6: <div class="stt-section upload-section">
- 8: <div class="upload-container">
- 10: <div class="file-input-row">
- 16: <div class="stt-section record-section">
web/python-web-app/templates/partials/index_slow/soundboard.html
- File type: HTML
- 1:<div id="soundboard-form" class="tab-content" style="display: none;">
- 2: <div style="display:flex; align-items:center; justify-content:center;">
- 6: <div id="soundboard-category-surface" data-testid="soundboard-category-surface">
- 11: <div id=”soundboard-category-management-toolbar” class=”soundboard-category-management-toolbar”
- 17: <div id="soundboard-category-management-create-row" class="soundboard-category-management-create-row" style="display:none;">
- 30: <div id=”soundboard-category-management-error” class=”soundboard-category-management-error”
web/python-web-app/templates/settings.html
- File type: HTML
- 4:
- 5:
- 7:
- 78:
- 80:<body>
- 81: <main class="card">
web/python-web-app/templates/auth_callback.html
- File type: HTML
- 4:
- 5:
- 6:
- 8:
- 62:
- 95: <body>
web/python-web-app/src/jobs/job_store.py
- File type: Python
- 1:import logging
- 3:from src.services.legacy_runtime_state_service import get_legacy_runtime_state
- 4:from src.services.persistent_job_service import (
- 11:def create_job(initial_data=None):
- 22:def get_job(job_id):
- 33:def update_job(job_id, **fields):
web/python-web-app/src/jobs/__init__.py
- File type: Python
web/python-web-app/src/db_table_names.py
- File type: Python
web/python-web-app/src/app.py
- File type: Python
- 1:from flask import Flask
- 3:from src.routes.categories import bp as categories_bp
- 4:from src.routes.health import bp as health_bp
- 5:from src.routes.legacy import bp as legacy_bp
- 6:from src.routes.soundboard import bp as soundboard_bp
- 7:from src.routes.settings import bp as settings_bp
- 8:from src.routes.stt import bp as stt_bp
- 9:from src.routes.tts import bp as tts_bp
web/python-web-app/src/create_drafts_table.sql
- File type: SQL
- 1:CREATE TABLE IF NOT EXISTS drafts (
- 10:CREATE INDEX IF NOT EXISTS idx_drafts_user_route_editor_created
web/python-web-app/tests/api/test_speech_contract_hardening.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _SpeechContractProvider:
- 7: def init(self, *, fail_audio_upload=False):
- 15: def is_configured(self):
- 18: def upload_from_filename(self, blob_path, source_path, content_type=None):
- 25: def upload_text(self, blob_path, text, content_type=”text/plain; charset=utf-8”):
- 30: def generate_download_url(self, blob_path, download_filename=None, expiration_hours=1):
- 34: def list_paths(self, prefix):
web/python-web-app/src/create_table.sql
- File type: SQL
- 4:CREATE TABLE IF NOT EXISTS pronunciations (
- 11:CREATE INDEX IF NOT EXISTS idx_pronunciations_term_lower ON pronunciations (LOWER(Term));
- 14:CREATE TABLE IF NOT EXISTS clip_orders (
web/python-web-app/tests/api/test_soundboard_supabase_mode.py
- File type: Python
- 1:from unittest.mock import MagicMock
- 3:import src.legacy_runtime as legacy_runtime
- 6:class _FakeCursor:
- 7: def init(self, responses, statements):
- 11: def enter(self):
- 14: def exit(self, exc_type, exc, tb):
- 17: def execute(self, sql, params=None):
- 20: def fetchone(self):
web/python-web-app/tests/api/test_tts_soundboard_workflow_target.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _WorkflowStorageProvider:
- 7: def init(self, *, fail_audio_upload=False):
- 15: def is_configured(self):
- 18: def upload_from_filename(self, blob_path, source_path, content_type=None):
- 25: def upload_text(self, blob_path, text, content_type=”text/plain; charset=utf-8”):
- 30: def generate_download_url(
- 36: def list_paths(self, prefix):
web/python-web-app/tests/api/test_pronunciations.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _PronunciationRowCursor:
- 5: def init(self, rows=None, row=None):
- 10: def enter(self):
- 13: def exit(self, *_args):
- 16: def execute(self, statement, params=None):
- 19: def fetchall(self):
- 22: def fetchone(self):
web/python-web-app/tests/api/test_health.py
- File type: Python
- 1:def test_health_endpoint(app_client):
web/python-web-app/tests/api/test_stt.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import io
- 3:from pathlib import Path
- 5:from src.services.audio_preprocessing import empty_capabilities
- 8:def test_speech_to_text_requires_api_key(app_client, monkeypatch):
- 16:def test_speech_to_text_requires_audio_file(app_client, monkeypatch):
- 24:def test_speech_to_text_rejects_conflicting_model_ids(app_client, monkeypatch):
- 40:def test_speech_to_text_strict_preprocessing_rejection_exposes_error_metadata_and_cleans_temp_files(
web/python-web-app/tests/api/test_models.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _SettingsCursor:
- 5: def init(self, rows=None):
- 9: def enter(self):
- 12: def exit(self, *_args):
- 15: def execute(self, statement, params=None):
- 18: def fetchall(self):
- 22:class _SettingsConn:
web/python-web-app/tests/api/test_soundboard_clip_audio_mode_regression.py
- File type: Python
- 1:from unittest.mock import MagicMock
- 3:import src.legacy_runtime as legacy_runtime
- 6:def _strict_auth_headers():
- 10:def test_strict_mode_tree_policy_denial_keeps_clip_load_contract(
- 57:def test_non_strict_mode_tree_policy_denial_keeps_provider_clip_load_contract(
- 65: class _Provider:
- 66: def is_configured(self):
- 107:def test_strict_mode_tree_policy_denial_remains_deterministic_for_malformed_tree_payload(
web/python-web-app/tests/api/test_categories.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import src.routes.categories as category_routes
- 5:def _enable_strict_mode_with_user(monkeypatch, user_id=”user-1”):
- 10:def _strict_auth_headers():
- 14:def test_category_create_respects_feature_flag(app_client, monkeypatch):
- 24:def test_category_update_respects_feature_flag(app_client, monkeypatch):
- 34:def test_category_reorder_respects_feature_flag(app_client, monkeypatch):
- 45:def test_category_delete_respects_feature_flag(app_client, monkeypatch):
web/python-web-app/tests/api/test_combined_endpoints.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:class _FakeCursor:
- 5: def init(self, responses, statements):
- 9: def enter(self):
- 12: def exit(self, exc_type, exc, tb):
- 15: def execute(self, sql, params=None):
- 18: def fetchall(self):
- 23: def fetchone(self):
web/python-web-app/tests/api/test_download_combined.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_download_combined_missing_file_returns_404(app_client, monkeypatch):
- 12:def test_download_combined_blocks_path_traversal(app_client, monkeypatch):
web/python-web-app/tests/api/test_soundboard_path_clips.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:from unittest.mock import MagicMock
- 5:def test_soundboard_path_clips_requires_configured_storage_provider(
- 11: class _Provider:
- 12: def is_configured(self):
- 22:def test_soundboard_path_clips_calls_service_with_correct_params(
- 30: class _Provider:
- 31: def is_configured(self):
web/python-web-app/tests/api/test_runtime_speech_isolation.py
- File type: Python
- 1:import io
- 2:from concurrent.futures import ThreadPoolExecutor
- 3:from pathlib import Path
- 5:import src.legacy_runtime as legacy_runtime
- 8:def _extract_relative_audio_path(payload):
- 12:def _run_tts_request(index):
- 18:def _run_sts_request(index):
- 31:def test_parallel_tts_requests_return_unique_artifacts(monkeypatch, tmp_path):
web/python-web-app/tests/api/test_regeneration_endpoints.py
- File type: Python
- 1:def test_commit_regeneration_requires_regen_id(app_client):
- 8:def test_discard_regeneration_missing_session_returns_404(app_client):
- 15:def test_preview_regeneration_missing_session_returns_404(app_client):
web/python-web-app/tests/api/test_settings_security.py
- File type: Python
- 1:def test_update_api_key_endpoint_disabled_by_default(app_client):
web/python-web-app/tests/api/test_voice_clone.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import io
- 5:def test_voice_clone_upload_requires_api_key(app_client, monkeypatch):
- 13:def test_voice_clone_upload_requires_audio_file(app_client, monkeypatch):
- 21:def test_voice_clone_upload_rejects_unsupported_file_type(app_client, monkeypatch):
- 33:def test_voice_clone_create_requires_api_key(app_client, monkeypatch):
- 44:def test_voice_clone_create_requires_database(app_client, monkeypatch):
- 58:def test_voice_clone_create_requires_json_payload(app_client, monkeypatch):
web/python-web-app/tests/api/test_soundboard.py
- File type: Python
- 1:def test_unknown_job_returns_404(app_client):
- 8:def test_successful_memory_job_status_payload_shape(app_client, monkeypatch):
- 9: import src.legacy_runtime as legacy_runtime
- 29:def test_soundboard_clips_supabase_strict_mode_requires_auth(app_client, monkeypatch):
- 30: import src.legacy_runtime as legacy_runtime
web/python-web-app/tests/api/test_sts.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 2:import io
- 5:def test_speech_to_speech_requires_api_key(app_client, monkeypatch):
- 13:def test_speech_to_speech_requires_audio_file(app_client, monkeypatch):
- 21:def test_speech_to_speech_requires_selected_file(app_client, monkeypatch):
- 33:def test_speech_to_speech_rejects_blank_transcription(app_client, monkeypatch):
- 37: def _fake_transcribe(*_args, **_kwargs):
- 52:def test_speech_to_speech_passes_through_transcription_errors(app_client, monkeypatch):
web/python-web-app/tests/api/test_user_settings.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 3:from src.routes.helpers import get_strict_user_id, get_user_scope_auth_context
- 6:def test_save_user_settings_requires_payload(app_client, monkeypatch):
- 16:def test_user_settings_requires_auth_in_strict_mode(app_client, monkeypatch):
- 17: import src.legacy_runtime as legacy_runtime
- 29:def test_user_settings_requires_auth_even_when_strict_flag_disabled(
- 43:class _RuntimeStub:
- 47: def resolve_request_user_id(_auth_header):
web/python-web-app/tests/api/test_cache_endpoints.py
- File type: Python
- 1:import pytest
- 3:import src.legacy_runtime as legacy_runtime
- 7:def _allow_cache_routes_in_strict_mode(monkeypatch):
- 11:def test_cache_status_requires_configuration(app_client):
- 18:def test_cache_clear_requires_configuration(app_client):
- 25:def test_cache_cleanup_requires_configuration(app_client):
- 32:def test_static_cache_route_rejects_traversal(app_client, monkeypatch, tmp_path):
web/python-web-app/tests/api/test_tts.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_text_to_speech_requires_text(app_client):
- 15:def test_text_to_speech_rejects_overlong_text(app_client):
- 26:def test_text_to_speech_handles_generation_failure(app_client, monkeypatch):
- 27: def _boom(*_args, **_kwargs):
- 45:def test_text_to_speech_returns_artifact_fields_without_mutating_runtime_global(
- 64:def test_download_audio_uses_explicit_artifact_reference(
- 81:def test_save_clip_to_soundboard_requires_explicit_artifact_or_text(
web/python-web-app/tests/api/test_runtime_entrypoint_closure.py
- File type: Python
- 3:from future import annotations
- 5:import importlib.util
- 6:import subprocess
- 7:import sys
- 8:from pathlib import Path
- 10:import src.legacy_runtime as legacy_runtime
- 11:import src.legacy_runtime as legacy_runtime
- 12:from src.app import create_app
web/python-web-app/tests/api/test_clip_convert_endpoints.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_convert_clip_requires_gcs(app_client, monkeypatch):
- 8: class _Provider:
- 9: def is_configured(self):
- 21:def test_convert_clip_validates_format(app_client, monkeypatch):
web/python-web-app/tests/api/test_voices.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_voices_requires_api_key(app_client, monkeypatch):
- 15:def test_voices_handles_upstream_exception(app_client, monkeypatch):
- 21: def _boom(*_args, **_kwargs):
- 31:def test_voices_requires_auth_in_strict_mode(app_client, monkeypatch):
- 42:def test_voices_rejects_spoofed_user_id_in_strict_mode(app_client, monkeypatch):
- 53:def test_voices_prefers_resolved_user_id_in_strict_mode(app_client, monkeypatch):
- 62: def mock_handler(user_id, *args, **kwargs):
web/python-web-app/tests/test_web_theme_defaults.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 4:import shutil
- 5:import subprocess
- 8:def _repo_root() -> Path:
- 12:def test_legacy_index_css_uses_ios_pear_meadow_defaults():
- 27:def test_marketing_tokens_match_ios_default_semantics():
- 41:def test_auth_callback_page_uses_pear_meadow_defaults():
web/python-web-app/tests/test_settings_routes.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_default_model_get_requires_auth_in_strict_mode(app_client, monkeypatch):
- 14:def test_default_model_get_returns_model_for_authorized_user_in_strict_mode(
- 40:def test_default_model_post_requires_auth_in_strict_mode(app_client, monkeypatch):
- 50:def test_default_model_post_updates_model_for_authorized_user_in_strict_mode(
- 77:def test_default_model_put_returns_deterministic_method_error_in_strict_mode(
web/python-web-app/tests/test_settings_cta_fallbacks.py
- File type: Python
- 1:def test_settings_parity_sections_render_required_non_subscription_ctas_and_readonly_summaries(
- 4: import src.legacy_runtime as legacy_runtime
- 37:def test_settings_pro_subscription_reenable_renders_web_manage_subscription_cta(
- 40: import src.legacy_runtime as legacy_runtime
web/python-web-app/tests/test_web_app_email_signup.py
- File type: Python
- 1:from future import annotations
- 3:from html.parser import HTMLParser
- 4:from pathlib import Path
- 5:import subprocess
- 7:import src.legacy_runtime as legacy_runtime
- 30:class ElementCollector(HTMLParser):
- 31: def init(self) -> None:
- 35: def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
web/python-web-app/tests/test_storage_provider.py
- File type: Python
- 1:from src.services.storage_provider import (
- 6:from src.services import storage_provider as storage_provider_module
- 7:import json
- 8:import requests
- 11:class FakeLogger:
- 12: def init(self):
- 17: def info(self, message, *args):
- 22: def warning(self, message, *args):
web/python-web-app/tests/test_user_settings_break_migration.py
- File type: Python
- 1:import json
- 3:import src.legacy_runtime as legacy_runtime
- 5:from src.services.user_settings_service import persist_user_settings
- 8:class _FakeCursor:
- 9: def init(self):
- 12: def enter(self):
- 15: def exit(self, exc_type, exc_val, exc_tb):
- 18: def execute(self, _query, params):
web/python-web-app/tests/test_settings_parity_matrix.py
- File type: Python
- 1:from pathlib import Path
- 4:def test_settings_categories_expose_deterministic_parity_modes(app_client):
- 35:def test_settings_advanced_section_implementation_is_preserved_for_reenable():
- 52:def test_settings_shared_sections_expose_ios_android_parity_controls(app_client):
- 85:def test_settings_speech_to_speech_section_exposes_override_controls(app_client):
- 112:def test_settings_soundboard_section_exposes_cache_and_offline_controls(app_client):
web/python-web-app/tests/test_voice_clone_subscription_ui_disabled.py
- File type: Python
- 1:import re
- 3:import src.legacy_runtime as legacy_runtime
- 6:def _root_html(app_client):
- 12:def _section(html, section_id):
- 31:def _assert_no_subscription_gating_copy(surface_name, section_html):
- 48:def test_speech_and_voice_clone_sections_hide_subscription_gating_copy_by_default(
web/python-web-app/tests/test_settings_feature_flags.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 3:from src.services.user_settings_service import persist_user_settings
- 6:def test_sectioned_ui_disabled_renders_legacy_layout_marker(app_client, monkeypatch):
- 19:def test_sectioned_ui_enabled_renders_hub(app_client, monkeypatch):
- 30:def test_structured_breaks_disabled_omits_default_break_settings_on_get(
- 40: def _fake_get_user_settings(_uid):
- 66:def test_structured_breaks_disabled_persist_skips_structured_column(monkeypatch):
- 71: class _Conn:
- File type: Python
- 1:def test_session_controls_render_in_app_header_not_tab_row(app_client):
web/python-web-app/tests/test_settings_strict_mode_readonly.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_settings_parity_sections_hide_subscription_status_in_strict_mode_by_default(
- 24:def test_settings_parity_sections_show_standard_readonly_status_when_not_strict(
- 42:def test_settings_parity_sections_show_subscription_status_when_reenabled(
web/python-web-app/tests/test_soundboard_session_cache_contract.py
- File type: Python
- 1:from pathlib import Path
- 19:def _source(path):
- 23:def test_soundboard_category_switch_uses_session_payload_cache():
- 33:def test_strict_path_loader_preserves_nested_category_paths():
- 44:def test_soundboard_reorder_save_updates_cache_without_refetching_category():
- 55:def test_soundboard_tab_switch_does_not_auto_refresh_after_ten_seconds():
- 64:def test_combine_success_appends_to_soundboard_session_cache_without_refetch():
web/python-web-app/tests/test_settings_strict_mode_contract.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_strict_post_break_only_does_not_call_edge_and_reports_unpersisted(
- 14: def _capture_edge(name, method=”GET”, auth_header=None, json_payload=None, **_kw):
- 41:def test_strict_post_mixed_supported_and_break_calls_edge_with_allowed_keys_only(
- 51: def _capture_edge(name, method=”GET”, auth_header=None, json_payload=None, **_kw):
- 99:def test_strict_post_soundboard_settings_calls_edge_without_unpersisted_warning(
- 109: def _capture_edge(name, method=”GET”, auth_header=None, json_payload=None, **_kw):
- 153:def test_strict_post_empty_body_still_invalid_when_no_unpersisted_fields(
web/python-web-app/tests/test_soundboard_routes.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_soundboard_combine_post_requires_auth_in_strict_mode(app_client, monkeypatch):
- 14:def test_soundboard_combine_post_routes_past_strict_policy_with_auth(
- 31:def test_soundboard_clip_convert_post_requires_auth_in_strict_mode(
- 46:def test_soundboard_clip_convert_post_routes_past_strict_policy_with_auth(
- 63:def test_soundboard_combined_convert_post_requires_auth_in_strict_mode(
- 78:def test_soundboard_combined_convert_post_routes_past_strict_policy_with_auth(
- 95:def test_soundboard_clips_put_returns_deterministic_method_error_in_strict_mode(
web/python-web-app/tests/test_soundboard_main_tab_surface.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 6:def _repo_root() -> Path:
- 10:def _soundboard_partial() -> str:
- 23:def _legacy_css() -> str:
- 28:def _soundboard_js() -> str:
- 33:def _speech_js() -> str:
- 38:def _voice_cloning_js() -> str:
web/python-web-app/tests/test_marketing_email_signup.py
- File type: Python
- 1:from future import annotations
- 3:from html.parser import HTMLParser
- 4:from pathlib import Path
- 7:class ElementCollector(HTMLParser):
- 8: def init(self) -> None:
-
| 12: def handle_starttag(self, tag: str, attrs: list[tuple[str, str |
None]]) -> None: |
- 16:class TextCollector(HTMLParser):
- 17: def init(self) -> None:
web/python-web-app/tests/test_settings_parity_additional_sections.py
- File type: Python
- 1:def test_settings_stt_model_uses_select_picker_for_ios_parity(app_client):
- 12:def test_settings_account_and_pro_sections_include_plan_and_legal_surfaces_when_reenabled(
- 15: import src.legacy_runtime as legacy_runtime
web/python-web-app/templates/templates/index_slow.html
- File type: HTML
- 10:
- 11:
- 15:
- 2250:<body>
- 2251: <div class="page-container">
- 2252: <div class="content-container">
web/python-web-app/src/jobs/job_store.py
- File type: Python
- 1:import logging
- 3:from src.services.legacy_runtime_state_service import get_legacy_runtime_state
- 4:from src.services.persistent_job_service import (
- 11:def create_job(initial_data=None):
- 22:def get_job(job_id):
- 33:def update_job(job_id, **fields):
web/python-web-app/src/jobs/__init__.py
- File type: Python
web/python-web-app/templates/templates/index_slow.html
- File type: HTML
- 10:
- 11:
- 15:
- 2250:<body>
- 2251: <div class="page-container">
- 2252: <div class="content-container">
web/python-web-app/src/db_table_names.py
- File type: Python
web/python-web-app/src/create_user_settings_table.sql
- File type: SQL
- 2:CREATE TABLE IF NOT EXISTS flask_user_settings (
- 11:CREATE UNIQUE INDEX IF NOT EXISTS idx_flask_user_settings_name_user ON flask_user_settings (setting_name, user_id);
web/python-web-app/tests/test_web_defaults_race.py
- File type: Python
- 1:from pathlib import Path
- 7:def _static_js(name):
- 13:def _partial_template(name):
- 19:def test_post_auth_defaults_reload_forces_account_settings_refetch():
- 29:def test_user_settings_loader_rejects_stale_pre_auth_responses():
- 42:def test_settings_tab_waits_for_catalog_dropdowns_before_applying_defaults():
- 79:def test_settings_tab_sliders_display_supabase_decimals_as_percent_values():
- 108:def test_settings_tts_language_uses_provider_model_dropdown():
web/python-web-app/tests/test_settings_style_presets_api.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_settings_tts_section_renders_style_preset_controls(app_client):
- 15:def test_style_presets_get_reads_from_edge_when_available(app_client, monkeypatch):
- 20: def _edge_call(_name, **_kwargs):
- 54:def test_style_presets_get_strict_mode_fails_closed_when_edge_unavailable(
- 77:def test_style_presets_create_routes_to_edge(app_client, monkeypatch):
- 84: def _edge_call(name, **kwargs):
web/python-web-app/tests/conftest.py
- File type: Python
- 1:import pytest
- 2:import sys
- 3:import os
- 4:from pathlib import Path
- 15:import src.legacy_runtime as legacy_runtime
- 19:def app_client():
web/python-web-app/tests/unit/test_legacy_runtime_regeneration_wrapper_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src.services import regeneration_route_service
- 65:class _CallCollector(ast.NodeVisitor):
- 66: def init(self):
- 69: def visit_Call(self, node):
- 74:def _call_name(node):
web/python-web-app/tests/unit/test_legacy_runtime_storage_config_delegation.py
- File type: Python
- 1:import ast
- 2:import importlib.util
- 3:import inspect
- 4:import sys
- 5:from pathlib import Path
- 7:import pytest
- 9:import src.legacy_runtime as legacy_runtime
- 10:from src.services.storage_config_service import SupabaseStorageConfig
web/python-web-app/tests/unit/test_cache_service.py
- File type: Python
- 1:from pathlib import Path
- 3:from src.services.cache_service import (
- 10:def test_build_cache_cleanup_payload_reports_freed_space():
- 16:def test_build_cache_status_payload_includes_usage_percentage():
- 22:def test_clear_cache_entries_clears_specific_categories(tmp_path):
web/python-web-app/tests/unit/test_cache.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_cache_size_is_zero_when_cache_dir_disabled(monkeypatch):
- 9:def test_cache_metadata_is_empty_when_cache_dir_disabled(monkeypatch):
web/python-web-app/tests/unit/test_supabase_soundboard_categories_service.py
- File type: Python
- 1:import uuid
- 3:from src.services.supabase_soundboard_categories_service import (
- 11:class _Logger:
- 12: def init(self):
- 15: def error(self, message, *_args, **_kwargs):
- 19:class _FakeCursor:
- 20: def init(self, conn, outcomes):
- 25: def enter(self):
web/python-web-app/tests/unit/test_legacy_runtime_speech_service_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src import legacy_runtime
- 6:from src.routes import stt as stt_routes
- 7:from src.routes import tts as tts_routes
- 8:from src.services import speech_route_dependencies as speech_deps
- 9:from src.services import speech_service
web/python-web-app/tests/unit/test_legacy_runtime_storage_enforcement.py
- File type: Python
- 1:import os
- 2:import subprocess
- 3:import sys
- 4:from pathlib import Path
- 10:def _run_runtime_import(env_overrides):
- 37:def test_legacy_runtime_fails_fast_when_storage_backend_is_not_supabase():
- 50:def test_legacy_runtime_fails_fast_when_supabase_storage_vars_are_missing():
- 66:def test_legacy_runtime_import_succeeds_with_required_supabase_storage_vars():
web/python-web-app/tests/unit/test_postgres_connection_pool.py
- File type: Python
- 1:from psycopg2 import extensions
- 3:from src.storage import postgres
- 6:class _Logger:
- 7: def init(self):
- 12: def info(self, message, *args):
- 15: def warning(self, message, *args):
- 18: def error(self, message, *args):
- 22:class _FakeCursor:
web/python-web-app/tests/unit/test_category_service.py
- File type: Python
- 1:from src.services.category_service import (
- 12:def test_normalize_create_category_payload_requires_name():
- 17:def test_normalize_create_category_payload_limits_name_length():
- 23:def test_normalize_create_category_payload_returns_clean_values():
- 32:def test_normalize_reorder_payload_requires_non_empty_list():
- 38:def test_normalize_reorder_payload_returns_entries():
- 45:class _Logger:
- 46: def init(self):
web/python-web-app/tests/unit/test_legacy_runtime_soundboard_wrapper_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src.services import soundboard_route_service
- 59:class _CallCollector(ast.NodeVisitor):
- 60: def init(self):
- 63: def visit_Call(self, node):
- 68:def _call_name(node):
web/python-web-app/tests/unit/test_auth_service.py
- File type: Python
- 1:from src.services.auth_service import (
- 9:class _Logger:
- 10: def init(self):
- 13: def warning(self, message, *args):
- 17:def _render_logs(entries):
- 27:def test_is_explicit_local_dev_context_true_for_flask_development():
- 31:def test_is_explicit_local_dev_context_true_for_legacy_runtime_env_local():
- 35:def test_is_explicit_local_dev_context_false_for_production():
web/python-web-app/tests/unit/test_category_runtime_service.py
- File type: Python
- 1:import logging
- 3:from src.services.category_runtime_service import (
- 16:class _FakeCursor:
- 17: def init(self, responses, statements, execute_error=None):
- 22: def enter(self):
- 25: def exit(self, exc_type, exc, tb):
- 28: def execute(self, sql, params=None):
- 33: def fetchone(self):
web/python-web-app/tests/unit/test_job_status_service.py
- File type: Python
- 1:from src.services.job_status_service import build_job_status_payload, build_job_status_response
- 4:def test_build_job_status_payload_returns_none_for_missing_job():
- 9:def test_build_job_status_payload_merges_job_id_and_fields():
- 14:def test_build_job_status_response_preserves_missing_job_envelope():
- 20:def test_build_job_status_response_wraps_existing_payload():
web/python-web-app/tests/unit/test_models_service.py
- File type: Python
- 1:from src.services.models_service import fetch_models
- 4:class _Resp:
- 5: def init(self, status_code, payload):
- 9: def json(self):
- 13:def test_fetch_models_requires_api_key():
- 19:def test_fetch_models_deduplicates_by_model_id():
- 20: def _get(_url, headers=None, timeout=None):
web/python-web-app/tests/unit/test_voices_service.py
- File type: Python
- 1:from src.services.voices_service import annotate_standard_voices, build_voices_response
- 4:class _Resp:
- 5: def init(self, status_code, payload):
- 9: def json(self):
- 13:def test_annotate_standard_voices_sets_fields():
- 19:def test_build_voices_response_requires_api_key():
- 25:def test_build_voices_response_combines_custom_and_standard():
- 26: def _get(_url, headers=None, timeout=None):
web/python-web-app/tests/unit/test_cache_runtime_service.py
- File type: Python
- 1:import json
- 2:import threading
- 4:from src.services import cache_runtime_service as cache_runtime
- 7:class _Logger:
- 8: def init(self):
- 11: def debug(self, message, *args):
- 14: def info(self, message, *args):
- 17: def warning(self, message, *args):
web/python-web-app/tests/unit/test_runtime_import_boundaries.py
- File type: Python
- 1:from future import annotations
- 3:import importlib.util
- 4:import sys
- 5:import threading
- 6:from pathlib import Path
- 7:from types import SimpleNamespace
- 9:from src.jobs import job_store
- 22:def test_job_store_uses_runtime_state_without_adapter_import(monkeypatch):
web/python-web-app/tests/unit/test_soundboard_service.py
- File type: Python
- 1:from src.services.soundboard_service import (
- 8:class _Logger:
- 9: def init(self):
- 14: def error(self, message, *args, **kwargs):
- 17: def warning(self, message, *args, **kwargs):
- 20: def info(self, message, *args, **kwargs):
- 24:class _Lock:
- 25: def enter(self):
web/python-web-app/tests/unit/test_pronunciation_dictionary_models.py
- File type: Python
- 3:import pytest
- 5:from src.legacy_runtime import (
- 26:def test_model_supports_pronunciation_dictionary(model_id, expected):
- 41:def test_model_uses_v3_pause_tags(model_id, expected):
- 45:def test_apply_pronunciation_details_noop_when_model_unsupported(monkeypatch):
- 46: import src.legacy_runtime as lr
- 62:def test_apply_pronunciation_details_non_v3_uses_ssml_break_between_sentences(monkeypatch):
- 63: import src.legacy_runtime as lr
web/python-web-app/tests/unit/test_settings_service.py
- File type: Python
- 1:from src.services.settings_service import handle_save_user_settings, handle_update_api_key
- 4:class _Logger:
- 5: def init(self):
- 8: def error(self, message):
- 12:def test_handle_update_api_key_rejects_when_disabled():
- 25:def test_handle_update_api_key_returns_success_and_key():
- 38:def test_handle_save_user_settings_wraps_exception():
- 41: def _boom(*_args):
web/python-web-app/tests/unit/test_legacy_runtime_cache_job_delegation.py
- File type: Python
- 1:import ast
- 2:import inspect
- 3:from pathlib import Path
- 5:import src.legacy_runtime as legacy_runtime
- 6:from src.services import cache_runtime_service
- 7:from src.services import persistent_job_service
- 59:class _CallCollector(ast.NodeVisitor):
- 60: def init(self):
web/python-web-app/tests/unit/test_strict_soundboard_service.py
- File type: Python
- 1:import logging
- 2:import json
- 4:import pytest
- 6:from src.services.strict_soundboard_service import (
- 24:class _FakeCursor:
- 25: def init(self, responses, statements, execute_error=None):
- 30: def enter(self):
- 33: def exit(self, exc_type, exc, tb):
web/python-web-app/tests/unit/test_draft_service.py
- File type: Python
- 1:import datetime
- 2:import logging
- 4:from src.services.draft_service import (
- 12:class _FakeCursor:
- 13: def init(self, responses, statements, execute_error=None):
- 18: def enter(self):
- 21: def exit(self, exc_type, exc, tb):
- 24: def execute(self, sql, params=None):
web/python-web-app/tests/unit/test_soundboard_route_service_cache_guard.py
- File type: Python
- 1:from types import SimpleNamespace
- 3:from src.services import soundboard_route_service
- 6:class _Logger:
- 7: def warning(self, *args, **kwargs):
- 11:def test_smart_cache_rejects_incomplete_order_coverage():
- 30:def test_smart_cache_accepts_complete_order_coverage():
web/python-web-app/tests/unit/test_user_settings_service.py
- File type: Python
- 1:from src.services.user_settings_service import (
- 9:def test_build_default_settings_has_expected_defaults():
- 21:def test_build_default_settings_normalizes_wrapper_defaults():
- 46:def test_resolve_web_settings_flag_parses_common_env_values():
- 83:def test_hydrate_settings_falls_back_to_default_theme_for_invalid_id():
- 91:def test_persist_user_settings_requires_payload():
- 97:def test_persist_user_settings_requires_connection_pool():
web/python-web-app/tests/unit/test_static_service.py
- File type: Python
- 1:from src.services.static_service import (
- 9:def test_build_download_filename_uses_generated_name():
- 14:def test_build_download_filename_falls_back_when_no_text():
- 19:def test_infer_cache_mime_type_falls_back_by_extension():
- 25:def test_resolve_download_file_path_rejects_path_traversal(tmp_path):
- 32:def test_resolve_download_file_path_requires_existing_file(tmp_path):
- 39:def test_infer_download_mime_type_has_fallbacks():
web/python-web-app/tests/unit/test_regeneration_service.py
- File type: Python
- 1:from src.services.regeneration_service import (
- 15:def test_parse_regeneration_request_payload_defaults():
- 22:def test_build_regeneration_preview_response_contains_expected_fields():
- 48:def test_parse_commit_payload_requires_regen_id():
- 55:def test_validate_commit_session_handles_keep_flow():
- 61:def test_resolve_regenerated_text_content_prefers_session_text(tmp_path):
- 68:def test_resolve_regenerated_text_content_reads_file(tmp_path):
- 77:def test_build_commit_regeneration_response_shape():
web/python-web-app/tests/unit/test_voice_clone_service.py
- File type: Python
- 1:from unittest.mock import MagicMock, ANY
- 2:import json
- 3:from src.services.voice_clone_service import (
- 11:def test_has_configured_storage_provider_requires_true_configuration():
- 22:def test_store_voice_clone_in_db_with_storage_provider():
- 71:def test_store_voice_clone_in_db_with_storage_provider_failure():
- 119:class _ExplodingPool:
- 120: def getconn(self):
web/python-web-app/tests/unit/test_supabase_edge_client.py
- File type: Python
- 1:from src.services.supabase_edge_client import (
- 8:from src.services.speech_runtime_service import allocate_speech_artifact
- 11:class _Logger:
- 12: def init(self):
- 17: def warning(self, message, *args):
- 20: def info(self, message, *args):
- 23: def debug(self, message, *args):
- 27:def _render_logs(entries):
web/python-web-app/tests/unit/test_supabase_storage_policy_migrations.py
- File type: Python
- 1:from pathlib import Path
- 4:def _repo_root() -> Path:
- 8:def test_storage_path_user_id_accepts_modern_uuid_versions():
web/python-web-app/tests/unit/test_persistent_job_service.py
- File type: Python
- 1:import logging
- 2:import threading
- 4:from src.services import persistent_job_service as service
- 7:class _FakeCursor:
- 8: def init(self, pool):
- 13: def enter(self):
- 16: def exit(self, exc_type, exc, tb):
- 19: def execute(self, sql, params=None):
web/python-web-app/tests/unit/test_stt_service.py
- File type: Python
- 1:import io
- 2:import json
- 4:import pytest
- 6:from src.services.audio_preprocessing import (
- 14:from src.services.stt_input_capture_service import (
- 20:from src.services.stt_service import handle_speech_to_speech, handle_speech_to_text
- 23:class _Logger:
- 24: def init(self):
web/python-web-app/tests/unit/test_legacy_runtime_low_risk_endpoint_delegation.py
- File type: Python
- 1:import ast
- 2:import inspect
- 3:from pathlib import Path
- 5:import src.legacy_runtime as legacy_runtime
- 6:from src.routes import legacy as legacy_routes
- 7:from src.services import category_runtime_service
- 8:from src.services import default_model_service
- 9:from src.services import draft_service
web/python-web-app/tests/unit/test_soundboard_route_dependencies.py
- File type: Python
- 1:from future import annotations
- 3:from types import SimpleNamespace
- 5:from src.services import soundboard_route_dependencies as deps
- 6:from src.services import supabase_soundboard_categories_service
- 7:from src.services.soundboard_service import (
- 13:class _ConfiguredProvider:
- 14: def is_configured(self):
- 18:class _CombinePreviewProvider:
web/python-web-app/tests/unit/test_storage_config_service.py
- File type: Python
- 1:import pytest
- 3:from src.services.storage_config_service import (
- 13:class FakeLogger:
- 14: def init(self):
- 17: def warning(self, message, *args):
- 21:class FakeProvider:
- 24: def init(self, *, configured=True, signed_url=”https://signed.example/clip”):
- 29: def is_configured(self):
web/python-web-app/tests/unit/test_app_factory.py
- File type: Python
- 1:from src.app import create_app
- 4:def test_create_app_returns_flask_app_with_health_route():
web/python-web-app/tests/unit/test_legacy_runtime_validation_coverage.py
- File type: Python
- 1:from future import annotations
- 3:import importlib.util
- 4:import sys
- 5:from pathlib import Path
-
| 35:def _coverage_doc(*, missing_requirement: str |
None = None, r058_status: str |
None = None, extra: str = “”) -> str: |
- 75:def _inventory_doc(*, extra: str = “”) -> str:
- 103:def _write_fixture_docs(tmp_path, coverage: str, inventory: str) -> tuple[Path, Path]:
- 111:def _messages(failures):
web/python-web-app/tests/unit/test_elevenlabs_key_resolution.py
- File type: Python
- 1:import logging
- 3:from src.services import elevenlabs_key_resolution as r
- 6:def test_parse_supabase_project_ref_from_url_extracts_ref():
- 12:def test_parse_supabase_project_ref_from_url_custom_domain_returns_none():
- 17:def test_fetch_elevenlabs_key_from_supabase_secrets_prefers_admin(monkeypatch):
- 18: class Resp:
- 21: def json(self):
- 28: def fake_get(url, headers, timeout):
web/python-web-app/tests/unit/test_user_settings_route_service.py
- File type: Python
- 1:from src.services.user_settings_service import (
- 8:def _local_settings(**overrides):
- 24:def test_get_user_settings_strict_edge_merges_synced_ids_into_local_settings():
- 86:def test_get_user_settings_non_dict_edge_json_and_settings_fall_back_to_local():
- 111:def test_save_user_settings_strict_unsupported_fields_persist_locally_when_db_available():
- 114: def save_locally(_connection_pool, data, user_id, **kwargs):
- 143:def test_save_user_settings_strict_unsupported_fields_without_db_are_acknowledged_not_persisted():
- 169:def test_save_user_settings_strict_full_tts_settings_syncs_edge_and_persists_local_fields():
web/python-web-app/tests/unit/test_legacy_runtime_auth_bootstrap_delegation.py
- File type: Python
- 1:from future import annotations
- 3:import ast
- 4:import importlib.util
- 5:import sys
- 6:from pathlib import Path
- 8:import src.legacy_runtime as legacy_runtime
- 9:import src.legacy_runtime as legacy_runtime
- 10:import src.routes.helpers as route_helpers
web/python-web-app/tests/unit/test_auth_bootstrap_service.py
- File type: Python
- 1:from src.services.auth_bootstrap_service import (
- 14:from src.services.auth_service import build_legacy_auth_bootstrap as compat_bootstrap
- 17:def test_auth_bootstrap_defaults_capture_strict_and_non_strict_modes():
- 32:def test_auth_service_reexports_bootstrap_for_migration_compatibility():
- 36:def test_auth_bootstrap_normalizes_configured_providers_from_env():
- 46:def test_normalize_oauth_providers_defaults_when_config_is_invalid():
- 52:def test_post_login_behavior_revalidates_configured_redirect_url():
- 78:def test_default_oauth_redirect_prefers_marketing_callback_from_sign_in_url():
web/python-web-app/tests/unit/test_legacy_runtime_retirement.py
- File type: Python
- 1:from future import annotations
- 3:import importlib.util
- 4:import sys
- 5:from pathlib import Path
- 7:import pytest
-
| 19:def _prior_verifier_commands(*, missing: str |
None = None) -> str: |
- 27:def _runtime_source(extra: str = “”) -> str:
- 29:from src.services import legacy_runtime_bootstrap_service
web/python-web-app/tests/unit/test_speech_service.py
- File type: Python
- 1:from src.services.speech_service import (
- 17:def test_extract_audio_file_requires_audio_field():
- 24:class _Audio:
- 25: def init(self, filename):
- 28: def seek(self, _n):
- 32:def test_extract_audio_file_requires_non_empty_filename():
- 39:def test_get_audio_mime_type_maps_extensions():
- 47:def test_model_supports_pronunciation_dictionary_rejects_empty_and_unknown_models():
web/python-web-app/tests/unit/test_tts_service.py
- File type: Python
- 1:from src.services.tts_service import (
- 7:from src.services.speech_service import apply_pronunciation_details
- 10:def _noop_apply_pronunciation(text, model):
- 14:class _Logger:
- 15: def init(self):
- 21: def error(self, message):
- 24: def warning(self, message, *args):
- 27: def debug(self, message, *args):
web/python-web-app/tests/unit/test_legacy_runtime_combine_wrapper_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src.services import combined_route_service
- 37:class _CallCollector(ast.NodeVisitor):
- 38: def init(self):
- 41: def visit_Call(self, node):
- 46:def _call_name(node):
web/python-web-app/tests/unit/test_theme_service.py
- File type: Python
- 1:from src.services.theme_service import (
- 9:def test_ios_theme_catalog_matches_full_ios_theme_ids():
- 26:def test_normalize_theme_id_falls_back_to_default_for_invalid_or_missing_values():
- 32:def test_resolve_effective_theme_prioritizes_signed_in_account_theme_over_local():
- 41:def test_resolve_effective_theme_uses_local_theme_when_signed_out():
- 50:def test_resolve_effective_theme_falls_back_to_default_when_all_candidates_invalid():
web/python-web-app/tests/unit/test_clips_service.py
- File type: Python
- 1:from src.services.clips_service import load_clips_by_path
- 4:def test_load_clips_by_path_requires_gcs():
- 21:def test_load_clips_by_path_returns_empty_payload_when_no_blobs():
web/python-web-app/tests/unit/test_pronunciation_service.py
- File type: Python
- 1:import logging
- 3:from src.services.pronunciation_service import (
- 19:def test_pronunciation_service_requires_database_for_list_get_upsert_delete():
- 37:def test_local_pronunciation_endpoint_helpers_redact_unexpected_failures():
- 38: class _FailingPool:
- 39: def getconn(self):
- 77:def test_upsert_pronunciation_requires_term():
- 78: class _Pool:
web/python-web-app/tests/unit/test_api_key_service.py
- File type: Python
- 1:from pathlib import Path
- 3:from src.services.api_key_service import upsert_env_key, update_env_api_key
- 6:def test_upsert_env_key_updates_existing_key():
- 12:def test_upsert_env_key_appends_missing_key():
- 18:def test_update_env_api_key_writes_file(tmp_path):
- 25:def test_update_env_api_key_creates_file(tmp_path):
web/python-web-app/tests/unit/test_legacy_runtime_user_settings_delegation.py
- File type: Python
- 1:import ast
- 2:import inspect
- 3:import textwrap
- 5:import src.legacy_runtime as legacy_runtime
- 6:from src.routes import legacy as legacy_routes
- 7:from src.routes import settings as settings_routes
- 18:def _function_tree(function):
- 22:def _call_chain(node):
web/python-web-app/tests/unit/test_legacy_runtime_page_bootstrap_delegation.py
- File type: Python
- 1:from future import annotations
- 3:import ast
- 4:import importlib.util
- 5:import sys
- 6:from pathlib import Path
- 8:import src.legacy_runtime as legacy_runtime
- 9:import src.app as app_module
- 10:import src.legacy_runtime as legacy_runtime
web/python-web-app/tests/unit/test_page_bootstrap_service.py
- File type: Python
- 1:from future import annotations
- 3:import pytest
- 5:from src.services import page_bootstrap_service as service
- 6:from src.services.speech_runtime_service import build_speech_runtime_error
- 9:class FakeResponse:
- 10: def init(self, body):
- 15:def _env(values):
- 19:def _jsonify(payload):
web/python-web-app/tests/unit/test_combined_service.py
- File type: Python
- 1:import pytest
- 3:from src.services.combined_service import (
- 62:class _Blob:
- 63: def init(self, exists=True):
- 67: def exists(self):
- 70: def delete(self):
- 74:def test_ensure_combined_delete_allowed_requires_storage_only():
- 84:def test_parse_convert_combined_payload_validates_inputs():
web/python-web-app/tests/unit/test_soundboard_migration_service.py
- File type: Python
- 1:from src.services.soundboard_migration_service import (
- 6:def test_build_soundboard_migration_manifest_counts_categories_and_missing_text():
- 36:def test_build_soundboard_migration_manifest_honors_excludes():
web/python-web-app/tests/test_settings_section_order.py
- File type: Python
- 1:def test_settings_categories_render_in_mobile_parity_order(app_client):
- File type: Python
- 1:from pathlib import Path
- 4:def _repo_root() -> Path:
- 8:def test_voice_clone_frontend_includes_auth_headers_for_user_scoped_requests():
- 65:def test_speech_frontend_orders_clones_first_and_warns_audio_only_download():
- 88:def test_voice_clone_frontend_uses_inline_delete_confirm_and_theme_preview_color():
web/python-web-app/src/create_background_jobs_table.sql
- File type: SQL
- 1:CREATE TABLE IF NOT EXISTS background_jobs (
- 11:CREATE INDEX IF NOT EXISTS idx_background_jobs_status ON background_jobs(status);
- 12:CREATE INDEX IF NOT EXISTS idx_background_jobs_updated_at ON background_jobs(updated_at);
web/python-web-app/src/create_custom_voices_table.sql
- File type: SQL
- 4:CREATE TABLE IF NOT EXISTS custom_voices (
- 18:CREATE INDEX IF NOT EXISTS idx_custom_voices_user_id ON custom_voices (user_id);
- 19:CREATE INDEX IF NOT EXISTS idx_custom_voices_elevenlabs_id ON custom_voices (elevenlabs_voice_id);
- 20:CREATE INDEX IF NOT EXISTS idx_custom_voices_active ON custom_voices (is_active);
- 23:CREATE OR REPLACE FUNCTION update_custom_voices_updated_at()
- 25:BEGIN
- 31:CREATE TRIGGER trigger_custom_voices_updated_at
web/python-web-app/src/create_soundboard_categories_table.sql
- File type: SQL
- 2:CREATE TABLE IF NOT EXISTS flask_soundboard_categories (
- 13:CREATE INDEX IF NOT EXISTS idx_flask_soundboard_categories_parent ON flask_soundboard_categories(parent_id);
- 14:CREATE INDEX IF NOT EXISTS idx_flask_soundboard_categories_parent_position ON flask_soundboard_categories(parent_id, position);
web/python-web-app/src/config.py
- File type: Python
- 1:from dataclasses import dataclass
- 2:import logging
- 3:import os
- 4:import sys
- 6:from src.services.elevenlabs_key_resolution import resolve_elevenlabs_api_key
- 10:class AppConfig:
-
| 19:def _as_bool(value: str |
None, default: bool) -> bool: |
- 25:def _get_optional(key: str, default: str | None = None) -> str | None:
web/python-web-app/src/__init__.py
- File type: Python
web/python-web-app/src/create_voice_samples_table.sql
- File type: SQL
- 4:CREATE TABLE IF NOT EXISTS voice_samples (
- 16:CREATE INDEX IF NOT EXISTS idx_voice_samples_voice_id ON voice_samples (voice_id);
- 17:CREATE INDEX IF NOT EXISTS idx_voice_samples_upload_date ON voice_samples (upload_date);
web/python-web-app/src/storage/gcs.py
- File type: Python
- 1:import os
- 2:import tempfile
- 3:import json
- 4:import datetime
- 6:from google.cloud import storage
- 9:def initialize_gcs(bucket_name, key_filename, logger):
- 75:def apply_gcs_billing_project(bucket, billing_project, logger):
- 85:def get_blob(bucket, blob_path):
web/python-web-app/src/storage/__init__.py
- File type: Python
web/python-web-app/src/storage/postgres.py
- File type: Python
- 1:from future import annotations
- 3:from typing import Any
- 5:from psycopg2 import OperationalError, extensions, pool
- 8:class _ValidatedConnectionPool:
- 11: def init(self, raw_pool: Any, logger: Any):
- 15: def getconn(self) -> Any:
- 28: def putconn(self, conn: Any, close: bool = False) -> None:
- 31: def closeall(self) -> None:
web/python-web-app/src/routes/stt.py
- File type: Python
- 1:from flask import Blueprint, jsonify, request
- 3:from src.services import speech_route_dependencies as speech_deps
- 4:from src.services.stt_service import handle_speech_to_speech, handle_speech_to_text
- 10:def _log_realtime_edge_result(function_name, status, payload, edge_result):
- 27:def _proxy_realtime_edge_function(function_name, json_payload):
- 62:def speech_to_text():
- 93:def sts_realtime_session():
- 101:def sts_near_realtime_session():
web/python-web-app/src/routes/helpers.py
- File type: Python
- 1:import os
- 3:from flask import jsonify
- 5:from src.services.auth_bootstrap_service import (
- 12:def _jsonify_error_response(error_response):
- 19:def get_user_scope_auth_context(runtime, auth_header, requested_user_id=None):
- 44:def get_strict_user_id(runtime, auth_header):
web/python-web-app/src/routes/soundboard.py
- File type: Python
- 1:from flask import Blueprint, g, jsonify, request
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services.soundboard_service import (
- 14:from src.services.soundboard_route_service import (
- 17:from src.services.supabase_soundboard_categories_service import move_clip_for_user
- 24:def block_soundboard_routes_in_strict_mode():
- 25: from src.services import soundboard_route_dependencies as runtime
- 62:def convert_soundboard_clip(category_id, filename):
web/python-web-app/src/routes/settings.py
- File type: Python
- 1:from flask import Blueprint, jsonify, render_template, request
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services.settings_service import (
- 8:from src.services.user_settings_service import (
- 12:from src.services.theme_service import normalize_theme_id
- 18:def _is_paid_plan_tier(plan_tier):
- 23:def _fetch_plan_tier_from_local_db(connection_pool, user_id):
- 68:def settings_page():
web/python-web-app/src/routes/__init__.py
- File type: Python
web/python-web-app/src/routes/tts.py
- File type: Python
- 1:from flask import Blueprint, Response, jsonify, request, stream_with_context
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services import speech_route_dependencies as speech_deps
- 5:from src.services.tts_service import (
- 16:def _is_dev_unauth_smoke_mode(_runtime_state, auth_header):
- 29:def get_models():
- 47:def text_to_speech():
- 83:def text_to_speech_stream():
web/python-web-app/src/routes/categories.py
- File type: Python
- 1:from flask import Blueprint, jsonify, request
- 3:from src.routes.helpers import get_user_scope_auth_context
- 4:from src.services.category_service import (
- 11:from src.services.supabase_soundboard_categories_service import (
- 26:def _strict_user_or_error(runtime):
- 34:def get_soundboard_categories_tree():
- 35: from src.services import category_route_dependencies as runtime
- 56:def create_soundboard_category():
web/python-web-app/src/routes/health.py
- File type: Python
- 1:from flask import Blueprint, jsonify, make_response
- 3:from src.services import page_bootstrap_service
- 10:def health():
- 15:def deploy_version():
web/python-web-app/src/routes/legacy.py
- File type: Python
- 1:from flask import Blueprint, jsonify, render_template, request
- 2:from werkzeug.exceptions import MethodNotAllowed
- 3:from urllib.parse import urlencode, urlparse
- 5:from src.routes.helpers import get_user_scope_auth_context
- 6:from src.services.auth_bootstrap_service import (
- 22:from src.services.default_model_service import (
- 26:from src.services.pronunciation_service import (
- 60:def _jsonify_error_response(error_response):
web/python-web-app/src/routes/voice_clone.py
- File type: Python
- 1:from flask import Blueprint, jsonify, request
- 2:import json
- 4:from src.routes.helpers import get_user_scope_auth_context
- 5:from src.services import voice_clone_route_dependencies as voice_deps
- 6:from src.services.voice_clone_service import (
- 20:def voice_clone_upload():
- 37:def voice_clone_preflight():
- 64:def voice_clone_create():
web/python-web-app/tests/test_product_workflow_target_brief.py
- File type: Python
- 1:from pathlib import Path
- 3:import pytest
- 42:class BriefValidationError(AssertionError):
- 46:def _read_brief() -> str:
- 53:def _section(text: str, heading: str) -> str:
- 64:def _assert_brief_contract(text: str) -> None:
- 101:def test_product_workflow_target_brief_preserves_s02_contract():
- 142:def test_product_workflow_target_brief_guard_rejects_malformed_contracts(
web/python-web-app/tests/test_web_tutorial_copy.py
- File type: Python
- 1:from future import annotations
- 3:from pathlib import Path
- 6:def _repo_root() -> Path:
- 10:def _partial(name: str) -> str:
- 23:def test_speech_instruction_copy_covers_current_save_share_and_settings_flows():
- 39:def test_soundboard_instruction_copy_covers_folder_and_clip_management():
- 50:def test_voice_clone_and_settings_instruction_copy_covers_current_guided_flow():
web/python-web-app/tests/test_soundboard_download_contract.py
- File type: Python
- 1:from pathlib import Path
- 12:def test_soundboard_download_helper_fetches_blob_before_anchor_download():
- 21:def test_soundboard_download_helper_does_not_open_new_window_fallback():
web/python-web-app/tests/test_browser_auth_bootstrap.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_index_in_strict_mode_exposes_auth_bootstrap_contract(app_client, monkeypatch):
- 46:def test_index_in_strict_mode_renders_configurable_apple_oauth_buttons(app_client, monkeypatch):
- 78:def test_index_bootstrap_link_uses_configured_sign_in_url(app_client, monkeypatch):
- 106:def test_auth_callback_forwards_to_web_public_origin(app_client, monkeypatch):
- 128:def test_auth_callback_accepts_no_trailing_slash(app_client, monkeypatch):
- 142:def test_auth_login_returns_session_payload(app_client, monkeypatch):
- 143: class _Response:
web/python-web-app/tests/test_seed_order_provider.py
- File type: Python
- 1:import json
- 3:import src.legacy_runtime as runtime
- 4:from flask import Flask
- 7:class _FakeProvider:
- 8: def init(self):
- 12: def is_configured(self):
- 15: def list_paths(self, prefix):
- 18: def read_json(self, blob_path, default):
web/python-web-app/templates/templates/soundboard/category.html
- File type: HTML
- 4:
- 8:
- 69:<body>
- 72: <div class="clips">
- 75: <div class="clip">
- 77: <div style="margin-top:6px; display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
web/python-web-app/templates/templates/soundboard/manage.html
- File type: HTML
- 4:
- 5:
- 8:
- 38:<body>
- 39: <div class="container">
- 40: <div class="split" style="justify-content: space-between;">
web/python-web-app/templates/templates/soundboard/index.html
- File type: HTML
- 4:
- 8:
- 56:<body>
web/python-web-app/templates/index_slow.html
- File type: HTML
- 11:
- 12:
- 14:
- 15:
- 16:
- 17:
web/marketing/assets/README.md
- File type: Other
web/marketing/styles/main.css
- File type: CSS
- 11:html { scroll-behavior: smooth; font-size: 16px; }
- 13:body {
- 24:body::before {
- 34:a { color: inherit; text-decoration: none; }
- 44:.container {
- 50:.site-header {
- 61:.site-header.scrolled { border-bottom-color: var(–border-mid); }
- 63:.nav-row {
- 70:.app-store-banner {
- 85:.app-store-banner:hover {
web/marketing/styles/tokens.css
- File type: CSS
- 1::root {
- 63::root[data-ios-theme=”atomic_tangerine”] {
- 71::root[data-ios-theme=”turquoise_dream”] {
- 79::root[data-ios-theme=”celadon_garden”] {
- 87::root[data-ios-theme=”khaki_earth”] {
- 95::root[data-ios-theme=”golden_hour”] {
- 103::root[data-ios-theme=”sunset_vibes”] {
- 111::root[data-ios-theme=”mirabelle_sunrise”] {
- 119::root[data-ios-theme=”robin_egg”] {
- 127::root[data-ios-theme=”rosy_pine”] {
web/python-web-app/templates/templates/soundboard/category.html
- File type: HTML
- 4:
- 8:
- 69:<body>
- 72: <div class="clips">
- 75: <div class="clip">
- 77: <div style="margin-top:6px; display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
web/python-web-app/templates/templates/soundboard/manage.html
- File type: HTML
- 4:
- 5:
- 8:
- 38:<body>
- 39: <div class="container">
- 40: <div class="split" style="justify-content: space-between;">
web/python-web-app/templates/templates/soundboard/index.html
- File type: HTML
- 4:
- 8:
- 56:<body>
web/python-web-app/templates/index_slow.html
- File type: HTML
- File type: Python
- 1:from pathlib import Path
- 4:def _repo_root() -> Path:
- 8:def test_voice_clone_frontend_includes_auth_headers_for_user_scoped_requests():
- 65:def test_speech_frontend_orders_clones_first_and_warns_audio_only_download():
- 88:def test_voice_clone_frontend_uses_inline_delete_confirm_and_theme_preview_color():
web/python-web-app/tests/test_settings_section_order.py
- File type: Python
- 1:def test_settings_categories_render_in_mobile_parity_order(app_client):
web/python-web-app/templates/soundboard/category.html
- File type: HTML
- 5:
- 9:
- 80:<body>
- 83: <div class="clips">
- 86: <div class="clip">
- 88: <div style="margin-top:6px; display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
web/python-web-app/templates/soundboard/manage.html
- File type: HTML
- 5:
- 6:
- 9:
- 172:<body>
- 173: <div class="container">
- 174: <div class="split" style="justify-content: space-between;">
web/python-web-app/templates/soundboard/index.html
- File type: HTML
- 5:
- 9:
- 63:<body>
web/marketing/index.html
- File type: HTML
- 4:
- 5:
- 7:
- 8:
- 11:
- 12:
web/python-web-app/README_CONTEXT.md
- File type: Other
web/python-web-app/tests/unit/test_legacy_runtime_regeneration_wrapper_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src.services import regeneration_route_service
- 65:class _CallCollector(ast.NodeVisitor):
- 66: def init(self):
- 69: def visit_Call(self, node):
- 74:def _call_name(node):
web/python-web-app/tests/unit/test_legacy_runtime_storage_config_delegation.py
- File type: Python
- 1:import ast
- 2:import importlib.util
- 3:import inspect
- 4:import sys
- 5:from pathlib import Path
- 7:import pytest
- 9:import src.legacy_runtime as legacy_runtime
- 10:from src.services.storage_config_service import SupabaseStorageConfig
web/python-web-app/tests/unit/test_cache_service.py
- File type: Python
- 1:from pathlib import Path
- 3:from src.services.cache_service import (
- 10:def test_build_cache_cleanup_payload_reports_freed_space():
- 16:def test_build_cache_status_payload_includes_usage_percentage():
- 22:def test_clear_cache_entries_clears_specific_categories(tmp_path):
web/python-web-app/tests/unit/test_cache.py
- File type: Python
- 1:import src.legacy_runtime as legacy_runtime
- 4:def test_cache_size_is_zero_when_cache_dir_disabled(monkeypatch):
- 9:def test_cache_metadata_is_empty_when_cache_dir_disabled(monkeypatch):
web/python-web-app/tests/unit/test_supabase_soundboard_categories_service.py
- File type: Python
- 1:import uuid
- 3:from src.services.supabase_soundboard_categories_service import (
- 11:class _Logger:
- 12: def init(self):
- 15: def error(self, message, *_args, **_kwargs):
- 19:class _FakeCursor:
- 20: def init(self, conn, outcomes):
- 25: def enter(self):
web/python-web-app/tests/unit/test_legacy_runtime_speech_service_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src import legacy_runtime
- 6:from src.routes import stt as stt_routes
- 7:from src.routes import tts as tts_routes
- 8:from src.services import speech_route_dependencies as speech_deps
- 9:from src.services import speech_service
web/python-web-app/tests/unit/test_legacy_runtime_storage_enforcement.py
- File type: Python
- 1:import os
- 2:import subprocess
- 3:import sys
- 4:from pathlib import Path
- 10:def _run_runtime_import(env_overrides):
- 37:def test_legacy_runtime_fails_fast_when_storage_backend_is_not_supabase():
- 50:def test_legacy_runtime_fails_fast_when_supabase_storage_vars_are_missing():
- 66:def test_legacy_runtime_import_succeeds_with_required_supabase_storage_vars():
web/python-web-app/tests/unit/test_postgres_connection_pool.py
- File type: Python
- 1:from psycopg2 import extensions
- 3:from src.storage import postgres
- 6:class _Logger:
- 7: def init(self):
- 12: def info(self, message, *args):
- 15: def warning(self, message, *args):
- 18: def error(self, message, *args):
- 22:class _FakeCursor:
web/python-web-app/tests/unit/test_category_service.py
- File type: Python
- 1:from src.services.category_service import (
- 12:def test_normalize_create_category_payload_requires_name():
- 17:def test_normalize_create_category_payload_limits_name_length():
- 23:def test_normalize_create_category_payload_returns_clean_values():
- 32:def test_normalize_reorder_payload_requires_non_empty_list():
- 38:def test_normalize_reorder_payload_returns_entries():
- 45:class _Logger:
- 46: def init(self):
web/python-web-app/tests/unit/test_legacy_runtime_soundboard_wrapper_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src.services import soundboard_route_service
- 59:class _CallCollector(ast.NodeVisitor):
- 60: def init(self):
- 63: def visit_Call(self, node):
- 68:def _call_name(node):
web/python-web-app/tests/unit/test_auth_service.py
- File type: Python
- 1:from src.services.auth_service import (
- 9:class _Logger:
- 10: def init(self):
- 13: def warning(self, message, *args):
- 17:def _render_logs(entries):
- 27:def test_is_explicit_local_dev_context_true_for_flask_development():
- 31:def test_is_explicit_local_dev_context_true_for_legacy_runtime_env_local():
- 35:def test_is_explicit_local_dev_context_false_for_production():
web/python-web-app/tests/unit/test_category_runtime_service.py
- File type: Python
- 1:import logging
- 3:from src.services.category_runtime_service import (
- 16:class _FakeCursor:
- 17: def init(self, responses, statements, execute_error=None):
- 22: def enter(self):
- 25: def exit(self, exc_type, exc, tb):
- 28: def execute(self, sql, params=None):
- 33: def fetchone(self):
web/python-web-app/tests/unit/test_job_status_service.py
- File type: Python
- 1:from src.services.job_status_service import build_job_status_payload, build_job_status_response
- 4:def test_build_job_status_payload_returns_none_for_missing_job():
- 9:def test_build_job_status_payload_merges_job_id_and_fields():
- 14:def test_build_job_status_response_preserves_missing_job_envelope():
- 20:def test_build_job_status_response_wraps_existing_payload():
web/python-web-app/tests/unit/test_models_service.py
- File type: Python
- 1:from src.services.models_service import fetch_models
- 4:class _Resp:
- 5: def init(self, status_code, payload):
- 9: def json(self):
- 13:def test_fetch_models_requires_api_key():
- 19:def test_fetch_models_deduplicates_by_model_id():
- 20: def _get(_url, headers=None, timeout=None):
web/python-web-app/tests/unit/test_voices_service.py
- File type: Python
- 1:from src.services.voices_service import annotate_standard_voices, build_voices_response
- 4:class _Resp:
- 5: def init(self, status_code, payload):
- 9: def json(self):
- 13:def test_annotate_standard_voices_sets_fields():
- 19:def test_build_voices_response_requires_api_key():
- 25:def test_build_voices_response_combines_custom_and_standard():
- 26: def _get(_url, headers=None, timeout=None):
web/python-web-app/tests/unit/test_cache_runtime_service.py
- File type: Python
- 1:import json
- 2:import threading
- 4:from src.services import cache_runtime_service as cache_runtime
- 7:class _Logger:
- 8: def init(self):
- 11: def debug(self, message, *args):
- 14: def info(self, message, *args):
- 17: def warning(self, message, *args):
web/python-web-app/tests/unit/test_runtime_import_boundaries.py
- File type: Python
- 1:from future import annotations
- 3:import importlib.util
- 4:import sys
- 5:import threading
- 6:from pathlib import Path
- 7:from types import SimpleNamespace
- 9:from src.jobs import job_store
- 22:def test_job_store_uses_runtime_state_without_adapter_import(monkeypatch):
web/python-web-app/tests/unit/test_soundboard_service.py
- File type: Python
- 1:from src.services.soundboard_service import (
- 8:class _Logger:
- 9: def init(self):
- 14: def error(self, message, *args, **kwargs):
- 17: def warning(self, message, *args, **kwargs):
- 20: def info(self, message, *args, **kwargs):
- 24:class _Lock:
- 25: def enter(self):
web/python-web-app/tests/unit/test_pronunciation_dictionary_models.py
- File type: Python
- 3:import pytest
- 5:from src.legacy_runtime import (
- 26:def test_model_supports_pronunciation_dictionary(model_id, expected):
- 41:def test_model_uses_v3_pause_tags(model_id, expected):
- 45:def test_apply_pronunciation_details_noop_when_model_unsupported(monkeypatch):
- 46: import src.legacy_runtime as lr
- 62:def test_apply_pronunciation_details_non_v3_uses_ssml_break_between_sentences(monkeypatch):
- 63: import src.legacy_runtime as lr
web/python-web-app/tests/unit/test_settings_service.py
- File type: Python
- 1:from src.services.settings_service import handle_save_user_settings, handle_update_api_key
- 4:class _Logger:
- 5: def init(self):
- 8: def error(self, message):
- 12:def test_handle_update_api_key_rejects_when_disabled():
- 25:def test_handle_update_api_key_returns_success_and_key():
- 38:def test_handle_save_user_settings_wraps_exception():
- 41: def _boom(*_args):
web/python-web-app/tests/unit/test_legacy_runtime_cache_job_delegation.py
- File type: Python
- 1:import ast
- 2:import inspect
- 3:from pathlib import Path
- 5:import src.legacy_runtime as legacy_runtime
- 6:from src.services import cache_runtime_service
- 7:from src.services import persistent_job_service
- 59:class _CallCollector(ast.NodeVisitor):
- 60: def init(self):
web/python-web-app/tests/unit/test_strict_soundboard_service.py
- File type: Python
- 1:import logging
- 2:import json
- 4:import pytest
- 6:from src.services.strict_soundboard_service import (
- 24:class _FakeCursor:
- 25: def init(self, responses, statements, execute_error=None):
- 30: def enter(self):
- 33: def exit(self, exc_type, exc, tb):
web/python-web-app/tests/unit/test_draft_service.py
- File type: Python
- 1:import datetime
- 2:import logging
- 4:from src.services.draft_service import (
- 12:class _FakeCursor:
- 13: def init(self, responses, statements, execute_error=None):
- 18: def enter(self):
- 21: def exit(self, exc_type, exc, tb):
- 24: def execute(self, sql, params=None):
web/python-web-app/tests/unit/test_soundboard_route_service_cache_guard.py
- File type: Python
- 1:from types import SimpleNamespace
- 3:from src.services import soundboard_route_service
- 6:class _Logger:
- 7: def warning(self, *args, **kwargs):
- 11:def test_smart_cache_rejects_incomplete_order_coverage():
- 30:def test_smart_cache_accepts_complete_order_coverage():
web/python-web-app/tests/unit/test_user_settings_service.py
- File type: Python
- 1:from src.services.user_settings_service import (
- 9:def test_build_default_settings_has_expected_defaults():
- 21:def test_build_default_settings_normalizes_wrapper_defaults():
- 46:def test_resolve_web_settings_flag_parses_common_env_values():
- 83:def test_hydrate_settings_falls_back_to_default_theme_for_invalid_id():
- 91:def test_persist_user_settings_requires_payload():
- 97:def test_persist_user_settings_requires_connection_pool():
web/python-web-app/tests/unit/test_static_service.py
- File type: Python
- 1:from src.services.static_service import (
- 9:def test_build_download_filename_uses_generated_name():
- 14:def test_build_download_filename_falls_back_when_no_text():
- 19:def test_infer_cache_mime_type_falls_back_by_extension():
- 25:def test_resolve_download_file_path_rejects_path_traversal(tmp_path):
- 32:def test_resolve_download_file_path_requires_existing_file(tmp_path):
- 39:def test_infer_download_mime_type_has_fallbacks():
web/python-web-app/tests/unit/test_regeneration_service.py
- File type: Python
- 1:from src.services.regeneration_service import (
- 15:def test_parse_regeneration_request_payload_defaults():
- 22:def test_build_regeneration_preview_response_contains_expected_fields():
- 48:def test_parse_commit_payload_requires_regen_id():
- 55:def test_validate_commit_session_handles_keep_flow():
- 61:def test_resolve_regenerated_text_content_prefers_session_text(tmp_path):
- 68:def test_resolve_regenerated_text_content_reads_file(tmp_path):
- 77:def test_build_commit_regeneration_response_shape():
web/python-web-app/tests/unit/test_voice_clone_service.py
- File type: Python
- 1:from unittest.mock import MagicMock, ANY
- 2:import json
- 3:from src.services.voice_clone_service import (
- 11:def test_has_configured_storage_provider_requires_true_configuration():
- 22:def test_store_voice_clone_in_db_with_storage_provider():
- 71:def test_store_voice_clone_in_db_with_storage_provider_failure():
- 119:class _ExplodingPool:
- 120: def getconn(self):
web/python-web-app/tests/unit/test_supabase_edge_client.py
- File type: Python
- 1:from src.services.supabase_edge_client import (
- 8:from src.services.speech_runtime_service import allocate_speech_artifact
- 11:class _Logger:
- 12: def init(self):
- 17: def warning(self, message, *args):
- 20: def info(self, message, *args):
- 23: def debug(self, message, *args):
- 27:def _render_logs(entries):
web/python-web-app/tests/unit/test_supabase_storage_policy_migrations.py
- File type: Python
- 1:from pathlib import Path
- 4:def _repo_root() -> Path:
- 8:def test_storage_path_user_id_accepts_modern_uuid_versions():
web/python-web-app/tests/unit/test_persistent_job_service.py
- File type: Python
- 1:import logging
- 2:import threading
- 4:from src.services import persistent_job_service as service
- 7:class _FakeCursor:
- 8: def init(self, pool):
- 13: def enter(self):
- 16: def exit(self, exc_type, exc, tb):
- 19: def execute(self, sql, params=None):
web/python-web-app/tests/unit/test_stt_service.py
- File type: Python
- 1:import io
- 2:import json
- 4:import pytest
- 6:from src.services.audio_preprocessing import (
- 14:from src.services.stt_input_capture_service import (
- 20:from src.services.stt_service import handle_speech_to_speech, handle_speech_to_text
- 23:class _Logger:
- 24: def init(self):
web/python-web-app/tests/unit/test_legacy_runtime_low_risk_endpoint_delegation.py
- File type: Python
- 1:import ast
- 2:import inspect
- 3:from pathlib import Path
- 5:import src.legacy_runtime as legacy_runtime
- 6:from src.routes import legacy as legacy_routes
- 7:from src.services import category_runtime_service
- 8:from src.services import default_model_service
- 9:from src.services import draft_service
web/python-web-app/tests/unit/test_soundboard_route_dependencies.py
- File type: Python
- 1:from future import annotations
- 3:from types import SimpleNamespace
- 5:from src.services import soundboard_route_dependencies as deps
- 6:from src.services import supabase_soundboard_categories_service
- 7:from src.services.soundboard_service import (
- 13:class _ConfiguredProvider:
- 14: def is_configured(self):
- 18:class _CombinePreviewProvider:
web/python-web-app/tests/unit/test_storage_config_service.py
- File type: Python
- 1:import pytest
- 3:from src.services.storage_config_service import (
- 13:class FakeLogger:
- 14: def init(self):
- 17: def warning(self, message, *args):
- 21:class FakeProvider:
- 24: def init(self, *, configured=True, signed_url=”https://signed.example/clip”):
- 29: def is_configured(self):
web/python-web-app/tests/unit/test_app_factory.py
- File type: Python
- 1:from src.app import create_app
- 4:def test_create_app_returns_flask_app_with_health_route():
web/python-web-app/tests/unit/test_legacy_runtime_validation_coverage.py
- File type: Python
- 1:from future import annotations
- 3:import importlib.util
- 4:import sys
- 5:from pathlib import Path
-
| 35:def _coverage_doc(*, missing_requirement: str |
None = None, r058_status: str |
None = None, extra: str = “”) -> str: |
- 75:def _inventory_doc(*, extra: str = “”) -> str:
- 103:def _write_fixture_docs(tmp_path, coverage: str, inventory: str) -> tuple[Path, Path]:
- 111:def _messages(failures):
web/python-web-app/tests/unit/test_elevenlabs_key_resolution.py
- File type: Python
- 1:import logging
- 3:from src.services import elevenlabs_key_resolution as r
- 6:def test_parse_supabase_project_ref_from_url_extracts_ref():
- 12:def test_parse_supabase_project_ref_from_url_custom_domain_returns_none():
- 17:def test_fetch_elevenlabs_key_from_supabase_secrets_prefers_admin(monkeypatch):
- 18: class Resp:
- 21: def json(self):
- 28: def fake_get(url, headers, timeout):
web/python-web-app/tests/unit/test_user_settings_route_service.py
- File type: Python
- 1:from src.services.user_settings_service import (
- 8:def _local_settings(**overrides):
- 24:def test_get_user_settings_strict_edge_merges_synced_ids_into_local_settings():
- 86:def test_get_user_settings_non_dict_edge_json_and_settings_fall_back_to_local():
- 111:def test_save_user_settings_strict_unsupported_fields_persist_locally_when_db_available():
- 114: def save_locally(_connection_pool, data, user_id, **kwargs):
- 143:def test_save_user_settings_strict_unsupported_fields_without_db_are_acknowledged_not_persisted():
- 169:def test_save_user_settings_strict_full_tts_settings_syncs_edge_and_persists_local_fields():
web/python-web-app/tests/unit/test_legacy_runtime_auth_bootstrap_delegation.py
- File type: Python
- 1:from future import annotations
- 3:import ast
- 4:import importlib.util
- 5:import sys
- 6:from pathlib import Path
- 8:import src.legacy_runtime as legacy_runtime
- 9:import src.legacy_runtime as legacy_runtime
- 10:import src.routes.helpers as route_helpers
web/python-web-app/tests/unit/test_auth_bootstrap_service.py
- File type: Python
- 1:from src.services.auth_bootstrap_service import (
- 14:from src.services.auth_service import build_legacy_auth_bootstrap as compat_bootstrap
- 17:def test_auth_bootstrap_defaults_capture_strict_and_non_strict_modes():
- 32:def test_auth_service_reexports_bootstrap_for_migration_compatibility():
- 36:def test_auth_bootstrap_normalizes_configured_providers_from_env():
- 46:def test_normalize_oauth_providers_defaults_when_config_is_invalid():
- 52:def test_post_login_behavior_revalidates_configured_redirect_url():
- 78:def test_default_oauth_redirect_prefers_marketing_callback_from_sign_in_url():
web/python-web-app/tests/unit/test_legacy_runtime_retirement.py
- File type: Python
- 1:from future import annotations
- 3:import importlib.util
- 4:import sys
- 5:from pathlib import Path
- 7:import pytest
-
| 19:def _prior_verifier_commands(*, missing: str |
None = None) -> str: |
- 27:def _runtime_source(extra: str = “”) -> str:
- 29:from src.services import legacy_runtime_bootstrap_service
web/python-web-app/tests/unit/test_speech_service.py
- File type: Python
- 1:from src.services.speech_service import (
- 17:def test_extract_audio_file_requires_audio_field():
- 24:class _Audio:
- 25: def init(self, filename):
- 28: def seek(self, _n):
- 32:def test_extract_audio_file_requires_non_empty_filename():
- 39:def test_get_audio_mime_type_maps_extensions():
- 47:def test_model_supports_pronunciation_dictionary_rejects_empty_and_unknown_models():
web/python-web-app/tests/unit/test_tts_service.py
- File type: Python
- 1:from src.services.tts_service import (
- 7:from src.services.speech_service import apply_pronunciation_details
- 10:def _noop_apply_pronunciation(text, model):
- 14:class _Logger:
- 15: def init(self):
- 21: def error(self, message):
- 24: def warning(self, message, *args):
- 27: def debug(self, message, *args):
web/python-web-app/tests/unit/test_legacy_runtime_combine_wrapper_delegation.py
- File type: Python
- 1:import ast
- 2:from pathlib import Path
- 4:import src.legacy_runtime as legacy_runtime
- 5:from src.services import combined_route_service
- 37:class _CallCollector(ast.NodeVisitor):
- 38: def init(self):
- 41: def visit_Call(self, node):
- 46:def _call_name(node):
web/python-web-app/tests/unit/test_theme_service.py
- File type: Python
- 1:from src.services.theme_service import (
- 9:def test_ios_theme_catalog_matches_full_ios_theme_ids():
- 26:def test_normalize_theme_id_falls_back_to_default_for_invalid_or_missing_values():
- 32:def test_resolve_effective_theme_prioritizes_signed_in_account_theme_over_local():
- 41:def test_resolve_effective_theme_uses_local_theme_when_signed_out():
- 50:def test_resolve_effective_theme_falls_back_to_default_when_all_candidates_invalid():
web/python-web-app/tests/unit/test_clips_service.py
- File type: Python
- 1:from src.services.clips_service import load_clips_by_path
- 4:def test_load_clips_by_path_requires_gcs():
- 21:def test_load_clips_by_path_returns_empty_payload_when_no_blobs():
web/python-web-app/tests/unit/test_pronunciation_service.py
- File type: Python
- 1:import logging
- 3:from src.services.pronunciation_service import (
- 19:def test_pronunciation_service_requires_database_for_list_get_upsert_delete():
- 37:def test_local_pronunciation_endpoint_helpers_redact_unexpected_failures():
- 38: class _FailingPool:
- 39: def getconn(self):
- 77:def test_upsert_pronunciation_requires_term():
- 78: class _Pool:
web/python-web-app/tests/unit/test_api_key_service.py
- File type: Python
- 1:from pathlib import Path
- 3:from src.services.api_key_service import upsert_env_key, update_env_api_key
- 6:def test_upsert_env_key_updates_existing_key():
- 12:def test_upsert_env_key_appends_missing_key():
- 18:def test_update_env_api_key_writes_file(tmp_path):
- 25:def test_update_env_api_key_creates_file(tmp_path):
web/python-web-app/tests/unit/test_legacy_runtime_user_settings_delegation.py
- File type: Python
- 1:import ast
- 2:import inspect
- 3:import textwrap
- 5:import src.legacy_runtime as legacy_runtime
- 6:from src.routes import legacy as legacy_routes
- 7:from src.routes import settings as settings_routes
- 18:def _function_tree(function):
- 22:def _call_chain(node):
web/python-web-app/tests/unit/test_legacy_runtime_page_bootstrap_delegation.py
- File type: Python
- 1:from future import annotations
- 3:import ast
- 4:import importlib.util
- 5:import sys
- 6:from pathlib import Path
- 8:import src.legacy_runtime as legacy_runtime
- 9:import src.app as app_module
- 10:import src.legacy_runtime as legacy_runtime
web/python-web-app/tests/unit/test_page_bootstrap_service.py
- File type: Python
- 1:from future import annotations
- 3:import pytest
- 5:from src.services import page_bootstrap_service as service
- 6:from src.services.speech_runtime_service import build_speech_runtime_error
- 9:class FakeResponse:
- 10: def init(self, body):
- 15:def _env(values):
- 19:def _jsonify(payload):
web/python-web-app/tests/unit/test_combined_service.py
- File type: Python
- 1:import pytest
- 3:from src.services.combined_service import (
- 62:class _Blob:
- 63: def init(self, exists=True):
- 67: def exists(self):
- 70: def delete(self):
- 74:def test_ensure_combined_delete_allowed_requires_storage_only():
- 84:def test_parse_convert_combined_payload_validates_inputs():
web/python-web-app/tests/unit/test_soundboard_migration_service.py
- File type: Python
- 1:from src.services.soundboard_migration_service import (
- 6:def test_build_soundboard_migration_manifest_counts_categories_and_missing_text():
- 36:def test_build_soundboard_migration_manifest_honors_excludes():
web/python-web-app/docker-entrypoint.sh
- File type: Other
web/python-web-app/requirements-dev.txt
- File type: Other
web/python-web-app/README.md
- File type: Other
web/python-web-app/static/last_tts_text.txt
- File type: Other
web/python-web-app/templates/soundboard/category.html
- File type: HTML
- 5:
- 9:
- 80:<body>
- 83: <div class="clips">
- 86: <div class="clip">
- 88: <div style="margin-top:6px; display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
web/python-web-app/templates/soundboard/manage.html
- File type: HTML
- 5:
- 6:
- 9:
- 172:<body>
- 173: <div class="container">
- 174: <div class="split" style="justify-content: space-between;">
web/python-web-app/templates/soundboard/index.html
- File type: HTML
- 5:
- 9:
- 63:<body>
web/python-web-app/static/third_party/fontawesome/6.4.0/css/all.min.css
- File type: CSS
- 6:.fa{font-family:var(–fa-style-family,”Font Awesome 6 Free”);font-weight:var(–fa-style,900)}.fa,.fa-brands,.fa-classic,.fa-regular,.fa-sharp,.fa-solid,.fab,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(–fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-classic,.fa-regular,.fa-solid,.far,.fas{font-family:”Font Awesome 6 Free”}.fa-brands,.fab{font-family:”Font Awesome 6 Brands”}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(–fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(–fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(–fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(–fa-border-radius,.1em);border:var(–fa-border-width,.08em) var(–fa-border-style,solid) var(–fa-border-color,#eee);padding:var(–fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(–fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(–fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(–fa-animation-delay,0s);animation-delay:var(–fa-animation-delay,0s);-webkit-animation-direction:var(–fa-animation-direction,normal);animation-direction:var(–fa-animation-direction,normal);-webkit-animation-duration:var(–fa-animation-duration,1s);animation-duration:var(–fa-animation-duration,1s);-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,ease-in-out);animation-timing-function:var(–fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(–fa-animation-delay,0s);animation-delay:var(–fa-animation-delay,0s);-webkit-animation-direction:var(–fa-animation-direction,normal);animation-direction:var(–fa-animation-direction,normal);-webkit-animation-duration:var(–fa-animation-duration,1s);animation-duration:var(–fa-animation-duration,1s);-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(–fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(–fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{-webkit-animation-delay:var(–fa-animation-delay,0s);animation-delay:var(–fa-animation-delay,0s);-webkit-animation-direction:var(–fa-animation-direction,normal);animation-direction:var(–fa-animation-direction,normal);-webkit-animation-duration:var(–fa-animation-duration,1s);animation-duration:var(–fa-animation-duration,1s)}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(–fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(–fa-animation-delay,0s);animation-delay:var(–fa-animation-delay,0s);-webkit-animation-direction:var(–fa-animation-direction,normal);animation-direction:var(–fa-animation-direction,normal);-webkit-animation-duration:var(–fa-animation-duration,1s);animation-duration:var(–fa-animation-duration,1s);-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,ease-in-out);animation-timing-function:var(–fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-duration:var(–fa-animation-duration,1s);animation-duration:var(–fa-animation-duration,1s);-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,linear);animation-timing-function:var(–fa-animation-timing,linear)}.fa-shake,.fa-spin{-webkit-animation-delay:var(–fa-animation-delay,0s);animation-delay:var(–fa-animation-delay,0s);-webkit-animation-direction:var(–fa-animation-direction,normal);animation-direction:var(–fa-animation-direction,normal)}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-duration:var(–fa-animation-duration,2s);animation-duration:var(–fa-animation-duration,2s);-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,linear);animation-timing-function:var(–fa-animation-timing,linear)}.fa-spin-reverse{–fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:var(–fa-animation-direction,normal);animation-direction:var(–fa-animation-direction,normal);-webkit-animation-duration:var(–fa-animation-duration,1s);animation-duration:var(–fa-animation-duration,1s);-webkit-animation-iteration-count:var(–fa-animation-iteration-count,infinite);animation-iteration-count:var(–fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(–fa-animation-timing,steps(8));animation-timing-function:var(–fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-transition-delay:0s;transition-delay:0s;-webkit-transition-duration:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(–fa-beat-scale,1.25));transform:scale(var(–fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(–fa-beat-scale,1.25));transform:scale(var(–fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(–fa-bounce-start-scale-x,1.1),var(–fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(–fa-bounce-start-scale-x,1.1),var(–fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(–fa-bounce-jump-scale-x,.9),var(–fa-bounce-jump-scale-y,1.1)) translateY(var(–fa-bounce-height,-.5em));transform:scale(var(–fa-bounce-jump-scale-x,.9),var(–fa-bounce-jump-scale-y,1.1)) translateY(var(–fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(–fa-bounce-land-scale-x,1.05),var(–fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(–fa-bounce-land-scale-x,1.05),var(–fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(–fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(–fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(–fa-bounce-start-scale-x,1.1),var(–fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(–fa-bounce-start-scale-x,1.1),var(–fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(–fa-bounce-jump-scale-x,.9),var(–fa-bounce-jump-scale-y,1.1)) translateY(var(–fa-bounce-height,-.5em));transform:scale(var(–fa-bounce-jump-scale-x,.9),var(–fa-bounce-jump-scale-y,1.1)) translateY(var(–fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(–fa-bounce-land-scale-x,1.05),var(–fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(–fa-bounce-land-scale-x,1.05),var(–fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(–fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(–fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(–fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(–fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,to{opacity:var(–fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(–fa-beat-fade-scale,1.125));transform:scale(var(–fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,to{opacity:var(–fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(–fa-beat-fade-scale,1.125));transform:scale(var(–fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(–fa-flip-x,0),var(–fa-flip-y,1),var(–fa-flip-z,0),var(–fa-flip-angle,-180deg));transform:rotate3d(var(–fa-flip-x,0),var(–fa-flip-y,1),var(–fa-flip-z,0),var(–fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(–fa-flip-x,0),var(–fa-flip-y,1),var(–fa-flip-z,0),var(–fa-flip-angle,-180deg));transform:rotate3d(var(–fa-flip-x,0),var(–fa-flip-y,1),var(–fa-flip-z,0),var(–fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}.fa-rotate-by{-webkit-transform:rotate(var(–fa-rotate-angle,none));transform:rotate(var(–fa-rotate-angle,none))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(–fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(–fa-inverse,#fff)}
- 8:.fa-0:before{content:”\30”}.fa-1:before{content:”\31”}.fa-2:before{content:”\32”}.fa-3:before{content:”\33”}.fa-4:before{content:”\34”}.fa-5:before{content:”\35”}.fa-6:before{content:”\36”}.fa-7:before{content:”\37”}.fa-8:before{content:”\38”}.fa-9:before{content:”\39”}.fa-fill-drip:before{content:”\f576”}.fa-arrows-to-circle:before{content:”\e4bd”}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:”\f138”}.fa-at:before{content:”\40”}.fa-trash-alt:before,.fa-trash-can:before{content:”\f2ed”}.fa-text-height:before{content:”\f034”}.fa-user-times:before,.fa-user-xmark:before{content:”\f235”}.fa-stethoscope:before{content:”\f0f1”}.fa-comment-alt:before,.fa-message:before{content:”\f27a”}.fa-info:before{content:”\f129”}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:”\f422”}.fa-explosion:before{content:”\e4e9”}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:”\f15c”}.fa-wave-square:before{content:”\f83e”}.fa-ring:before{content:”\f70b”}.fa-building-un:before{content:”\e4d9”}.fa-dice-three:before{content:”\f527”}.fa-calendar-alt:before,.fa-calendar-days:before{content:”\f073”}.fa-anchor-circle-check:before{content:”\e4aa”}.fa-building-circle-arrow-right:before{content:”\e4d1”}.fa-volleyball-ball:before,.fa-volleyball:before{content:”\f45f”}.fa-arrows-up-to-line:before{content:”\e4c2”}.fa-sort-desc:before,.fa-sort-down:before{content:”\f0dd”}.fa-circle-minus:before,.fa-minus-circle:before{content:”\f056”}.fa-door-open:before{content:”\f52b”}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:”\f2f5”}.fa-atom:before{content:”\f5d2”}.fa-soap:before{content:”\e06e”}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:”\f86d”}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:”\f539”}.fa-bridge-circle-check:before{content:”\e4c9”}.fa-pump-medical:before{content:”\e06a”}.fa-fingerprint:before{content:”\f577”}.fa-hand-point-right:before{content:”\f0a4”}.fa-magnifying-glass-location:before,.fa-search-location:before{content:”\f689”}.fa-forward-step:before,.fa-step-forward:before{content:”\f051”}.fa-face-smile-beam:before,.fa-smile-beam:before{content:”\f5b8”}.fa-flag-checkered:before{content:”\f11e”}.fa-football-ball:before,.fa-football:before{content:”\f44e”}.fa-school-circle-exclamation:before{content:”\e56c”}.fa-crop:before{content:”\f125”}.fa-angle-double-down:before,.fa-angles-down:before{content:”\f103”}.fa-users-rectangle:before{content:”\e594”}.fa-people-roof:before{content:”\e537”}.fa-people-line:before{content:”\e534”}.fa-beer-mug-empty:before,.fa-beer:before{content:”\f0fc”}.fa-diagram-predecessor:before{content:”\e477”}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:”\f176”}.fa-burn:before,.fa-fire-flame-simple:before{content:”\f46a”}.fa-male:before,.fa-person:before{content:”\f183”}.fa-laptop:before{content:”\f109”}.fa-file-csv:before{content:”\f6dd”}.fa-menorah:before{content:”\f676”}.fa-truck-plane:before{content:”\e58f”}.fa-record-vinyl:before{content:”\f8d9”}.fa-face-grin-stars:before,.fa-grin-stars:before{content:”\f587”}.fa-bong:before{content:”\f55c”}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:”\f67b”}.fa-arrow-down-up-across-line:before{content:”\e4af”}.fa-spoon:before,.fa-utensil-spoon:before{content:”\f2e5”}.fa-jar-wheat:before{content:”\e517”}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:”\f674”}.fa-file-circle-exclamation:before{content:”\e4eb”}.fa-circle-h:before,.fa-hospital-symbol:before{content:”\f47e”}.fa-pager:before{content:”\f815”}.fa-address-book:before,.fa-contact-book:before{content:”\f2b9”}.fa-strikethrough:before{content:”\f0cc”}.fa-k:before{content:”\4b”}.fa-landmark-flag:before{content:”\e51c”}.fa-pencil-alt:before,.fa-pencil:before{content:”\f303”}.fa-backward:before{content:”\f04a”}.fa-caret-right:before{content:”\f0da”}.fa-comments:before{content:”\f086”}.fa-file-clipboard:before,.fa-paste:before{content:”\f0ea”}.fa-code-pull-request:before{content:”\e13c”}.fa-clipboard-list:before{content:”\f46d”}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:”\f4de”}.fa-user-check:before{content:”\f4fc”}.fa-vial-virus:before{content:”\e597”}.fa-sheet-plastic:before{content:”\e571”}.fa-blog:before{content:”\f781”}.fa-user-ninja:before{content:”\f504”}.fa-person-arrow-up-from-line:before{content:”\e539”}.fa-scroll-torah:before,.fa-torah:before{content:”\f6a0”}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:”\f458”}.fa-toggle-off:before{content:”\f204”}.fa-archive:before,.fa-box-archive:before{content:”\f187”}.fa-person-drowning:before{content:”\e545”}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:”\f886”}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:”\f58a”}.fa-spray-can:before{content:”\f5bd”}.fa-truck-monster:before{content:”\f63b”}.fa-w:before{content:”\57”}.fa-earth-africa:before,.fa-globe-africa:before{content:”\f57c”}.fa-rainbow:before{content:”\f75b”}.fa-circle-notch:before{content:”\f1ce”}.fa-tablet-alt:before,.fa-tablet-screen-button:before{content:”\f3fa”}.fa-paw:before{content:”\f1b0”}.fa-cloud:before{content:”\f0c2”}.fa-trowel-bricks:before{content:”\e58a”}.fa-face-flushed:before,.fa-flushed:before{content:”\f579”}.fa-hospital-user:before{content:”\f80d”}.fa-tent-arrow-left-right:before{content:”\e57f”}.fa-gavel:before,.fa-legal:before{content:”\f0e3”}.fa-binoculars:before{content:”\f1e5”}.fa-microphone-slash:before{content:”\f131”}.fa-box-tissue:before{content:”\e05b”}.fa-motorcycle:before{content:”\f21c”}.fa-bell-concierge:before,.fa-concierge-bell:before{content:”\f562”}.fa-pen-ruler:before,.fa-pencil-ruler:before{content:”\f5ae”}.fa-people-arrows-left-right:before,.fa-people-arrows:before{content:”\e068”}.fa-mars-and-venus-burst:before{content:”\e523”}.fa-caret-square-right:before,.fa-square-caret-right:before{content:”\f152”}.fa-cut:before,.fa-scissors:before{content:”\f0c4”}.fa-sun-plant-wilt:before{content:”\e57a”}.fa-toilets-portable:before{content:”\e584”}.fa-hockey-puck:before{content:”\f453”}.fa-table:before{content:”\f0ce”}.fa-magnifying-glass-arrow-right:before{content:”\e521”}.fa-digital-tachograph:before,.fa-tachograph-digital:before{content:”\f566”}.fa-users-slash:before{content:”\e073”}.fa-clover:before{content:”\e139”}.fa-mail-reply:before,.fa-reply:before{content:”\f3e5”}.fa-star-and-crescent:before{content:”\f699”}.fa-house-fire:before{content:”\e50c”}.fa-minus-square:before,.fa-square-minus:before{content:”\f146”}.fa-helicopter:before{content:”\f533”}.fa-compass:before{content:”\f14e”}.fa-caret-square-down:before,.fa-square-caret-down:before{content:”\f150”}.fa-file-circle-question:before{content:”\e4ef”}.fa-laptop-code:before{content:”\f5fc”}.fa-swatchbook:before{content:”\f5c3”}.fa-prescription-bottle:before{content:”\f485”}.fa-bars:before,.fa-navicon:before{content:”\f0c9”}.fa-people-group:before{content:”\e533”}.fa-hourglass-3:before,.fa-hourglass-end:before{content:”\f253”}.fa-heart-broken:before,.fa-heart-crack:before{content:”\f7a9”}.fa-external-link-square-alt:before,.fa-square-up-right:before{content:”\f360”}.fa-face-kiss-beam:before,.fa-kiss-beam:before{content:”\f597”}.fa-film:before{content:”\f008”}.fa-ruler-horizontal:before{content:”\f547”}.fa-people-robbery:before{content:”\e536”}.fa-lightbulb:before{content:”\f0eb”}.fa-caret-left:before{content:”\f0d9”}.fa-circle-exclamation:before,.fa-exclamation-circle:before{content:”\f06a”}.fa-school-circle-xmark:before{content:”\e56d”}.fa-arrow-right-from-bracket:before,.fa-sign-out:before{content:”\f08b”}.fa-chevron-circle-down:before,.fa-circle-chevron-down:before{content:”\f13a”}.fa-unlock-alt:before,.fa-unlock-keyhole:before{content:”\f13e”}.fa-cloud-showers-heavy:before{content:”\f740”}.fa-headphones-alt:before,.fa-headphones-simple:before{content:”\f58f”}.fa-sitemap:before{content:”\f0e8”}.fa-circle-dollar-to-slot:before,.fa-donate:before{content:”\f4b9”}.fa-memory:before{content:”\f538”}.fa-road-spikes:before{content:”\e568”}.fa-fire-burner:before{content:”\e4f1”}.fa-flag:before{content:”\f024”}.fa-hanukiah:before{content:”\f6e6”}.fa-feather:before{content:”\f52d”}.fa-volume-down:before,.fa-volume-low:before{content:”\f027”}.fa-comment-slash:before{content:”\f4b3”}.fa-cloud-sun-rain:before{content:”\f743”}.fa-compress:before{content:”\f066”}.fa-wheat-alt:before,.fa-wheat-awn:before{content:”\e2cd”}.fa-ankh:before{content:”\f644”}.fa-hands-holding-child:before{content:”\e4fa”}.fa-asterisk:before{content:”\2a”}.fa-check-square:before,.fa-square-check:before{content:”\f14a”}.fa-peseta-sign:before{content:”\e221”}.fa-header:before,.fa-heading:before{content:”\f1dc”}.fa-ghost:before{content:”\f6e2”}.fa-list-squares:before,.fa-list:before{content:”\f03a”}.fa-phone-square-alt:before,.fa-square-phone-flip:before{content:”\f87b”}.fa-cart-plus:before{content:”\f217”}.fa-gamepad:before{content:”\f11b”}.fa-circle-dot:before,.fa-dot-circle:before{content:”\f192”}.fa-dizzy:before,.fa-face-dizzy:before{content:”\f567”}.fa-egg:before{content:”\f7fb”}.fa-house-medical-circle-xmark:before{content:”\e513”}.fa-campground:before{content:”\f6bb”}.fa-folder-plus:before{content:”\f65e”}.fa-futbol-ball:before,.fa-futbol:before,.fa-soccer-ball:before{content:”\f1e3”}.fa-paint-brush:before,.fa-paintbrush:before{content:”\f1fc”}.fa-lock:before{content:”\f023”}.fa-gas-pump:before{content:”\f52f”}.fa-hot-tub-person:before,.fa-hot-tub:before{content:”\f593”}.fa-map-location:before,.fa-map-marked:before{content:”\f59f”}.fa-house-flood-water:before{content:”\e50e”}.fa-tree:before{content:”\f1bb”}.fa-bridge-lock:before{content:”\e4cc”}.fa-sack-dollar:before{content:”\f81d”}.fa-edit:before,.fa-pen-to-square:before{content:”\f044”}.fa-car-side:before{content:”\f5e4”}.fa-share-alt:before,.fa-share-nodes:before{content:”\f1e0”}.fa-heart-circle-minus:before{content:”\e4ff”}.fa-hourglass-2:before,.fa-hourglass-half:before{content:”\f252”}.fa-microscope:before{content:”\f610”}.fa-sink:before{content:”\e06d”}.fa-bag-shopping:before,.fa-shopping-bag:before{content:”\f290”}.fa-arrow-down-z-a:before,.fa-sort-alpha-desc:before,.fa-sort-alpha-down-alt:before{content:”\f881”}.fa-mitten:before{content:”\f7b5”}.fa-person-rays:before{content:”\e54d”}.fa-users:before{content:”\f0c0”}.fa-eye-slash:before{content:”\f070”}.fa-flask-vial:before{content:”\e4f3”}.fa-hand-paper:before,.fa-hand:before{content:”\f256”}.fa-om:before{content:”\f679”}.fa-worm:before{content:”\e599”}.fa-house-circle-xmark:before{content:”\e50b”}.fa-plug:before{content:”\f1e6”}.fa-chevron-up:before{content:”\f077”}.fa-hand-spock:before{content:”\f259”}.fa-stopwatch:before{content:”\f2f2”}.fa-face-kiss:before,.fa-kiss:before{content:”\f596”}.fa-bridge-circle-xmark:before{content:”\e4cb”}.fa-face-grin-tongue:before,.fa-grin-tongue:before{content:”\f589”}.fa-chess-bishop:before{content:”\f43a”}.fa-face-grin-wink:before,.fa-grin-wink:before{content:”\f58c”}.fa-deaf:before,.fa-deafness:before,.fa-ear-deaf:before,.fa-hard-of-hearing:before{content:”\f2a4”}.fa-road-circle-check:before{content:”\e564”}.fa-dice-five:before{content:”\f523”}.fa-rss-square:before,.fa-square-rss:before{content:”\f143”}.fa-land-mine-on:before{content:”\e51b”}.fa-i-cursor:before{content:”\f246”}.fa-stamp:before{content:”\f5bf”}.fa-stairs:before{content:”\e289”}.fa-i:before{content:”\49”}.fa-hryvnia-sign:before,.fa-hryvnia:before{content:”\f6f2”}.fa-pills:before{content:”\f484”}.fa-face-grin-wide:before,.fa-grin-alt:before{content:”\f581”}.fa-tooth:before{content:”\f5c9”}.fa-v:before{content:”\56”}.fa-bangladeshi-taka-sign:before{content:”\e2e6”}.fa-bicycle:before{content:”\f206”}.fa-rod-asclepius:before,.fa-rod-snake:before,.fa-staff-aesculapius:before,.fa-staff-snake:before{content:”\e579”}.fa-head-side-cough-slash:before{content:”\e062”}.fa-ambulance:before,.fa-truck-medical:before{content:”\f0f9”}.fa-wheat-awn-circle-exclamation:before{content:”\e598”}.fa-snowman:before{content:”\f7d0”}.fa-mortar-pestle:before{content:”\f5a7”}.fa-road-barrier:before{content:”\e562”}.fa-school:before{content:”\f549”}.fa-igloo:before{content:”\f7ae”}.fa-joint:before{content:”\f595”}.fa-angle-right:before{content:”\f105”}.fa-horse:before{content:”\f6f0”}.fa-q:before{content:”\51”}.fa-g:before{content:”\47”}.fa-notes-medical:before{content:”\f481”}.fa-temperature-2:before,.fa-temperature-half:before,.fa-thermometer-2:before,.fa-thermometer-half:before{content:”\f2c9”}.fa-dong-sign:before{content:”\e169”}.fa-capsules:before{content:”\f46b”}.fa-poo-bolt:before,.fa-poo-storm:before{content:”\f75a”}.fa-face-frown-open:before,.fa-frown-open:before{content:”\f57a”}.fa-hand-point-up:before{content:”\f0a6”}.fa-money-bill:before{content:”\f0d6”}.fa-bookmark:before{content:”\f02e”}.fa-align-justify:before{content:”\f039”}.fa-umbrella-beach:before{content:”\f5ca”}.fa-helmet-un:before{content:”\e503”}.fa-bullseye:before{content:”\f140”}.fa-bacon:before{content:”\f7e5”}.fa-hand-point-down:before{content:”\f0a7”}.fa-arrow-up-from-bracket:before{content:”\e09a”}.fa-folder-blank:before,.fa-folder:before{content:”\f07b”}.fa-file-medical-alt:before,.fa-file-waveform:before{content:”\f478”}.fa-radiation:before{content:”\f7b9”}.fa-chart-simple:before{content:”\e473”}.fa-mars-stroke:before{content:”\f229”}.fa-vial:before{content:”\f492”}.fa-dashboard:before,.fa-gauge-med:before,.fa-gauge:before,.fa-tachometer-alt-average:before{content:”\f624”}.fa-magic-wand-sparkles:before,.fa-wand-magic-sparkles:before{content:”\e2ca”}.fa-e:before{content:”\45”}.fa-pen-alt:before,.fa-pen-clip:before{content:”\f305”}.fa-bridge-circle-exclamation:before{content:”\e4ca”}.fa-user:before{content:”\f007”}.fa-school-circle-check:before{content:”\e56b”}.fa-dumpster:before{content:”\f793”}.fa-shuttle-van:before,.fa-van-shuttle:before{content:”\f5b6”}.fa-building-user:before{content:”\e4da”}.fa-caret-square-left:before,.fa-square-caret-left:before{content:”\f191”}.fa-highlighter:before{content:”\f591”}.fa-key:before{content:”\f084”}.fa-bullhorn:before{content:”\f0a1”}.fa-globe:before{content:”\f0ac”}.fa-synagogue:before{content:”\f69b”}.fa-person-half-dress:before{content:”\e548”}.fa-road-bridge:before{content:”\e563”}.fa-location-arrow:before{content:”\f124”}.fa-c:before{content:”\43”}.fa-tablet-button:before{content:”\f10a”}.fa-building-lock:before{content:”\e4d6”}.fa-pizza-slice:before{content:”\f818”}.fa-money-bill-wave:before{content:”\f53a”}.fa-area-chart:before,.fa-chart-area:before{content:”\f1fe”}.fa-house-flag:before{content:”\e50d”}.fa-person-circle-minus:before{content:”\e540”}.fa-ban:before,.fa-cancel:before{content:”\f05e”}.fa-camera-rotate:before{content:”\e0d8”}.fa-air-freshener:before,.fa-spray-can-sparkles:before{content:”\f5d0”}.fa-star:before{content:”\f005”}.fa-repeat:before{content:”\f363”}.fa-cross:before{content:”\f654”}.fa-box:before{content:”\f466”}.fa-venus-mars:before{content:”\f228”}.fa-arrow-pointer:before,.fa-mouse-pointer:before{content:”\f245”}.fa-expand-arrows-alt:before,.fa-maximize:before{content:”\f31e”}.fa-charging-station:before{content:”\f5e7”}.fa-shapes:before,.fa-triangle-circle-square:before{content:”\f61f”}.fa-random:before,.fa-shuffle:before{content:”\f074”}.fa-person-running:before,.fa-running:before{content:”\f70c”}.fa-mobile-retro:before{content:”\e527”}.fa-grip-lines-vertical:before{content:”\f7a5”}.fa-spider:before{content:”\f717”}.fa-hands-bound:before{content:”\e4f9”}.fa-file-invoice-dollar:before{content:”\f571”}.fa-plane-circle-exclamation:before{content:”\e556”}.fa-x-ray:before{content:”\f497”}.fa-spell-check:before{content:”\f891”}.fa-slash:before{content:”\f715”}.fa-computer-mouse:before,.fa-mouse:before{content:”\f8cc”}.fa-arrow-right-to-bracket:before,.fa-sign-in:before{content:”\f090”}.fa-shop-slash:before,.fa-store-alt-slash:before{content:”\e070”}.fa-server:before{content:”\f233”}.fa-virus-covid-slash:before{content:”\e4a9”}.fa-shop-lock:before{content:”\e4a5”}.fa-hourglass-1:before,.fa-hourglass-start:before{content:”\f251”}.fa-blender-phone:before{content:”\f6b6”}.fa-building-wheat:before{content:”\e4db”}.fa-person-breastfeeding:before{content:”\e53a”}.fa-right-to-bracket:before,.fa-sign-in-alt:before{content:”\f2f6”}.fa-venus:before{content:”\f221”}.fa-passport:before{content:”\f5ab”}.fa-heart-pulse:before,.fa-heartbeat:before{content:”\f21e”}.fa-people-carry-box:before,.fa-people-carry:before{content:”\f4ce”}.fa-temperature-high:before{content:”\f769”}.fa-microchip:before{content:”\f2db”}.fa-crown:before{content:”\f521”}.fa-weight-hanging:before{content:”\f5cd”}.fa-xmarks-lines:before{content:”\e59a”}.fa-file-prescription:before{content:”\f572”}.fa-weight-scale:before,.fa-weight:before{content:”\f496”}.fa-user-friends:before,.fa-user-group:before{content:”\f500”}.fa-arrow-up-a-z:before,.fa-sort-alpha-up:before{content:”\f15e”}.fa-chess-knight:before{content:”\f441”}.fa-face-laugh-squint:before,.fa-laugh-squint:before{content:”\f59b”}.fa-wheelchair:before{content:”\f193”}.fa-arrow-circle-up:before,.fa-circle-arrow-up:before{content:”\f0aa”}.fa-toggle-on:before{content:”\f205”}.fa-person-walking:before,.fa-walking:before{content:”\f554”}.fa-l:before{content:”\4c”}.fa-fire:before{content:”\f06d”}.fa-bed-pulse:before,.fa-procedures:before{content:”\f487”}.fa-shuttle-space:before,.fa-space-shuttle:before{content:”\f197”}.fa-face-laugh:before,.fa-laugh:before{content:”\f599”}.fa-folder-open:before{content:”\f07c”}.fa-heart-circle-plus:before{content:”\e500”}.fa-code-fork:before{content:”\e13b”}.fa-city:before{content:”\f64f”}.fa-microphone-alt:before,.fa-microphone-lines:before{content:”\f3c9”}.fa-pepper-hot:before{content:”\f816”}.fa-unlock:before{content:”\f09c”}.fa-colon-sign:before{content:”\e140”}.fa-headset:before{content:”\f590”}.fa-store-slash:before{content:”\e071”}.fa-road-circle-xmark:before{content:”\e566”}.fa-user-minus:before{content:”\f503”}.fa-mars-stroke-up:before,.fa-mars-stroke-v:before{content:”\f22a”}.fa-champagne-glasses:before,.fa-glass-cheers:before{content:”\f79f”}.fa-clipboard:before{content:”\f328”}.fa-house-circle-exclamation:before{content:”\e50a”}.fa-file-arrow-up:before,.fa-file-upload:before{content:”\f574”}.fa-wifi-3:before,.fa-wifi-strong:before,.fa-wifi:before{content:”\f1eb”}.fa-bath:before,.fa-bathtub:before{content:”\f2cd”}.fa-underline:before{content:”\f0cd”}.fa-user-edit:before,.fa-user-pen:before{content:”\f4ff”}.fa-signature:before{content:”\f5b7”}.fa-stroopwafel:before{content:”\f551”}.fa-bold:before{content:”\f032”}.fa-anchor-lock:before{content:”\e4ad”}.fa-building-ngo:before{content:”\e4d7”}.fa-manat-sign:before{content:”\e1d5”}.fa-not-equal:before{content:”\f53e”}.fa-border-style:before,.fa-border-top-left:before{content:”\f853”}.fa-map-location-dot:before,.fa-map-marked-alt:before{content:”\f5a0”}.fa-jedi:before{content:”\f669”}.fa-poll:before,.fa-square-poll-vertical:before{content:”\f681”}.fa-mug-hot:before{content:”\f7b6”}.fa-battery-car:before,.fa-car-battery:before{content:”\f5df”}.fa-gift:before{content:”\f06b”}.fa-dice-two:before{content:”\f528”}.fa-chess-queen:before{content:”\f445”}.fa-glasses:before{content:”\f530”}.fa-chess-board:before{content:”\f43c”}.fa-building-circle-check:before{content:”\e4d2”}.fa-person-chalkboard:before{content:”\e53d”}.fa-mars-stroke-h:before,.fa-mars-stroke-right:before{content:”\f22b”}.fa-hand-back-fist:before,.fa-hand-rock:before{content:”\f255”}.fa-caret-square-up:before,.fa-square-caret-up:before{content:”\f151”}.fa-cloud-showers-water:before{content:”\e4e4”}.fa-bar-chart:before,.fa-chart-bar:before{content:”\f080”}.fa-hands-bubbles:before,.fa-hands-wash:before{content:”\e05e”}.fa-less-than-equal:before{content:”\f537”}.fa-train:before{content:”\f238”}.fa-eye-low-vision:before,.fa-low-vision:before{content:”\f2a8”}.fa-crow:before{content:”\f520”}.fa-sailboat:before{content:”\e445”}.fa-window-restore:before{content:”\f2d2”}.fa-plus-square:before,.fa-square-plus:before{content:”\f0fe”}.fa-torii-gate:before{content:”\f6a1”}.fa-frog:before{content:”\f52e”}.fa-bucket:before{content:”\e4cf”}.fa-image:before{content:”\f03e”}.fa-microphone:before{content:”\f130”}.fa-cow:before{content:”\f6c8”}.fa-caret-up:before{content:”\f0d8”}.fa-screwdriver:before{content:”\f54a”}.fa-folder-closed:before{content:”\e185”}.fa-house-tsunami:before{content:”\e515”}.fa-square-nfi:before{content:”\e576”}.fa-arrow-up-from-ground-water:before{content:”\e4b5”}.fa-glass-martini-alt:before,.fa-martini-glass:before{content:”\f57b”}.fa-rotate-back:before,.fa-rotate-backward:before,.fa-rotate-left:before,.fa-undo-alt:before{content:”\f2ea”}.fa-columns:before,.fa-table-columns:before{content:”\f0db”}.fa-lemon:before{content:”\f094”}.fa-head-side-mask:before{content:”\e063”}.fa-handshake:before{content:”\f2b5”}.fa-gem:before{content:”\f3a5”}.fa-dolly-box:before,.fa-dolly:before{content:”\f472”}.fa-smoking:before{content:”\f48d”}.fa-compress-arrows-alt:before,.fa-minimize:before{content:”\f78c”}.fa-monument:before{content:”\f5a6”}.fa-snowplow:before{content:”\f7d2”}.fa-angle-double-right:before,.fa-angles-right:before{content:”\f101”}.fa-cannabis:before{content:”\f55f”}.fa-circle-play:before,.fa-play-circle:before{content:”\f144”}.fa-tablets:before{content:”\f490”}.fa-ethernet:before{content:”\f796”}.fa-eur:before,.fa-euro-sign:before,.fa-euro:before{content:”\f153”}.fa-chair:before{content:”\f6c0”}.fa-check-circle:before,.fa-circle-check:before{content:”\f058”}.fa-circle-stop:before,.fa-stop-circle:before{content:”\f28d”}.fa-compass-drafting:before,.fa-drafting-compass:before{content:”\f568”}.fa-plate-wheat:before{content:”\e55a”}.fa-icicles:before{content:”\f7ad”}.fa-person-shelter:before{content:”\e54f”}.fa-neuter:before{content:”\f22c”}.fa-id-badge:before{content:”\f2c1”}.fa-marker:before{content:”\f5a1”}.fa-face-laugh-beam:before,.fa-laugh-beam:before{content:”\f59a”}.fa-helicopter-symbol:before{content:”\e502”}.fa-universal-access:before{content:”\f29a”}.fa-chevron-circle-up:before,.fa-circle-chevron-up:before{content:”\f139”}.fa-lari-sign:before{content:”\e1c8”}.fa-volcano:before{content:”\f770”}.fa-person-walking-dashed-line-arrow-right:before{content:”\e553”}.fa-gbp:before,.fa-pound-sign:before,.fa-sterling-sign:before{content:”\f154”}.fa-viruses:before{content:”\e076”}.fa-square-person-confined:before{content:”\e577”}.fa-user-tie:before{content:”\f508”}.fa-arrow-down-long:before,.fa-long-arrow-down:before{content:”\f175”}.fa-tent-arrow-down-to-line:before{content:”\e57e”}.fa-certificate:before{content:”\f0a3”}.fa-mail-reply-all:before,.fa-reply-all:before{content:”\f122”}.fa-suitcase:before{content:”\f0f2”}.fa-person-skating:before,.fa-skating:before{content:”\f7c5”}.fa-filter-circle-dollar:before,.fa-funnel-dollar:before{content:”\f662”}.fa-camera-retro:before{content:”\f083”}.fa-arrow-circle-down:before,.fa-circle-arrow-down:before{content:”\f0ab”}.fa-arrow-right-to-file:before,.fa-file-import:before{content:”\f56f”}.fa-external-link-square:before,.fa-square-arrow-up-right:before{content:”\f14c”}.fa-box-open:before{content:”\f49e”}.fa-scroll:before{content:”\f70e”}.fa-spa:before{content:”\f5bb”}.fa-location-pin-lock:before{content:”\e51f”}.fa-pause:before{content:”\f04c”}.fa-hill-avalanche:before{content:”\e507”}.fa-temperature-0:before,.fa-temperature-empty:before,.fa-thermometer-0:before,.fa-thermometer-empty:before{content:”\f2cb”}.fa-bomb:before{content:”\f1e2”}.fa-registered:before{content:”\f25d”}.fa-address-card:before,.fa-contact-card:before,.fa-vcard:before{content:”\f2bb”}.fa-balance-scale-right:before,.fa-scale-unbalanced-flip:before{content:”\f516”}.fa-subscript:before{content:”\f12c”}.fa-diamond-turn-right:before,.fa-directions:before{content:”\f5eb”}.fa-burst:before{content:”\e4dc”}.fa-house-laptop:before,.fa-laptop-house:before{content:”\e066”}.fa-face-tired:before,.fa-tired:before{content:”\f5c8”}.fa-money-bills:before{content:”\e1f3”}.fa-smog:before{content:”\f75f”}.fa-crutch:before{content:”\f7f7”}.fa-cloud-arrow-up:before,.fa-cloud-upload-alt:before,.fa-cloud-upload:before{content:”\f0ee”}.fa-palette:before{content:”\f53f”}.fa-arrows-turn-right:before{content:”\e4c0”}.fa-vest:before{content:”\e085”}.fa-ferry:before{content:”\e4ea”}.fa-arrows-down-to-people:before{content:”\e4b9”}.fa-seedling:before,.fa-sprout:before{content:”\f4d8”}.fa-arrows-alt-h:before,.fa-left-right:before{content:”\f337”}.fa-boxes-packing:before{content:”\e4c7”}.fa-arrow-circle-left:before,.fa-circle-arrow-left:before{content:”\f0a8”}.fa-group-arrows-rotate:before{content:”\e4f6”}.fa-bowl-food:before{content:”\e4c6”}.fa-candy-cane:before{content:”\f786”}.fa-arrow-down-wide-short:before,.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:”\f160”}.fa-cloud-bolt:before,.fa-thunderstorm:before{content:”\f76c”}.fa-remove-format:before,.fa-text-slash:before{content:”\f87d”}.fa-face-smile-wink:before,.fa-smile-wink:before{content:”\f4da”}.fa-file-word:before{content:”\f1c2”}.fa-file-powerpoint:before{content:”\f1c4”}.fa-arrows-h:before,.fa-arrows-left-right:before{content:”\f07e”}.fa-house-lock:before{content:”\e510”}.fa-cloud-arrow-down:before,.fa-cloud-download-alt:before,.fa-cloud-download:before{content:”\f0ed”}.fa-children:before{content:”\e4e1”}.fa-blackboard:before,.fa-chalkboard:before{content:”\f51b”}.fa-user-alt-slash:before,.fa-user-large-slash:before{content:”\f4fa”}.fa-envelope-open:before{content:”\f2b6”}.fa-handshake-alt-slash:before,.fa-handshake-simple-slash:before{content:”\e05f”}.fa-mattress-pillow:before{content:”\e525”}.fa-guarani-sign:before{content:”\e19a”}.fa-arrows-rotate:before,.fa-refresh:before,.fa-sync:before{content:”\f021”}.fa-fire-extinguisher:before{content:”\f134”}.fa-cruzeiro-sign:before{content:”\e152”}.fa-greater-than-equal:before{content:”\f532”}.fa-shield-alt:before,.fa-shield-halved:before{content:”\f3ed”}.fa-atlas:before,.fa-book-atlas:before{content:”\f558”}.fa-virus:before{content:”\e074”}.fa-envelope-circle-check:before{content:”\e4e8”}.fa-layer-group:before{content:”\f5fd”}.fa-arrows-to-dot:before{content:”\e4be”}.fa-archway:before{content:”\f557”}.fa-heart-circle-check:before{content:”\e4fd”}.fa-house-chimney-crack:before,.fa-house-damage:before{content:”\f6f1”}.fa-file-archive:before,.fa-file-zipper:before{content:”\f1c6”}.fa-square:before{content:”\f0c8”}.fa-glass-martini:before,.fa-martini-glass-empty:before{content:”\f000”}.fa-couch:before{content:”\f4b8”}.fa-cedi-sign:before{content:”\e0df”}.fa-italic:before{content:”\f033”}.fa-church:before{content:”\f51d”}.fa-comments-dollar:before{content:”\f653”}.fa-democrat:before{content:”\f747”}.fa-z:before{content:”\5a”}.fa-person-skiing:before,.fa-skiing:before{content:”\f7c9”}.fa-road-lock:before{content:”\e567”}.fa-a:before{content:”\41”}.fa-temperature-arrow-down:before,.fa-temperature-down:before{content:”\e03f”}.fa-feather-alt:before,.fa-feather-pointed:before{content:”\f56b”}.fa-p:before{content:”\50”}.fa-snowflake:before{content:”\f2dc”}.fa-newspaper:before{content:”\f1ea”}.fa-ad:before,.fa-rectangle-ad:before{content:”\f641”}.fa-arrow-circle-right:before,.fa-circle-arrow-right:before{content:”\f0a9”}.fa-filter-circle-xmark:before{content:”\e17b”}.fa-locust:before{content:”\e520”}.fa-sort:before,.fa-unsorted:before{content:”\f0dc”}.fa-list-1-2:before,.fa-list-numeric:before,.fa-list-ol:before{content:”\f0cb”}.fa-person-dress-burst:before{content:”\e544”}.fa-money-check-alt:before,.fa-money-check-dollar:before{content:”\f53d”}.fa-vector-square:before{content:”\f5cb”}.fa-bread-slice:before{content:”\f7ec”}.fa-language:before{content:”\f1ab”}.fa-face-kiss-wink-heart:before,.fa-kiss-wink-heart:before{content:”\f598”}.fa-filter:before{content:”\f0b0”}.fa-question:before{content:”\3f”}.fa-file-signature:before{content:”\f573”}.fa-arrows-alt:before,.fa-up-down-left-right:before{content:”\f0b2”}.fa-house-chimney-user:before{content:”\e065”}.fa-hand-holding-heart:before{content:”\f4be”}.fa-puzzle-piece:before{content:”\f12e”}.fa-money-check:before{content:”\f53c”}.fa-star-half-alt:before,.fa-star-half-stroke:before{content:”\f5c0”}.fa-code:before{content:”\f121”}.fa-glass-whiskey:before,.fa-whiskey-glass:before{content:”\f7a0”}.fa-building-circle-exclamation:before{content:”\e4d3”}.fa-magnifying-glass-chart:before{content:”\e522”}.fa-arrow-up-right-from-square:before,.fa-external-link:before{content:”\f08e”}.fa-cubes-stacked:before{content:”\e4e6”}.fa-krw:before,.fa-won-sign:before,.fa-won:before{content:”\f159”}.fa-virus-covid:before{content:”\e4a8”}.fa-austral-sign:before{content:”\e0a9”}.fa-f:before{content:”\46”}.fa-leaf:before{content:”\f06c”}.fa-road:before{content:”\f018”}.fa-cab:before,.fa-taxi:before{content:”\f1ba”}.fa-person-circle-plus:before{content:”\e541”}.fa-chart-pie:before,.fa-pie-chart:before{content:”\f200”}.fa-bolt-lightning:before{content:”\e0b7”}.fa-sack-xmark:before{content:”\e56a”}.fa-file-excel:before{content:”\f1c3”}.fa-file-contract:before{content:”\f56c”}.fa-fish-fins:before{content:”\e4f2”}.fa-building-flag:before{content:”\e4d5”}.fa-face-grin-beam:before,.fa-grin-beam:before{content:”\f582”}.fa-object-ungroup:before{content:”\f248”}.fa-poop:before{content:”\f619”}.fa-location-pin:before,.fa-map-marker:before{content:”\f041”}.fa-kaaba:before{content:”\f66b”}.fa-toilet-paper:before{content:”\f71e”}.fa-hard-hat:before,.fa-hat-hard:before,.fa-helmet-safety:before{content:”\f807”}.fa-eject:before{content:”\f052”}.fa-arrow-alt-circle-right:before,.fa-circle-right:before{content:”\f35a”}.fa-plane-circle-check:before{content:”\e555”}.fa-face-rolling-eyes:before,.fa-meh-rolling-eyes:before{content:”\f5a5”}.fa-object-group:before{content:”\f247”}.fa-chart-line:before,.fa-line-chart:before{content:”\f201”}.fa-mask-ventilator:before{content:”\e524”}.fa-arrow-right:before{content:”\f061”}.fa-map-signs:before,.fa-signs-post:before{content:”\f277”}.fa-cash-register:before{content:”\f788”}.fa-person-circle-question:before{content:”\e542”}.fa-h:before{content:”\48”}.fa-tarp:before{content:”\e57b”}.fa-screwdriver-wrench:before,.fa-tools:before{content:”\f7d9”}.fa-arrows-to-eye:before{content:”\e4bf”}.fa-plug-circle-bolt:before{content:”\e55b”}.fa-heart:before{content:”\f004”}.fa-mars-and-venus:before{content:”\f224”}.fa-home-user:before,.fa-house-user:before{content:”\e1b0”}.fa-dumpster-fire:before{content:”\f794”}.fa-house-crack:before{content:”\e3b1”}.fa-cocktail:before,.fa-martini-glass-citrus:before{content:”\f561”}.fa-face-surprise:before,.fa-surprise:before{content:”\f5c2”}.fa-bottle-water:before{content:”\e4c5”}.fa-circle-pause:before,.fa-pause-circle:before{content:”\f28b”}.fa-toilet-paper-slash:before{content:”\e072”}.fa-apple-alt:before,.fa-apple-whole:before{content:”\f5d1”}.fa-kitchen-set:before{content:”\e51a”}.fa-r:before{content:”\52”}.fa-temperature-1:before,.fa-temperature-quarter:before,.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:”\f2ca”}.fa-cube:before{content:”\f1b2”}.fa-bitcoin-sign:before{content:”\e0b4”}.fa-shield-dog:before{content:”\e573”}.fa-solar-panel:before{content:”\f5ba”}.fa-lock-open:before{content:”\f3c1”}.fa-elevator:before{content:”\e16d”}.fa-money-bill-transfer:before{content:”\e528”}.fa-money-bill-trend-up:before{content:”\e529”}.fa-house-flood-water-circle-arrow-right:before{content:”\e50f”}.fa-poll-h:before,.fa-square-poll-horizontal:before{content:”\f682”}.fa-circle:before{content:”\f111”}.fa-backward-fast:before,.fa-fast-backward:before{content:”\f049”}.fa-recycle:before{content:”\f1b8”}.fa-user-astronaut:before{content:”\f4fb”}.fa-plane-slash:before{content:”\e069”}.fa-trademark:before{content:”\f25c”}.fa-basketball-ball:before,.fa-basketball:before{content:”\f434”}.fa-satellite-dish:before{content:”\f7c0”}.fa-arrow-alt-circle-up:before,.fa-circle-up:before{content:”\f35b”}.fa-mobile-alt:before,.fa-mobile-screen-button:before{content:”\f3cd”}.fa-volume-high:before,.fa-volume-up:before{content:”\f028”}.fa-users-rays:before{content:”\e593”}.fa-wallet:before{content:”\f555”}.fa-clipboard-check:before{content:”\f46c”}.fa-file-audio:before{content:”\f1c7”}.fa-burger:before,.fa-hamburger:before{content:”\f805”}.fa-wrench:before{content:”\f0ad”}.fa-bugs:before{content:”\e4d0”}.fa-rupee-sign:before,.fa-rupee:before{content:”\f156”}.fa-file-image:before{content:”\f1c5”}.fa-circle-question:before,.fa-question-circle:before{content:”\f059”}.fa-plane-departure:before{content:”\f5b0”}.fa-handshake-slash:before{content:”\e060”}.fa-book-bookmark:before{content:”\e0bb”}.fa-code-branch:before{content:”\f126”}.fa-hat-cowboy:before{content:”\f8c0”}.fa-bridge:before{content:”\e4c8”}.fa-phone-alt:before,.fa-phone-flip:before{content:”\f879”}.fa-truck-front:before{content:”\e2b7”}.fa-cat:before{content:”\f6be”}.fa-anchor-circle-exclamation:before{content:”\e4ab”}.fa-truck-field:before{content:”\e58d”}.fa-route:before{content:”\f4d7”}.fa-clipboard-question:before{content:”\e4e3”}.fa-panorama:before{content:”\e209”}.fa-comment-medical:before{content:”\f7f5”}.fa-teeth-open:before{content:”\f62f”}.fa-file-circle-minus:before{content:”\e4ed”}.fa-tags:before{content:”\f02c”}.fa-wine-glass:before{content:”\f4e3”}.fa-fast-forward:before,.fa-forward-fast:before{content:”\f050”}.fa-face-meh-blank:before,.fa-meh-blank:before{content:”\f5a4”}.fa-parking:before,.fa-square-parking:before{content:”\f540”}.fa-house-signal:before{content:”\e012”}.fa-bars-progress:before,.fa-tasks-alt:before{content:”\f828”}.fa-faucet-drip:before{content:”\e006”}.fa-cart-flatbed:before,.fa-dolly-flatbed:before{content:”\f474”}.fa-ban-smoking:before,.fa-smoking-ban:before{content:”\f54d”}.fa-terminal:before{content:”\f120”}.fa-mobile-button:before{content:”\f10b”}.fa-house-medical-flag:before{content:”\e514”}.fa-basket-shopping:before,.fa-shopping-basket:before{content:”\f291”}.fa-tape:before{content:”\f4db”}.fa-bus-alt:before,.fa-bus-simple:before{content:”\f55e”}.fa-eye:before{content:”\f06e”}.fa-face-sad-cry:before,.fa-sad-cry:before{content:”\f5b3”}.fa-audio-description:before{content:”\f29e”}.fa-person-military-to-person:before{content:”\e54c”}.fa-file-shield:before{content:”\e4f0”}.fa-user-slash:before{content:”\f506”}.fa-pen:before{content:”\f304”}.fa-tower-observation:before{content:”\e586”}.fa-file-code:before{content:”\f1c9”}.fa-signal-5:before,.fa-signal-perfect:before,.fa-signal:before{content:”\f012”}.fa-bus:before{content:”\f207”}.fa-heart-circle-xmark:before{content:”\e501”}.fa-home-lg:before,.fa-house-chimney:before{content:”\e3af”}.fa-window-maximize:before{content:”\f2d0”}.fa-face-frown:before,.fa-frown:before{content:”\f119”}.fa-prescription:before{content:”\f5b1”}.fa-shop:before,.fa-store-alt:before{content:”\f54f”}.fa-floppy-disk:before,.fa-save:before{content:”\f0c7”}.fa-vihara:before{content:”\f6a7”}.fa-balance-scale-left:before,.fa-scale-unbalanced:before{content:”\f515”}.fa-sort-asc:before,.fa-sort-up:before{content:”\f0de”}.fa-comment-dots:before,.fa-commenting:before{content:”\f4ad”}.fa-plant-wilt:before{content:”\e5aa”}.fa-diamond:before{content:”\f219”}.fa-face-grin-squint:before,.fa-grin-squint:before{content:”\f585”}.fa-hand-holding-dollar:before,.fa-hand-holding-usd:before{content:”\f4c0”}.fa-bacterium:before{content:”\e05a”}.fa-hand-pointer:before{content:”\f25a”}.fa-drum-steelpan:before{content:”\f56a”}.fa-hand-scissors:before{content:”\f257”}.fa-hands-praying:before,.fa-praying-hands:before{content:”\f684”}.fa-arrow-right-rotate:before,.fa-arrow-rotate-forward:before,.fa-arrow-rotate-right:before,.fa-redo:before{content:”\f01e”}.fa-biohazard:before{content:”\f780”}.fa-location-crosshairs:before,.fa-location:before{content:”\f601”}.fa-mars-double:before{content:”\f227”}.fa-child-dress:before{content:”\e59c”}.fa-users-between-lines:before{content:”\e591”}.fa-lungs-virus:before{content:”\e067”}.fa-face-grin-tears:before,.fa-grin-tears:before{content:”\f588”}.fa-phone:before{content:”\f095”}.fa-calendar-times:before,.fa-calendar-xmark:before{content:”\f273”}.fa-child-reaching:before{content:”\e59d”}.fa-head-side-virus:before{content:”\e064”}.fa-user-cog:before,.fa-user-gear:before{content:”\f4fe”}.fa-arrow-up-1-9:before,.fa-sort-numeric-up:before{content:”\f163”}.fa-door-closed:before{content:”\f52a”}.fa-shield-virus:before{content:”\e06c”}.fa-dice-six:before{content:”\f526”}.fa-mosquito-net:before{content:”\e52c”}.fa-bridge-water:before{content:”\e4ce”}.fa-person-booth:before{content:”\f756”}.fa-text-width:before{content:”\f035”}.fa-hat-wizard:before{content:”\f6e8”}.fa-pen-fancy:before{content:”\f5ac”}.fa-digging:before,.fa-person-digging:before{content:”\f85e”}.fa-trash:before{content:”\f1f8”}.fa-gauge-simple-med:before,.fa-gauge-simple:before,.fa-tachometer-average:before{content:”\f629”}.fa-book-medical:before{content:”\f7e6”}.fa-poo:before{content:”\f2fe”}.fa-quote-right-alt:before,.fa-quote-right:before{content:”\f10e”}.fa-shirt:before,.fa-t-shirt:before,.fa-tshirt:before{content:”\f553”}.fa-cubes:before{content:”\f1b3”}.fa-divide:before{content:”\f529”}.fa-tenge-sign:before,.fa-tenge:before{content:”\f7d7”}.fa-headphones:before{content:”\f025”}.fa-hands-holding:before{content:”\f4c2”}.fa-hands-clapping:before{content:”\e1a8”}.fa-republican:before{content:”\f75e”}.fa-arrow-left:before{content:”\f060”}.fa-person-circle-xmark:before{content:”\e543”}.fa-ruler:before{content:”\f545”}.fa-align-left:before{content:”\f036”}.fa-dice-d6:before{content:”\f6d1”}.fa-restroom:before{content:”\f7bd”}.fa-j:before{content:”\4a”}.fa-users-viewfinder:before{content:”\e595”}.fa-file-video:before{content:”\f1c8”}.fa-external-link-alt:before,.fa-up-right-from-square:before{content:”\f35d”}.fa-table-cells:before,.fa-th:before{content:”\f00a”}.fa-file-pdf:before{content:”\f1c1”}.fa-bible:before,.fa-book-bible:before{content:”\f647”}.fa-o:before{content:”\4f”}.fa-medkit:before,.fa-suitcase-medical:before{content:”\f0fa”}.fa-user-secret:before{content:”\f21b”}.fa-otter:before{content:”\f700”}.fa-female:before,.fa-person-dress:before{content:”\f182”}.fa-comment-dollar:before{content:”\f651”}.fa-briefcase-clock:before,.fa-business-time:before{content:”\f64a”}.fa-table-cells-large:before,.fa-th-large:before{content:”\f009”}.fa-book-tanakh:before,.fa-tanakh:before{content:”\f827”}.fa-phone-volume:before,.fa-volume-control-phone:before{content:”\f2a0”}.fa-hat-cowboy-side:before{content:”\f8c1”}.fa-clipboard-user:before{content:”\f7f3”}.fa-child:before{content:”\f1ae”}.fa-lira-sign:before{content:”\f195”}.fa-satellite:before{content:”\f7bf”}.fa-plane-lock:before{content:”\e558”}.fa-tag:before{content:”\f02b”}.fa-comment:before{content:”\f075”}.fa-birthday-cake:before,.fa-cake-candles:before,.fa-cake:before{content:”\f1fd”}.fa-envelope:before{content:”\f0e0”}.fa-angle-double-up:before,.fa-angles-up:before{content:”\f102”}.fa-paperclip:before{content:”\f0c6”}.fa-arrow-right-to-city:before{content:”\e4b3”}.fa-ribbon:before{content:”\f4d6”}.fa-lungs:before{content:”\f604”}.fa-arrow-up-9-1:before,.fa-sort-numeric-up-alt:before{content:”\f887”}.fa-litecoin-sign:before{content:”\e1d3”}.fa-border-none:before{content:”\f850”}.fa-circle-nodes:before{content:”\e4e2”}.fa-parachute-box:before{content:”\f4cd”}.fa-indent:before{content:”\f03c”}.fa-truck-field-un:before{content:”\e58e”}.fa-hourglass-empty:before,.fa-hourglass:before{content:”\f254”}.fa-mountain:before{content:”\f6fc”}.fa-user-doctor:before,.fa-user-md:before{content:”\f0f0”}.fa-circle-info:before,.fa-info-circle:before{content:”\f05a”}.fa-cloud-meatball:before{content:”\f73b”}.fa-camera-alt:before,.fa-camera:before{content:”\f030”}.fa-square-virus:before{content:”\e578”}.fa-meteor:before{content:”\f753”}.fa-car-on:before{content:”\e4dd”}.fa-sleigh:before{content:”\f7cc”}.fa-arrow-down-1-9:before,.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:”\f162”}.fa-hand-holding-droplet:before,.fa-hand-holding-water:before{content:”\f4c1”}.fa-water:before{content:”\f773”}.fa-calendar-check:before{content:”\f274”}.fa-braille:before{content:”\f2a1”}.fa-prescription-bottle-alt:before,.fa-prescription-bottle-medical:before{content:”\f486”}.fa-landmark:before{content:”\f66f”}.fa-truck:before{content:”\f0d1”}.fa-crosshairs:before{content:”\f05b”}.fa-person-cane:before{content:”\e53c”}.fa-tent:before{content:”\e57d”}.fa-vest-patches:before{content:”\e086”}.fa-check-double:before{content:”\f560”}.fa-arrow-down-a-z:before,.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:”\f15d”}.fa-money-bill-wheat:before{content:”\e52a”}.fa-cookie:before{content:”\f563”}.fa-arrow-left-rotate:before,.fa-arrow-rotate-back:before,.fa-arrow-rotate-backward:before,.fa-arrow-rotate-left:before,.fa-undo:before{content:”\f0e2”}.fa-hard-drive:before,.fa-hdd:before{content:”\f0a0”}.fa-face-grin-squint-tears:before,.fa-grin-squint-tears:before{content:”\f586”}.fa-dumbbell:before{content:”\f44b”}.fa-list-alt:before,.fa-rectangle-list:before{content:”\f022”}.fa-tarp-droplet:before{content:”\e57c”}.fa-house-medical-circle-check:before{content:”\e511”}.fa-person-skiing-nordic:before,.fa-skiing-nordic:before{content:”\f7ca”}.fa-calendar-plus:before{content:”\f271”}.fa-plane-arrival:before{content:”\f5af”}.fa-arrow-alt-circle-left:before,.fa-circle-left:before{content:”\f359”}.fa-subway:before,.fa-train-subway:before{content:”\f239”}.fa-chart-gantt:before{content:”\e0e4”}.fa-indian-rupee-sign:before,.fa-indian-rupee:before,.fa-inr:before{content:”\e1bc”}.fa-crop-alt:before,.fa-crop-simple:before{content:”\f565”}.fa-money-bill-1:before,.fa-money-bill-alt:before{content:”\f3d1”}.fa-left-long:before,.fa-long-arrow-alt-left:before{content:”\f30a”}.fa-dna:before{content:”\f471”}.fa-virus-slash:before{content:”\e075”}.fa-minus:before,.fa-subtract:before{content:”\f068”}.fa-chess:before{content:”\f439”}.fa-arrow-left-long:before,.fa-long-arrow-left:before{content:”\f177”}.fa-plug-circle-check:before{content:”\e55c”}.fa-street-view:before{content:”\f21d”}.fa-franc-sign:before{content:”\e18f”}.fa-volume-off:before{content:”\f026”}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before,.fa-hands-american-sign-language-interpreting:before,.fa-hands-asl-interpreting:before{content:”\f2a3”}.fa-cog:before,.fa-gear:before{content:”\f013”}.fa-droplet-slash:before,.fa-tint-slash:before{content:”\f5c7”}.fa-mosque:before{content:”\f678”}.fa-mosquito:before{content:”\e52b”}.fa-star-of-david:before{content:”\f69a”}.fa-person-military-rifle:before{content:”\e54b”}.fa-cart-shopping:before,.fa-shopping-cart:before{content:”\f07a”}.fa-vials:before{content:”\f493”}.fa-plug-circle-plus:before{content:”\e55f”}.fa-place-of-worship:before{content:”\f67f”}.fa-grip-vertical:before{content:”\f58e”}.fa-arrow-turn-up:before,.fa-level-up:before{content:”\f148”}.fa-u:before{content:”\55”}.fa-square-root-alt:before,.fa-square-root-variable:before{content:”\f698”}.fa-clock-four:before,.fa-clock:before{content:”\f017”}.fa-backward-step:before,.fa-step-backward:before{content:”\f048”}.fa-pallet:before{content:”\f482”}.fa-faucet:before{content:”\e005”}.fa-baseball-bat-ball:before{content:”\f432”}.fa-s:before{content:”\53”}.fa-timeline:before{content:”\e29c”}.fa-keyboard:before{content:”\f11c”}.fa-caret-down:before{content:”\f0d7”}.fa-clinic-medical:before,.fa-house-chimney-medical:before{content:”\f7f2”}.fa-temperature-3:before,.fa-temperature-three-quarters:before,.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:”\f2c8”}.fa-mobile-android-alt:before,.fa-mobile-screen:before{content:”\f3cf”}.fa-plane-up:before{content:”\e22d”}.fa-piggy-bank:before{content:”\f4d3”}.fa-battery-3:before,.fa-battery-half:before{content:”\f242”}.fa-mountain-city:before{content:”\e52e”}.fa-coins:before{content:”\f51e”}.fa-khanda:before{content:”\f66d”}.fa-sliders-h:before,.fa-sliders:before{content:”\f1de”}.fa-folder-tree:before{content:”\f802”}.fa-network-wired:before{content:”\f6ff”}.fa-map-pin:before{content:”\f276”}.fa-hamsa:before{content:”\f665”}.fa-cent-sign:before{content:”\e3f5”}.fa-flask:before{content:”\f0c3”}.fa-person-pregnant:before{content:”\e31e”}.fa-wand-sparkles:before{content:”\f72b”}.fa-ellipsis-v:before,.fa-ellipsis-vertical:before{content:”\f142”}.fa-ticket:before{content:”\f145”}.fa-power-off:before{content:”\f011”}.fa-long-arrow-alt-right:before,.fa-right-long:before{content:”\f30b”}.fa-flag-usa:before{content:”\f74d”}.fa-laptop-file:before{content:”\e51d”}.fa-teletype:before,.fa-tty:before{content:”\f1e4”}.fa-diagram-next:before{content:”\e476”}.fa-person-rifle:before{content:”\e54e”}.fa-house-medical-circle-exclamation:before{content:”\e512”}.fa-closed-captioning:before{content:”\f20a”}.fa-hiking:before,.fa-person-hiking:before{content:”\f6ec”}.fa-venus-double:before{content:”\f226”}.fa-images:before{content:”\f302”}.fa-calculator:before{content:”\f1ec”}.fa-people-pulling:before{content:”\e535”}.fa-n:before{content:”\4e”}.fa-cable-car:before,.fa-tram:before{content:”\f7da”}.fa-cloud-rain:before{content:”\f73d”}.fa-building-circle-xmark:before{content:”\e4d4”}.fa-ship:before{content:”\f21a”}.fa-arrows-down-to-line:before{content:”\e4b8”}.fa-download:before{content:”\f019”}.fa-face-grin:before,.fa-grin:before{content:”\f580”}.fa-backspace:before,.fa-delete-left:before{content:”\f55a”}.fa-eye-dropper-empty:before,.fa-eye-dropper:before,.fa-eyedropper:before{content:”\f1fb”}.fa-file-circle-check:before{content:”\e5a0”}.fa-forward:before{content:”\f04e”}.fa-mobile-android:before,.fa-mobile-phone:before,.fa-mobile:before{content:”\f3ce”}.fa-face-meh:before,.fa-meh:before{content:”\f11a”}.fa-align-center:before{content:”\f037”}.fa-book-dead:before,.fa-book-skull:before{content:”\f6b7”}.fa-drivers-license:before,.fa-id-card:before{content:”\f2c2”}.fa-dedent:before,.fa-outdent:before{content:”\f03b”}.fa-heart-circle-exclamation:before{content:”\e4fe”}.fa-home-alt:before,.fa-home-lg-alt:before,.fa-home:before,.fa-house:before{content:”\f015”}.fa-calendar-week:before{content:”\f784”}.fa-laptop-medical:before{content:”\f812”}.fa-b:before{content:”\42”}.fa-file-medical:before{content:”\f477”}.fa-dice-one:before{content:”\f525”}.fa-kiwi-bird:before{content:”\f535”}.fa-arrow-right-arrow-left:before,.fa-exchange:before{content:”\f0ec”}.fa-redo-alt:before,.fa-rotate-forward:before,.fa-rotate-right:before{content:”\f2f9”}.fa-cutlery:before,.fa-utensils:before{content:”\f2e7”}.fa-arrow-up-wide-short:before,.fa-sort-amount-up:before{content:”\f161”}.fa-mill-sign:before{content:”\e1ed”}.fa-bowl-rice:before{content:”\e2eb”}.fa-skull:before{content:”\f54c”}.fa-broadcast-tower:before,.fa-tower-broadcast:before{content:”\f519”}.fa-truck-pickup:before{content:”\f63c”}.fa-long-arrow-alt-up:before,.fa-up-long:before{content:”\f30c”}.fa-stop:before{content:”\f04d”}.fa-code-merge:before{content:”\f387”}.fa-upload:before{content:”\f093”}.fa-hurricane:before{content:”\f751”}.fa-mound:before{content:”\e52d”}.fa-toilet-portable:before{content:”\e583”}.fa-compact-disc:before{content:”\f51f”}.fa-file-arrow-down:before,.fa-file-download:before{content:”\f56d”}.fa-caravan:before{content:”\f8ff”}.fa-shield-cat:before{content:”\e572”}.fa-bolt:before,.fa-zap:before{content:”\f0e7”}.fa-glass-water:before{content:”\e4f4”}.fa-oil-well:before{content:”\e532”}.fa-vault:before{content:”\e2c5”}.fa-mars:before{content:”\f222”}.fa-toilet:before{content:”\f7d8”}.fa-plane-circle-xmark:before{content:”\e557”}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen-sign:before,.fa-yen:before{content:”\f157”}.fa-rouble:before,.fa-rub:before,.fa-ruble-sign:before,.fa-ruble:before{content:”\f158”}.fa-sun:before{content:”\f185”}.fa-guitar:before{content:”\f7a6”}.fa-face-laugh-wink:before,.fa-laugh-wink:before{content:”\f59c”}.fa-horse-head:before{content:”\f7ab”}.fa-bore-hole:before{content:”\e4c3”}.fa-industry:before{content:”\f275”}.fa-arrow-alt-circle-down:before,.fa-circle-down:before{content:”\f358”}.fa-arrows-turn-to-dots:before{content:”\e4c1”}.fa-florin-sign:before{content:”\e184”}.fa-arrow-down-short-wide:before,.fa-sort-amount-desc:before,.fa-sort-amount-down-alt:before{content:”\f884”}.fa-less-than:before{content:”\3c”}.fa-angle-down:before{content:”\f107”}.fa-car-tunnel:before{content:”\e4de”}.fa-head-side-cough:before{content:”\e061”}.fa-grip-lines:before{content:”\f7a4”}.fa-thumbs-down:before{content:”\f165”}.fa-user-lock:before{content:”\f502”}.fa-arrow-right-long:before,.fa-long-arrow-right:before{content:”\f178”}.fa-anchor-circle-xmark:before{content:”\e4ac”}.fa-ellipsis-h:before,.fa-ellipsis:before{content:”\f141”}.fa-chess-pawn:before{content:”\f443”}.fa-first-aid:before,.fa-kit-medical:before{content:”\f479”}.fa-person-through-window:before{content:”\e5a9”}.fa-toolbox:before{content:”\f552”}.fa-hands-holding-circle:before{content:”\e4fb”}.fa-bug:before{content:”\f188”}.fa-credit-card-alt:before,.fa-credit-card:before{content:”\f09d”}.fa-automobile:before,.fa-car:before{content:”\f1b9”}.fa-hand-holding-hand:before{content:”\e4f7”}.fa-book-open-reader:before,.fa-book-reader:before{content:”\f5da”}.fa-mountain-sun:before{content:”\e52f”}.fa-arrows-left-right-to-line:before{content:”\e4ba”}.fa-dice-d20:before{content:”\f6cf”}.fa-truck-droplet:before{content:”\e58c”}.fa-file-circle-xmark:before{content:”\e5a1”}.fa-temperature-arrow-up:before,.fa-temperature-up:before{content:”\e040”}.fa-medal:before{content:”\f5a2”}.fa-bed:before{content:”\f236”}.fa-h-square:before,.fa-square-h:before{content:”\f0fd”}.fa-podcast:before{content:”\f2ce”}.fa-temperature-4:before,.fa-temperature-full:before,.fa-thermometer-4:before,.fa-thermometer-full:before{content:”\f2c7”}.fa-bell:before{content:”\f0f3”}.fa-superscript:before{content:”\f12b”}.fa-plug-circle-xmark:before{content:”\e560”}.fa-star-of-life:before{content:”\f621”}.fa-phone-slash:before{content:”\f3dd”}.fa-paint-roller:before{content:”\f5aa”}.fa-hands-helping:before,.fa-handshake-angle:before{content:”\f4c4”}.fa-location-dot:before,.fa-map-marker-alt:before{content:”\f3c5”}.fa-file:before{content:”\f15b”}.fa-greater-than:before{content:”\3e”}.fa-person-swimming:before,.fa-swimmer:before{content:”\f5c4”}.fa-arrow-down:before{content:”\f063”}.fa-droplet:before,.fa-tint:before{content:”\f043”}.fa-eraser:before{content:”\f12d”}.fa-earth-america:before,.fa-earth-americas:before,.fa-earth:before,.fa-globe-americas:before{content:”\f57d”}.fa-person-burst:before{content:”\e53b”}.fa-dove:before{content:”\f4ba”}.fa-battery-0:before,.fa-battery-empty:before{content:”\f244”}.fa-socks:before{content:”\f696”}.fa-inbox:before{content:”\f01c”}.fa-section:before{content:”\e447”}.fa-gauge-high:before,.fa-tachometer-alt-fast:before,.fa-tachometer-alt:before{content:”\f625”}.fa-envelope-open-text:before{content:”\f658”}.fa-hospital-alt:before,.fa-hospital-wide:before,.fa-hospital:before{content:”\f0f8”}.fa-wine-bottle:before{content:”\f72f”}.fa-chess-rook:before{content:”\f447”}.fa-bars-staggered:before,.fa-reorder:before,.fa-stream:before{content:”\f550”}.fa-dharmachakra:before{content:”\f655”}.fa-hotdog:before{content:”\f80f”}.fa-blind:before,.fa-person-walking-with-cane:before{content:”\f29d”}.fa-drum:before{content:”\f569”}.fa-ice-cream:before{content:”\f810”}.fa-heart-circle-bolt:before{content:”\e4fc”}.fa-fax:before{content:”\f1ac”}.fa-paragraph:before{content:”\f1dd”}.fa-check-to-slot:before,.fa-vote-yea:before{content:”\f772”}.fa-star-half:before{content:”\f089”}.fa-boxes-alt:before,.fa-boxes-stacked:before,.fa-boxes:before{content:”\f468”}.fa-chain:before,.fa-link:before{content:”\f0c1”}.fa-assistive-listening-systems:before,.fa-ear-listen:before{content:”\f2a2”}.fa-tree-city:before{content:”\e587”}.fa-play:before{content:”\f04b”}.fa-font:before{content:”\f031”}.fa-rupiah-sign:before{content:”\e23d”}.fa-magnifying-glass:before,.fa-search:before{content:”\f002”}.fa-ping-pong-paddle-ball:before,.fa-table-tennis-paddle-ball:before,.fa-table-tennis:before{content:”\f45d”}.fa-diagnoses:before,.fa-person-dots-from-line:before{content:”\f470”}.fa-trash-can-arrow-up:before,.fa-trash-restore-alt:before{content:”\f82a”}.fa-naira-sign:before{content:”\e1f6”}.fa-cart-arrow-down:before{content:”\f218”}.fa-walkie-talkie:before{content:”\f8ef”}.fa-file-edit:before,.fa-file-pen:before{content:”\f31c”}.fa-receipt:before{content:”\f543”}.fa-pen-square:before,.fa-pencil-square:before,.fa-square-pen:before{content:”\f14b”}.fa-suitcase-rolling:before{content:”\f5c1”}.fa-person-circle-exclamation:before{content:”\e53f”}.fa-chevron-down:before{content:”\f078”}.fa-battery-5:before,.fa-battery-full:before,.fa-battery:before{content:”\f240”}.fa-skull-crossbones:before{content:”\f714”}.fa-code-compare:before{content:”\e13a”}.fa-list-dots:before,.fa-list-ul:before{content:”\f0ca”}.fa-school-lock:before{content:”\e56f”}.fa-tower-cell:before{content:”\e585”}.fa-down-long:before,.fa-long-arrow-alt-down:before{content:”\f309”}.fa-ranking-star:before{content:”\e561”}.fa-chess-king:before{content:”\f43f”}.fa-person-harassing:before{content:”\e549”}.fa-brazilian-real-sign:before{content:”\e46c”}.fa-landmark-alt:before,.fa-landmark-dome:before{content:”\f752”}.fa-arrow-up:before{content:”\f062”}.fa-television:before,.fa-tv-alt:before,.fa-tv:before{content:”\f26c”}.fa-shrimp:before{content:”\e448”}.fa-list-check:before,.fa-tasks:before{content:”\f0ae”}.fa-jug-detergent:before{content:”\e519”}.fa-circle-user:before,.fa-user-circle:before{content:”\f2bd”}.fa-user-shield:before{content:”\f505”}.fa-wind:before{content:”\f72e”}.fa-car-burst:before,.fa-car-crash:before{content:”\f5e1”}.fa-y:before{content:”\59”}.fa-person-snowboarding:before,.fa-snowboarding:before{content:”\f7ce”}.fa-shipping-fast:before,.fa-truck-fast:before{content:”\f48b”}.fa-fish:before{content:”\f578”}.fa-user-graduate:before{content:”\f501”}.fa-adjust:before,.fa-circle-half-stroke:before{content:”\f042”}.fa-clapperboard:before{content:”\e131”}.fa-circle-radiation:before,.fa-radiation-alt:before{content:”\f7ba”}.fa-baseball-ball:before,.fa-baseball:before{content:”\f433”}.fa-jet-fighter-up:before{content:”\e518”}.fa-diagram-project:before,.fa-project-diagram:before{content:”\f542”}.fa-copy:before{content:”\f0c5”}.fa-volume-mute:before,.fa-volume-times:before,.fa-volume-xmark:before{content:”\f6a9”}.fa-hand-sparkles:before{content:”\e05d”}.fa-grip-horizontal:before,.fa-grip:before{content:”\f58d”}.fa-share-from-square:before,.fa-share-square:before{content:”\f14d”}.fa-child-combatant:before,.fa-child-rifle:before{content:”\e4e0”}.fa-gun:before{content:”\e19b”}.fa-phone-square:before,.fa-square-phone:before{content:”\f098”}.fa-add:before,.fa-plus:before{content:”\2b”}.fa-expand:before{content:”\f065”}.fa-computer:before{content:”\e4e5”}.fa-close:before,.fa-multiply:before,.fa-remove:before,.fa-times:before,.fa-xmark:before{content:”\f00d”}.fa-arrows-up-down-left-right:before,.fa-arrows:before{content:”\f047”}.fa-chalkboard-teacher:before,.fa-chalkboard-user:before{content:”\f51c”}.fa-peso-sign:before{content:”\e222”}.fa-building-shield:before{content:”\e4d8”}.fa-baby:before{content:”\f77c”}.fa-users-line:before{content:”\e592”}.fa-quote-left-alt:before,.fa-quote-left:before{content:”\f10d”}.fa-tractor:before{content:”\f722”}.fa-trash-arrow-up:before,.fa-trash-restore:before{content:”\f829”}.fa-arrow-down-up-lock:before{content:”\e4b0”}.fa-lines-leaning:before{content:”\e51e”}.fa-ruler-combined:before{content:”\f546”}.fa-copyright:before{content:”\f1f9”}.fa-equals:before{content:”\3d”}.fa-blender:before{content:”\f517”}.fa-teeth:before{content:”\f62e”}.fa-ils:before,.fa-shekel-sign:before,.fa-shekel:before,.fa-sheqel-sign:before,.fa-sheqel:before{content:”\f20b”}.fa-map:before{content:”\f279”}.fa-rocket:before{content:”\f135”}.fa-photo-film:before,.fa-photo-video:before{content:”\f87c”}.fa-folder-minus:before{content:”\f65d”}.fa-store:before{content:”\f54e”}.fa-arrow-trend-up:before{content:”\e098”}.fa-plug-circle-minus:before{content:”\e55e”}.fa-sign-hanging:before,.fa-sign:before{content:”\f4d9”}.fa-bezier-curve:before{content:”\f55b”}.fa-bell-slash:before{content:”\f1f6”}.fa-tablet-android:before,.fa-tablet:before{content:”\f3fb”}.fa-school-flag:before{content:”\e56e”}.fa-fill:before{content:”\f575”}.fa-angle-up:before{content:”\f106”}.fa-drumstick-bite:before{content:”\f6d7”}.fa-holly-berry:before{content:”\f7aa”}.fa-chevron-left:before{content:”\f053”}.fa-bacteria:before{content:”\e059”}.fa-hand-lizard:before{content:”\f258”}.fa-notdef:before{content:”\e1fe”}.fa-disease:before{content:”\f7fa”}.fa-briefcase-medical:before{content:”\f469”}.fa-genderless:before{content:”\f22d”}.fa-chevron-right:before{content:”\f054”}.fa-retweet:before{content:”\f079”}.fa-car-alt:before,.fa-car-rear:before{content:”\f5de”}.fa-pump-soap:before{content:”\e06b”}.fa-video-slash:before{content:”\f4e2”}.fa-battery-2:before,.fa-battery-quarter:before{content:”\f243”}.fa-radio:before{content:”\f8d7”}.fa-baby-carriage:before,.fa-carriage-baby:before{content:”\f77d”}.fa-traffic-light:before{content:”\f637”}.fa-thermometer:before{content:”\f491”}.fa-vr-cardboard:before{content:”\f729”}.fa-hand-middle-finger:before{content:”\f806”}.fa-percent:before,.fa-percentage:before{content:”\25”}.fa-truck-moving:before{content:”\f4df”}.fa-glass-water-droplet:before{content:”\e4f5”}.fa-display:before{content:”\e163”}.fa-face-smile:before,.fa-smile:before{content:”\f118”}.fa-thumb-tack:before,.fa-thumbtack:before{content:”\f08d”}.fa-trophy:before{content:”\f091”}.fa-person-praying:before,.fa-pray:before{content:”\f683”}.fa-hammer:before{content:”\f6e3”}.fa-hand-peace:before{content:”\f25b”}.fa-rotate:before,.fa-sync-alt:before{content:”\f2f1”}.fa-spinner:before{content:”\f110”}.fa-robot:before{content:”\f544”}.fa-peace:before{content:”\f67c”}.fa-cogs:before,.fa-gears:before{content:”\f085”}.fa-warehouse:before{content:”\f494”}.fa-arrow-up-right-dots:before{content:”\e4b7”}.fa-splotch:before{content:”\f5bc”}.fa-face-grin-hearts:before,.fa-grin-hearts:before{content:”\f584”}.fa-dice-four:before{content:”\f524”}.fa-sim-card:before{content:”\f7c4”}.fa-transgender-alt:before,.fa-transgender:before{content:”\f225”}.fa-mercury:before{content:”\f223”}.fa-arrow-turn-down:before,.fa-level-down:before{content:”\f149”}.fa-person-falling-burst:before{content:”\e547”}.fa-award:before{content:”\f559”}.fa-ticket-alt:before,.fa-ticket-simple:before{content:”\f3ff”}.fa-building:before{content:”\f1ad”}.fa-angle-double-left:before,.fa-angles-left:before{content:”\f100”}.fa-qrcode:before{content:”\f029”}.fa-clock-rotate-left:before,.fa-history:before{content:”\f1da”}.fa-face-grin-beam-sweat:before,.fa-grin-beam-sweat:before{content:”\f583”}.fa-arrow-right-from-file:before,.fa-file-export:before{content:”\f56e”}.fa-shield-blank:before,.fa-shield:before{content:”\f132”}.fa-arrow-up-short-wide:before,.fa-sort-amount-up-alt:before{content:”\f885”}.fa-house-medical:before{content:”\e3b2”}.fa-golf-ball-tee:before,.fa-golf-ball:before{content:”\f450”}.fa-chevron-circle-left:before,.fa-circle-chevron-left:before{content:”\f137”}.fa-house-chimney-window:before{content:”\e00d”}.fa-pen-nib:before{content:”\f5ad”}.fa-tent-arrow-turn-left:before{content:”\e580”}.fa-tents:before{content:”\e582”}.fa-magic:before,.fa-wand-magic:before{content:”\f0d0”}.fa-dog:before{content:”\f6d3”}.fa-carrot:before{content:”\f787”}.fa-moon:before{content:”\f186”}.fa-wine-glass-alt:before,.fa-wine-glass-empty:before{content:”\f5ce”}.fa-cheese:before{content:”\f7ef”}.fa-yin-yang:before{content:”\f6ad”}.fa-music:before{content:”\f001”}.fa-code-commit:before{content:”\f386”}.fa-temperature-low:before{content:”\f76b”}.fa-biking:before,.fa-person-biking:before{content:”\f84a”}.fa-broom:before{content:”\f51a”}.fa-shield-heart:before{content:”\e574”}.fa-gopuram:before{content:”\f664”}.fa-earth-oceania:before,.fa-globe-oceania:before{content:”\e47b”}.fa-square-xmark:before,.fa-times-square:before,.fa-xmark-square:before{content:”\f2d3”}.fa-hashtag:before{content:”\23”}.fa-expand-alt:before,.fa-up-right-and-down-left-from-center:before{content:”\f424”}.fa-oil-can:before{content:”\f613”}.fa-t:before{content:”\54”}.fa-hippo:before{content:”\f6ed”}.fa-chart-column:before{content:”\e0e3”}.fa-infinity:before{content:”\f534”}.fa-vial-circle-check:before{content:”\e596”}.fa-person-arrow-down-to-line:before{content:”\e538”}.fa-voicemail:before{content:”\f897”}.fa-fan:before{content:”\f863”}.fa-person-walking-luggage:before{content:”\e554”}.fa-arrows-alt-v:before,.fa-up-down:before{content:”\f338”}.fa-cloud-moon-rain:before{content:”\f73c”}.fa-calendar:before{content:”\f133”}.fa-trailer:before{content:”\e041”}.fa-bahai:before,.fa-haykal:before{content:”\f666”}.fa-sd-card:before{content:”\f7c2”}.fa-dragon:before{content:”\f6d5”}.fa-shoe-prints:before{content:”\f54b”}.fa-circle-plus:before,.fa-plus-circle:before{content:”\f055”}.fa-face-grin-tongue-wink:before,.fa-grin-tongue-wink:before{content:”\f58b”}.fa-hand-holding:before{content:”\f4bd”}.fa-plug-circle-exclamation:before{content:”\e55d”}.fa-chain-broken:before,.fa-chain-slash:before,.fa-link-slash:before,.fa-unlink:before{content:”\f127”}.fa-clone:before{content:”\f24d”}.fa-person-walking-arrow-loop-left:before{content:”\e551”}.fa-arrow-up-z-a:before,.fa-sort-alpha-up-alt:before{content:”\f882”}.fa-fire-alt:before,.fa-fire-flame-curved:before{content:”\f7e4”}.fa-tornado:before{content:”\f76f”}.fa-file-circle-plus:before{content:”\e494”}.fa-book-quran:before,.fa-quran:before{content:”\f687”}.fa-anchor:before{content:”\f13d”}.fa-border-all:before{content:”\f84c”}.fa-angry:before,.fa-face-angry:before{content:”\f556”}.fa-cookie-bite:before{content:”\f564”}.fa-arrow-trend-down:before{content:”\e097”}.fa-feed:before,.fa-rss:before{content:”\f09e”}.fa-draw-polygon:before{content:”\f5ee”}.fa-balance-scale:before,.fa-scale-balanced:before{content:”\f24e”}.fa-gauge-simple-high:before,.fa-tachometer-fast:before,.fa-tachometer:before{content:”\f62a”}.fa-shower:before{content:”\f2cc”}.fa-desktop-alt:before,.fa-desktop:before{content:”\f390”}.fa-m:before{content:”\4d”}.fa-table-list:before,.fa-th-list:before{content:”\f00b”}.fa-comment-sms:before,.fa-sms:before{content:”\f7cd”}.fa-book:before{content:”\f02d”}.fa-user-plus:before{content:”\f234”}.fa-check:before{content:”\f00c”}.fa-battery-4:before,.fa-battery-three-quarters:before{content:”\f241”}.fa-house-circle-check:before{content:”\e509”}.fa-angle-left:before{content:”\f104”}.fa-diagram-successor:before{content:”\e47a”}.fa-truck-arrow-right:before{content:”\e58b”}.fa-arrows-split-up-and-left:before{content:”\e4bc”}.fa-fist-raised:before,.fa-hand-fist:before{content:”\f6de”}.fa-cloud-moon:before{content:”\f6c3”}.fa-briefcase:before{content:”\f0b1”}.fa-person-falling:before{content:”\e546”}.fa-image-portrait:before,.fa-portrait:before{content:”\f3e0”}.fa-user-tag:before{content:”\f507”}.fa-rug:before{content:”\e569”}.fa-earth-europe:before,.fa-globe-europe:before{content:”\f7a2”}.fa-cart-flatbed-suitcase:before,.fa-luggage-cart:before{content:”\f59d”}.fa-rectangle-times:before,.fa-rectangle-xmark:before,.fa-times-rectangle:before,.fa-window-close:before{content:”\f410”}.fa-baht-sign:before{content:”\e0ac”}.fa-book-open:before{content:”\f518”}.fa-book-journal-whills:before,.fa-journal-whills:before{content:”\f66a”}.fa-handcuffs:before{content:”\e4f8”}.fa-exclamation-triangle:before,.fa-triangle-exclamation:before,.fa-warning:before{content:”\f071”}.fa-database:before{content:”\f1c0”}.fa-arrow-turn-right:before,.fa-mail-forward:before,.fa-share:before{content:”\f064”}.fa-bottle-droplet:before{content:”\e4c4”}.fa-mask-face:before{content:”\e1d7”}.fa-hill-rockslide:before{content:”\e508”}.fa-exchange-alt:before,.fa-right-left:before{content:”\f362”}.fa-paper-plane:before{content:”\f1d8”}.fa-road-circle-exclamation:before{content:”\e565”}.fa-dungeon:before{content:”\f6d9”}.fa-align-right:before{content:”\f038”}.fa-money-bill-1-wave:before,.fa-money-bill-wave-alt:before{content:”\f53b”}.fa-life-ring:before{content:”\f1cd”}.fa-hands:before,.fa-sign-language:before,.fa-signing:before{content:”\f2a7”}.fa-calendar-day:before{content:”\f783”}.fa-ladder-water:before,.fa-swimming-pool:before,.fa-water-ladder:before{content:”\f5c5”}.fa-arrows-up-down:before,.fa-arrows-v:before{content:”\f07d”}.fa-face-grimace:before,.fa-grimace:before{content:”\f57f”}.fa-wheelchair-alt:before,.fa-wheelchair-move:before{content:”\e2ce”}.fa-level-down-alt:before,.fa-turn-down:before{content:”\f3be”}.fa-person-walking-arrow-right:before{content:”\e552”}.fa-envelope-square:before,.fa-square-envelope:before{content:”\f199”}.fa-dice:before{content:”\f522”}.fa-bowling-ball:before{content:”\f436”}.fa-brain:before{content:”\f5dc”}.fa-band-aid:before,.fa-bandage:before{content:”\f462”}.fa-calendar-minus:before{content:”\f272”}.fa-circle-xmark:before,.fa-times-circle:before,.fa-xmark-circle:before{content:”\f057”}.fa-gifts:before{content:”\f79c”}.fa-hotel:before{content:”\f594”}.fa-earth-asia:before,.fa-globe-asia:before{content:”\f57e”}.fa-id-card-alt:before,.fa-id-card-clip:before{content:”\f47f”}.fa-magnifying-glass-plus:before,.fa-search-plus:before{content:”\f00e”}.fa-thumbs-up:before{content:”\f164”}.fa-user-clock:before{content:”\f4fd”}.fa-allergies:before,.fa-hand-dots:before{content:”\f461”}.fa-file-invoice:before{content:”\f570”}.fa-window-minimize:before{content:”\f2d1”}.fa-coffee:before,.fa-mug-saucer:before{content:”\f0f4”}.fa-brush:before{content:”\f55d”}.fa-mask:before{content:”\f6fa”}.fa-magnifying-glass-minus:before,.fa-search-minus:before{content:”\f010”}.fa-ruler-vertical:before{content:”\f548”}.fa-user-alt:before,.fa-user-large:before{content:”\f406”}.fa-train-tram:before{content:”\e5b4”}.fa-user-nurse:before{content:”\f82f”}.fa-syringe:before{content:”\f48e”}.fa-cloud-sun:before{content:”\f6c4”}.fa-stopwatch-20:before{content:”\e06f”}.fa-square-full:before{content:”\f45c”}.fa-magnet:before{content:”\f076”}.fa-jar:before{content:”\e516”}.fa-note-sticky:before,.fa-sticky-note:before{content:”\f249”}.fa-bug-slash:before{content:”\e490”}.fa-arrow-up-from-water-pump:before{content:”\e4b6”}.fa-bone:before{content:”\f5d7”}.fa-user-injured:before{content:”\f728”}.fa-face-sad-tear:before,.fa-sad-tear:before{content:”\f5b4”}.fa-plane:before{content:”\f072”}.fa-tent-arrows-down:before{content:”\e581”}.fa-exclamation:before{content:”\21”}.fa-arrows-spin:before{content:”\e4bb”}.fa-print:before{content:”\f02f”}.fa-try:before,.fa-turkish-lira-sign:before,.fa-turkish-lira:before{content:”\e2bb”}.fa-dollar-sign:before,.fa-dollar:before,.fa-usd:before{content:”\24”}.fa-x:before{content:”\58”}.fa-magnifying-glass-dollar:before,.fa-search-dollar:before{content:”\f688”}.fa-users-cog:before,.fa-users-gear:before{content:”\f509”}.fa-person-military-pointing:before{content:”\e54a”}.fa-bank:before,.fa-building-columns:before,.fa-institution:before,.fa-museum:before,.fa-university:before{content:”\f19c”}.fa-umbrella:before{content:”\f0e9”}.fa-trowel:before{content:”\e589”}.fa-d:before{content:”\44”}.fa-stapler:before{content:”\e5af”}.fa-masks-theater:before,.fa-theater-masks:before{content:”\f630”}.fa-kip-sign:before{content:”\e1c4”}.fa-hand-point-left:before{content:”\f0a5”}.fa-handshake-alt:before,.fa-handshake-simple:before{content:”\f4c6”}.fa-fighter-jet:before,.fa-jet-fighter:before{content:”\f0fb”}.fa-share-alt-square:before,.fa-square-share-nodes:before{content:”\f1e1”}.fa-barcode:before{content:”\f02a”}.fa-plus-minus:before{content:”\e43c”}.fa-video-camera:before,.fa-video:before{content:”\f03d”}.fa-graduation-cap:before,.fa-mortar-board:before{content:”\f19d”}.fa-hand-holding-medical:before{content:”\e05c”}.fa-person-circle-check:before{content:”\e53e”}.fa-level-up-alt:before,.fa-turn-up:before{content:”\f3bf”}
- 9:.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host,:root{–fa-style-family-brands:”Font Awesome 6 Brands”;–fa-font-brands:normal 400 1em/1 “Font Awesome 6 Brands”}@font-face{font-family:”Font Awesome 6 Brands”;font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2) format(“woff2”),url(../webfonts/fa-brands-400.ttf) format(“truetype”)}.fa-brands,.fab{font-weight:400}.fa-monero:before{content:”\f3d0”}.fa-hooli:before{content:”\f427”}.fa-yelp:before{content:”\f1e9”}.fa-cc-visa:before{content:”\f1f0”}.fa-lastfm:before{content:”\f202”}.fa-shopware:before{content:”\f5b5”}.fa-creative-commons-nc:before{content:”\f4e8”}.fa-aws:before{content:”\f375”}.fa-redhat:before{content:”\f7bc”}.fa-yoast:before{content:”\f2b1”}.fa-cloudflare:before{content:”\e07d”}.fa-ups:before{content:”\f7e0”}.fa-wpexplorer:before{content:”\f2de”}.fa-dyalog:before{content:”\f399”}.fa-bity:before{content:”\f37a”}.fa-stackpath:before{content:”\f842”}.fa-buysellads:before{content:”\f20d”}.fa-first-order:before{content:”\f2b0”}.fa-modx:before{content:”\f285”}.fa-guilded:before{content:”\e07e”}.fa-vnv:before{content:”\f40b”}.fa-js-square:before,.fa-square-js:before{content:”\f3b9”}.fa-microsoft:before{content:”\f3ca”}.fa-qq:before{content:”\f1d6”}.fa-orcid:before{content:”\f8d2”}.fa-java:before{content:”\f4e4”}.fa-invision:before{content:”\f7b0”}.fa-creative-commons-pd-alt:before{content:”\f4ed”}.fa-centercode:before{content:”\f380”}.fa-glide-g:before{content:”\f2a6”}.fa-drupal:before{content:”\f1a9”}.fa-hire-a-helper:before{content:”\f3b0”}.fa-creative-commons-by:before{content:”\f4e7”}.fa-unity:before{content:”\e049”}.fa-whmcs:before{content:”\f40d”}.fa-rocketchat:before{content:”\f3e8”}.fa-vk:before{content:”\f189”}.fa-untappd:before{content:”\f405”}.fa-mailchimp:before{content:”\f59e”}.fa-css3-alt:before{content:”\f38b”}.fa-reddit-square:before,.fa-square-reddit:before{content:”\f1a2”}.fa-vimeo-v:before{content:”\f27d”}.fa-contao:before{content:”\f26d”}.fa-square-font-awesome:before{content:”\e5ad”}.fa-deskpro:before{content:”\f38f”}.fa-sistrix:before{content:”\f3ee”}.fa-instagram-square:before,.fa-square-instagram:before{content:”\e055”}.fa-battle-net:before{content:”\f835”}.fa-the-red-yeti:before{content:”\f69d”}.fa-hacker-news-square:before,.fa-square-hacker-news:before{content:”\f3af”}.fa-edge:before{content:”\f282”}.fa-napster:before{content:”\f3d2”}.fa-snapchat-square:before,.fa-square-snapchat:before{content:”\f2ad”}.fa-google-plus-g:before{content:”\f0d5”}.fa-artstation:before{content:”\f77a”}.fa-markdown:before{content:”\f60f”}.fa-sourcetree:before{content:”\f7d3”}.fa-google-plus:before{content:”\f2b3”}.fa-diaspora:before{content:”\f791”}.fa-foursquare:before{content:”\f180”}.fa-stack-overflow:before{content:”\f16c”}.fa-github-alt:before{content:”\f113”}.fa-phoenix-squadron:before{content:”\f511”}.fa-pagelines:before{content:”\f18c”}.fa-algolia:before{content:”\f36c”}.fa-red-river:before{content:”\f3e3”}.fa-creative-commons-sa:before{content:”\f4ef”}.fa-safari:before{content:”\f267”}.fa-google:before{content:”\f1a0”}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:”\f35c”}.fa-atlassian:before{content:”\f77b”}.fa-linkedin-in:before{content:”\f0e1”}.fa-digital-ocean:before{content:”\f391”}.fa-nimblr:before{content:”\f5a8”}.fa-chromecast:before{content:”\f838”}.fa-evernote:before{content:”\f839”}.fa-hacker-news:before{content:”\f1d4”}.fa-creative-commons-sampling:before{content:”\f4f0”}.fa-adversal:before{content:”\f36a”}.fa-creative-commons:before{content:”\f25e”}.fa-watchman-monitoring:before{content:”\e087”}.fa-fonticons:before{content:”\f280”}.fa-weixin:before{content:”\f1d7”}.fa-shirtsinbulk:before{content:”\f214”}.fa-codepen:before{content:”\f1cb”}.fa-git-alt:before{content:”\f841”}.fa-lyft:before{content:”\f3c3”}.fa-rev:before{content:”\f5b2”}.fa-windows:before{content:”\f17a”}.fa-wizards-of-the-coast:before{content:”\f730”}.fa-square-viadeo:before,.fa-viadeo-square:before{content:”\f2aa”}.fa-meetup:before{content:”\f2e0”}.fa-centos:before{content:”\f789”}.fa-adn:before{content:”\f170”}.fa-cloudsmith:before{content:”\f384”}.fa-pied-piper-alt:before{content:”\f1a8”}.fa-dribbble-square:before,.fa-square-dribbble:before{content:”\f397”}.fa-codiepie:before{content:”\f284”}.fa-node:before{content:”\f419”}.fa-mix:before{content:”\f3cb”}.fa-steam:before{content:”\f1b6”}.fa-cc-apple-pay:before{content:”\f416”}.fa-scribd:before{content:”\f28a”}.fa-openid:before{content:”\f19b”}.fa-instalod:before{content:”\e081”}.fa-expeditedssl:before{content:”\f23e”}.fa-sellcast:before{content:”\f2da”}.fa-square-twitter:before,.fa-twitter-square:before{content:”\f081”}.fa-r-project:before{content:”\f4f7”}.fa-delicious:before{content:”\f1a5”}.fa-freebsd:before{content:”\f3a4”}.fa-vuejs:before{content:”\f41f”}.fa-accusoft:before{content:”\f369”}.fa-ioxhost:before{content:”\f208”}.fa-fonticons-fi:before{content:”\f3a2”}.fa-app-store:before{content:”\f36f”}.fa-cc-mastercard:before{content:”\f1f1”}.fa-itunes-note:before{content:”\f3b5”}.fa-golang:before{content:”\e40f”}.fa-kickstarter:before{content:”\f3bb”}.fa-grav:before{content:”\f2d6”}.fa-weibo:before{content:”\f18a”}.fa-uncharted:before{content:”\e084”}.fa-firstdraft:before{content:”\f3a1”}.fa-square-youtube:before,.fa-youtube-square:before{content:”\f431”}.fa-wikipedia-w:before{content:”\f266”}.fa-rendact:before,.fa-wpressr:before{content:”\f3e4”}.fa-angellist:before{content:”\f209”}.fa-galactic-republic:before{content:”\f50c”}.fa-nfc-directional:before{content:”\e530”}.fa-skype:before{content:”\f17e”}.fa-joget:before{content:”\f3b7”}.fa-fedora:before{content:”\f798”}.fa-stripe-s:before{content:”\f42a”}.fa-meta:before{content:”\e49b”}.fa-laravel:before{content:”\f3bd”}.fa-hotjar:before{content:”\f3b1”}.fa-bluetooth-b:before{content:”\f294”}.fa-sticker-mule:before{content:”\f3f7”}.fa-creative-commons-zero:before{content:”\f4f3”}.fa-hips:before{content:”\f452”}.fa-behance:before{content:”\f1b4”}.fa-reddit:before{content:”\f1a1”}.fa-discord:before{content:”\f392”}.fa-chrome:before{content:”\f268”}.fa-app-store-ios:before{content:”\f370”}.fa-cc-discover:before{content:”\f1f2”}.fa-wpbeginner:before{content:”\f297”}.fa-confluence:before{content:”\f78d”}.fa-mdb:before{content:”\f8ca”}.fa-dochub:before{content:”\f394”}.fa-accessible-icon:before{content:”\f368”}.fa-ebay:before{content:”\f4f4”}.fa-amazon:before{content:”\f270”}.fa-unsplash:before{content:”\e07c”}.fa-yarn:before{content:”\f7e3”}.fa-square-steam:before,.fa-steam-square:before{content:”\f1b7”}.fa-500px:before{content:”\f26e”}.fa-square-vimeo:before,.fa-vimeo-square:before{content:”\f194”}.fa-asymmetrik:before{content:”\f372”}.fa-font-awesome-flag:before,.fa-font-awesome-logo-full:before,.fa-font-awesome:before{content:”\f2b4”}.fa-gratipay:before{content:”\f184”}.fa-apple:before{content:”\f179”}.fa-hive:before{content:”\e07f”}.fa-gitkraken:before{content:”\f3a6”}.fa-keybase:before{content:”\f4f5”}.fa-apple-pay:before{content:”\f415”}.fa-padlet:before{content:”\e4a0”}.fa-amazon-pay:before{content:”\f42c”}.fa-github-square:before,.fa-square-github:before{content:”\f092”}.fa-stumbleupon:before{content:”\f1a4”}.fa-fedex:before{content:”\f797”}.fa-phoenix-framework:before{content:”\f3dc”}.fa-shopify:before{content:”\e057”}.fa-neos:before{content:”\f612”}.fa-hackerrank:before{content:”\f5f7”}.fa-researchgate:before{content:”\f4f8”}.fa-swift:before{content:”\f8e1”}.fa-angular:before{content:”\f420”}.fa-speakap:before{content:”\f3f3”}.fa-angrycreative:before{content:”\f36e”}.fa-y-combinator:before{content:”\f23b”}.fa-empire:before{content:”\f1d1”}.fa-envira:before{content:”\f299”}.fa-gitlab-square:before,.fa-square-gitlab:before{content:”\e5ae”}.fa-studiovinari:before{content:”\f3f8”}.fa-pied-piper:before{content:”\f2ae”}.fa-wordpress:before{content:”\f19a”}.fa-product-hunt:before{content:”\f288”}.fa-firefox:before{content:”\f269”}.fa-linode:before{content:”\f2b8”}.fa-goodreads:before{content:”\f3a8”}.fa-odnoklassniki-square:before,.fa-square-odnoklassniki:before{content:”\f264”}.fa-jsfiddle:before{content:”\f1cc”}.fa-sith:before{content:”\f512”}.fa-themeisle:before{content:”\f2b2”}.fa-page4:before{content:”\f3d7”}.fa-hashnode:before{content:”\e499”}.fa-react:before{content:”\f41b”}.fa-cc-paypal:before{content:”\f1f4”}.fa-squarespace:before{content:”\f5be”}.fa-cc-stripe:before{content:”\f1f5”}.fa-creative-commons-share:before{content:”\f4f2”}.fa-bitcoin:before{content:”\f379”}.fa-keycdn:before{content:”\f3ba”}.fa-opera:before{content:”\f26a”}.fa-itch-io:before{content:”\f83a”}.fa-umbraco:before{content:”\f8e8”}.fa-galactic-senate:before{content:”\f50d”}.fa-ubuntu:before{content:”\f7df”}.fa-draft2digital:before{content:”\f396”}.fa-stripe:before{content:”\f429”}.fa-houzz:before{content:”\f27c”}.fa-gg:before{content:”\f260”}.fa-dhl:before{content:”\f790”}.fa-pinterest-square:before,.fa-square-pinterest:before{content:”\f0d3”}.fa-xing:before{content:”\f168”}.fa-blackberry:before{content:”\f37b”}.fa-creative-commons-pd:before{content:”\f4ec”}.fa-playstation:before{content:”\f3df”}.fa-quinscape:before{content:”\f459”}.fa-less:before{content:”\f41d”}.fa-blogger-b:before{content:”\f37d”}.fa-opencart:before{content:”\f23d”}.fa-vine:before{content:”\f1ca”}.fa-paypal:before{content:”\f1ed”}.fa-gitlab:before{content:”\f296”}.fa-typo3:before{content:”\f42b”}.fa-reddit-alien:before{content:”\f281”}.fa-yahoo:before{content:”\f19e”}.fa-dailymotion:before{content:”\e052”}.fa-affiliatetheme:before{content:”\f36b”}.fa-pied-piper-pp:before{content:”\f1a7”}.fa-bootstrap:before{content:”\f836”}.fa-odnoklassniki:before{content:”\f263”}.fa-nfc-symbol:before{content:”\e531”}.fa-ethereum:before{content:”\f42e”}.fa-speaker-deck:before{content:”\f83c”}.fa-creative-commons-nc-eu:before{content:”\f4e9”}.fa-patreon:before{content:”\f3d9”}.fa-avianex:before{content:”\f374”}.fa-ello:before{content:”\f5f1”}.fa-gofore:before{content:”\f3a7”}.fa-bimobject:before{content:”\f378”}.fa-facebook-f:before{content:”\f39e”}.fa-google-plus-square:before,.fa-square-google-plus:before{content:”\f0d4”}.fa-mandalorian:before{content:”\f50f”}.fa-first-order-alt:before{content:”\f50a”}.fa-osi:before{content:”\f41a”}.fa-google-wallet:before{content:”\f1ee”}.fa-d-and-d-beyond:before{content:”\f6ca”}.fa-periscope:before{content:”\f3da”}.fa-fulcrum:before{content:”\f50b”}.fa-cloudscale:before{content:”\f383”}.fa-forumbee:before{content:”\f211”}.fa-mizuni:before{content:”\f3cc”}.fa-schlix:before{content:”\f3ea”}.fa-square-xing:before,.fa-xing-square:before{content:”\f169”}.fa-bandcamp:before{content:”\f2d5”}.fa-wpforms:before{content:”\f298”}.fa-cloudversify:before{content:”\f385”}.fa-usps:before{content:”\f7e1”}.fa-megaport:before{content:”\f5a3”}.fa-magento:before{content:”\f3c4”}.fa-spotify:before{content:”\f1bc”}.fa-optin-monster:before{content:”\f23c”}.fa-fly:before{content:”\f417”}.fa-aviato:before{content:”\f421”}.fa-itunes:before{content:”\f3b4”}.fa-cuttlefish:before{content:”\f38c”}.fa-blogger:before{content:”\f37c”}.fa-flickr:before{content:”\f16e”}.fa-viber:before{content:”\f409”}.fa-soundcloud:before{content:”\f1be”}.fa-digg:before{content:”\f1a6”}.fa-tencent-weibo:before{content:”\f1d5”}.fa-symfony:before{content:”\f83d”}.fa-maxcdn:before{content:”\f136”}.fa-etsy:before{content:”\f2d7”}.fa-facebook-messenger:before{content:”\f39f”}.fa-audible:before{content:”\f373”}.fa-think-peaks:before{content:”\f731”}.fa-bilibili:before{content:”\e3d9”}.fa-erlang:before{content:”\f39d”}.fa-cotton-bureau:before{content:”\f89e”}.fa-dashcube:before{content:”\f210”}.fa-42-group:before,.fa-innosoft:before{content:”\e080”}.fa-stack-exchange:before{content:”\f18d”}.fa-elementor:before{content:”\f430”}.fa-pied-piper-square:before,.fa-square-pied-piper:before{content:”\e01e”}.fa-creative-commons-nd:before{content:”\f4eb”}.fa-palfed:before{content:”\f3d8”}.fa-superpowers:before{content:”\f2dd”}.fa-resolving:before{content:”\f3e7”}.fa-xbox:before{content:”\f412”}.fa-searchengin:before{content:”\f3eb”}.fa-tiktok:before{content:”\e07b”}.fa-facebook-square:before,.fa-square-facebook:before{content:”\f082”}.fa-renren:before{content:”\f18b”}.fa-linux:before{content:”\f17c”}.fa-glide:before{content:”\f2a5”}.fa-linkedin:before{content:”\f08c”}.fa-hubspot:before{content:”\f3b2”}.fa-deploydog:before{content:”\f38e”}.fa-twitch:before{content:”\f1e8”}.fa-ravelry:before{content:”\f2d9”}.fa-mixer:before{content:”\e056”}.fa-lastfm-square:before,.fa-square-lastfm:before{content:”\f203”}.fa-vimeo:before{content:”\f40a”}.fa-mendeley:before{content:”\f7b3”}.fa-uniregistry:before{content:”\f404”}.fa-figma:before{content:”\f799”}.fa-creative-commons-remix:before{content:”\f4ee”}.fa-cc-amazon-pay:before{content:”\f42d”}.fa-dropbox:before{content:”\f16b”}.fa-instagram:before{content:”\f16d”}.fa-cmplid:before{content:”\e360”}.fa-facebook:before{content:”\f09a”}.fa-gripfire:before{content:”\f3ac”}.fa-jedi-order:before{content:”\f50e”}.fa-uikit:before{content:”\f403”}.fa-fort-awesome-alt:before{content:”\f3a3”}.fa-phabricator:before{content:”\f3db”}.fa-ussunnah:before{content:”\f407”}.fa-earlybirds:before{content:”\f39a”}.fa-trade-federation:before{content:”\f513”}.fa-autoprefixer:before{content:”\f41c”}.fa-whatsapp:before{content:”\f232”}.fa-slideshare:before{content:”\f1e7”}.fa-google-play:before{content:”\f3ab”}.fa-viadeo:before{content:”\f2a9”}.fa-line:before{content:”\f3c0”}.fa-google-drive:before{content:”\f3aa”}.fa-servicestack:before{content:”\f3ec”}.fa-simplybuilt:before{content:”\f215”}.fa-bitbucket:before{content:”\f171”}.fa-imdb:before{content:”\f2d8”}.fa-deezer:before{content:”\e077”}.fa-raspberry-pi:before{content:”\f7bb”}.fa-jira:before{content:”\f7b1”}.fa-docker:before{content:”\f395”}.fa-screenpal:before{content:”\e570”}.fa-bluetooth:before{content:”\f293”}.fa-gitter:before{content:”\f426”}.fa-d-and-d:before{content:”\f38d”}.fa-microblog:before{content:”\e01a”}.fa-cc-diners-club:before{content:”\f24c”}.fa-gg-circle:before{content:”\f261”}.fa-pied-piper-hat:before{content:”\f4e5”}.fa-kickstarter-k:before{content:”\f3bc”}.fa-yandex:before{content:”\f413”}.fa-readme:before{content:”\f4d5”}.fa-html5:before{content:”\f13b”}.fa-sellsy:before{content:”\f213”}.fa-sass:before{content:”\f41e”}.fa-wirsindhandwerk:before,.fa-wsh:before{content:”\e2d0”}.fa-buromobelexperte:before{content:”\f37f”}.fa-salesforce:before{content:”\f83b”}.fa-octopus-deploy:before{content:”\e082”}.fa-medapps:before{content:”\f3c6”}.fa-ns8:before{content:”\f3d5”}.fa-pinterest-p:before{content:”\f231”}.fa-apper:before{content:”\f371”}.fa-fort-awesome:before{content:”\f286”}.fa-waze:before{content:”\f83f”}.fa-cc-jcb:before{content:”\f24b”}.fa-snapchat-ghost:before,.fa-snapchat:before{content:”\f2ab”}.fa-fantasy-flight-games:before{content:”\f6dc”}.fa-rust:before{content:”\e07a”}.fa-wix:before{content:”\f5cf”}.fa-behance-square:before,.fa-square-behance:before{content:”\f1b5”}.fa-supple:before{content:”\f3f9”}.fa-rebel:before{content:”\f1d0”}.fa-css3:before{content:”\f13c”}.fa-staylinked:before{content:”\f3f5”}.fa-kaggle:before{content:”\f5fa”}.fa-space-awesome:before{content:”\e5ac”}.fa-deviantart:before{content:”\f1bd”}.fa-cpanel:before{content:”\f388”}.fa-goodreads-g:before{content:”\f3a9”}.fa-git-square:before,.fa-square-git:before{content:”\f1d2”}.fa-square-tumblr:before,.fa-tumblr-square:before{content:”\f174”}.fa-trello:before{content:”\f181”}.fa-creative-commons-nc-jp:before{content:”\f4ea”}.fa-get-pocket:before{content:”\f265”}.fa-perbyte:before{content:”\e083”}.fa-grunt:before{content:”\f3ad”}.fa-weebly:before{content:”\f5cc”}.fa-connectdevelop:before{content:”\f20e”}.fa-leanpub:before{content:”\f212”}.fa-black-tie:before{content:”\f27e”}.fa-themeco:before{content:”\f5c6”}.fa-python:before{content:”\f3e2”}.fa-android:before{content:”\f17b”}.fa-bots:before{content:”\e340”}.fa-free-code-camp:before{content:”\f2c5”}.fa-hornbill:before{content:”\f592”}.fa-js:before{content:”\f3b8”}.fa-ideal:before{content:”\e013”}.fa-git:before{content:”\f1d3”}.fa-dev:before{content:”\f6cc”}.fa-sketch:before{content:”\f7c6”}.fa-yandex-international:before{content:”\f414”}.fa-cc-amex:before{content:”\f1f3”}.fa-uber:before{content:”\f402”}.fa-github:before{content:”\f09b”}.fa-php:before{content:”\f457”}.fa-alipay:before{content:”\f642”}.fa-youtube:before{content:”\f167”}.fa-skyatlas:before{content:”\f216”}.fa-firefox-browser:before{content:”\e007”}.fa-replyd:before{content:”\f3e6”}.fa-suse:before{content:”\f7d6”}.fa-jenkins:before{content:”\f3b6”}.fa-twitter:before{content:”\f099”}.fa-rockrms:before{content:”\f3e9”}.fa-pinterest:before{content:”\f0d2”}.fa-buffer:before{content:”\f837”}.fa-npm:before{content:”\f3d4”}.fa-yammer:before{content:”\f840”}.fa-btc:before{content:”\f15a”}.fa-dribbble:before{content:”\f17d”}.fa-stumbleupon-circle:before{content:”\f1a3”}.fa-internet-explorer:before{content:”\f26b”}.fa-stubber:before{content:”\e5c7”}.fa-telegram-plane:before,.fa-telegram:before{content:”\f2c6”}.fa-old-republic:before{content:”\f510”}.fa-odysee:before{content:”\e5c6”}.fa-square-whatsapp:before,.fa-whatsapp-square:before{content:”\f40c”}.fa-node-js:before{content:”\f3d3”}.fa-edge-legacy:before{content:”\e078”}.fa-slack-hash:before,.fa-slack:before{content:”\f198”}.fa-medrt:before{content:”\f3c8”}.fa-usb:before{content:”\f287”}.fa-tumblr:before{content:”\f173”}.fa-vaadin:before{content:”\f408”}.fa-quora:before{content:”\f2c4”}.fa-reacteurope:before{content:”\f75d”}.fa-medium-m:before,.fa-medium:before{content:”\f23a”}.fa-amilia:before{content:”\f36d”}.fa-mixcloud:before{content:”\f289”}.fa-flipboard:before{content:”\f44d”}.fa-viacoin:before{content:”\f237”}.fa-critical-role:before{content:”\f6c9”}.fa-sitrox:before{content:”\e44a”}.fa-discourse:before{content:”\f393”}.fa-joomla:before{content:”\f1aa”}.fa-mastodon:before{content:”\f4f6”}.fa-airbnb:before{content:”\f834”}.fa-wolf-pack-battalion:before{content:”\f514”}.fa-buy-n-large:before{content:”\f8a6”}.fa-gulp:before{content:”\f3ae”}.fa-creative-commons-sampling-plus:before{content:”\f4f1”}.fa-strava:before{content:”\f428”}.fa-ember:before{content:”\f423”}.fa-canadian-maple-leaf:before{content:”\f785”}.fa-teamspeak:before{content:”\f4f9”}.fa-pushed:before{content:”\f3e1”}.fa-wordpress-simple:before{content:”\f411”}.fa-nutritionix:before{content:”\f3d6”}.fa-wodu:before{content:”\e088”}.fa-google-pay:before{content:”\e079”}.fa-intercom:before{content:”\f7af”}.fa-zhihu:before{content:”\f63f”}.fa-korvue:before{content:”\f42f”}.fa-pix:before{content:”\e43a”}.fa-steam-symbol:before{content:”\f3f6”}:host,:root{–fa-font-regular:normal 400 1em/1 “Font Awesome 6 Free”}@font-face{font-family:”Font Awesome 6 Free”;font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format(“woff2”),url(../webfonts/fa-regular-400.ttf) format(“truetype”)}.fa-regular,.far{font-weight:400}:host,:root{–fa-style-family-classic:”Font Awesome 6 Free”;–fa-font-solid:normal 900 1em/1 “Font Awesome 6 Free”}@font-face{font-family:”Font Awesome 6 Free”;font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format(“woff2”),url(../webfonts/fa-solid-900.ttf) format(“truetype”)}.fa-solid,.fas{font-weight:900}@font-face{font-family:”Font Awesome 5 Brands”;font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format(“woff2”),url(../webfonts/fa-brands-400.ttf) format(“truetype”)}@font-face{font-family:”Font Awesome 5 Free”;font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format(“woff2”),url(../webfonts/fa-solid-900.ttf) format(“truetype”)}@font-face{font-family:”Font Awesome 5 Free”;font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format(“woff2”),url(../webfonts/fa-regular-400.ttf) format(“truetype”)}@font-face{font-family:”FontAwesome”;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format(“woff2”),url(../webfonts/fa-solid-900.ttf) format(“truetype”)}@font-face{font-family:”FontAwesome”;font-display:block;src:url(../webfonts/fa-brands-400.woff2) format(“woff2”),url(../webfonts/fa-brands-400.ttf) format(“truetype”)}@font-face{font-family:”FontAwesome”;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format(“woff2”),url(../webfonts/fa-regular-400.ttf) format(“truetype”);unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:”FontAwesome”;font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format(“woff2”),url(../webfonts/fa-v4compatibility.ttf) format(“truetype”);unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a}
web/marketing/scripts/waitlist.js
- File type: JavaScript
- 1:const WAITLIST_ENDPOINT =
- 6:const waitlistForm = document.getElementById(“waitlist-form”);
- 7:const waitlistStatus = document.getElementById(“waitlist-status”);
- 9:function setWaitlistStatus(message, tone = “neutral”) {
- 15:function isValidEmail(email) {
- 20:async function getAuthHeader() {
web/marketing/scripts/main.js
- File type: JavaScript
- 2:const SUPABASE_URL = document.querySelector(‘meta[name=”supabase-url”]’)?.getAttribute(“content”) ?? “”;
- 3:const SUPABASE_ANON_KEY = document.querySelector(‘meta[name=”supabase-anon-key”]’)?.getAttribute(“content”) ?? “”;
- 7:let stSupabase = null;
- 8:let stSupabaseAuthListenerBound = false;
- 9:function tryInitSupabaseClient() {
- 30:const AUTH_RETURN_SESSION_KEY = “speaktrue.auth.return_expected”;
- 31:const MARKETING_SIGN_OUT_QUERY_PARAM = “speaktrue_sign_out”;
- 33:function readMetaContent(name) {
- 37:function resolvePostLoginRedirectTarget() {
- 53:function appendSessionTransferFragment(redirectTarget, session) {
web/marketing/scripts/theme_boot.js
- File type: JavaScript
- 31: function normalizeThemeId(themeId) {
web/marketing/scripts/deploy_refresh.js
- File type: JavaScript
- 14: function readCurrentVersion() {
- 24: function storageGet(storage, key) {
- 32: function storageSet(storage, key, value) {
- 40: function isStableDeployVersion(version) {
- 48: function currentUrlHasRefreshMarker(version) {
- 57: function samePathReload(version) {
- 73: function reloadForVersion(version) {
- 83: function rememberCurrentVersion(version) {
- 88: function readManifestVersion(payload) {
- 92: function pollManifest(manifestUrl, currentVersion) {
web/python-web-app/docs/SUPABASE_MIGRATION_CONTRACT.md
- File type: Other
web/python-web-app/docs/SUPABASE_EDGE_ROLLOUT.md
- File type: Other
web/python-web-app/docs/SUPABASE_STRICT_TEST_PLAN.md
- File type: Other
web/python-web-app/docs/SOUNDBOARD_CATEGORY_AND_ORDERING.md
- File type: Other
web/python-web-app/static/css/index_slow.css
- File type: CSS
- 1::root {
- 4897:@keyframes spin {
web/python-web-app/static/js/index_speech.js
- File type: JavaScript
- 1: function updateSelectedModel(sourceType) {
- 25: function updatePronunciationStatus(isEnabled) {
- 53: function flattenSoundboardCategoryTargets(nodes, targets = [], depth = 0) {
- 81: function setCategoryDropdownOptions(categoryDropdown, options, emptyLabel) {
- 105: async function refreshSaveCategoryOptions({
- 150: function exposeTTSSoundboardWorkflowState() {
- 164: function clearLatestArtifact(reason) {
- 170: function setLatestArtifact(artifact) {
- 176: function soundboardToast(message, type, duration) {
- 186: function mergeAuthHeaders(extra) {
web/python-web-app/static/js/index_sts_live_voice.js
- File type: JavaScript
- 7: function decodeBase64ToBytes(base64) {
- 16: function pcm16Base64ToFloat32(base64) {
- 26: function openSocket(url) {
- 61: function buildSocketUrl(tts) {
- 78: function voiceSettingsFromSession(tts) {
- 88: async function createSTSLiveVoiceTTSPlayer(session, callbacks) {
- 111: function currentStats(status) {
- 123: function emitState(status) {
- 129: function wait(ms) {
- 133: function playAudioBase64(base64) {
web/python-web-app/static/js/index_voice_cloning.js
- File type: JavaScript
- 1: function initializeVoiceCloningTab() {
- 9: function mergeVoiceCloneAuthHeaders(extra) {
- 16: function resolveVoiceCloneAuthHeaders(extra) {
- 38: function getVoiceClonePreflightState() {
- 49: function computeUploadFingerprint() {
- 57: function invalidateVoiceClonePreflight(reasonText) {
- 73: function renderVoiceClonePreflightResult(result) {
- 100: function runVoiceClonePreflight() {
- 170: function customVoicesAuthKey(headers) {
- 177: function loadCustomVoices(options) {
web/python-web-app/static/js/deploy_refresh.js
- File type: JavaScript
- 14: function readCurrentVersion() {
- 24: function storageGet(storage, key) {
- 32: function storageSet(storage, key, value) {
- 40: function isStableDeployVersion(version) {
- 48: function currentUrlHasRefreshMarker(version) {
- 57: function samePathReload(version) {
- 73: function reloadForVersion(version) {
- 83: function rememberCurrentVersion(version) {
- 88: function readManifestVersion(payload) {
- 92: function pollManifest(manifestUrl, currentVersion) {
web/python-web-app/static/js/theme_boot.js
- File type: JavaScript
- 31: function normalizeThemeId(themeId) {
web/python-web-app/static/js/theme_catalog.js
- File type: JavaScript
- 24: function normalizeThemeId(themeId) {
- 35: function resolveEffectiveTheme(options) {
- 49: function readThemeFromLocalStorage() {
- 57: function attemptThemeLocalStorageWrite(themeId) {
- 67: function writeThemeToLocalStorage(themeId) {
- 71: function readAuthHeader() {
- 82: function isSignedIn() {
- 86: function parseHexColor(hexColor) {
- 98: function mixColors(hexA, hexB, ratio) {
- 108: function withAlpha(hexColor, alpha) {
web/python-web-app/static/js/email_sign_in.js
- File type: JavaScript
- 19: function getModal() {
- 22: function getForm() {
- 25: function getErrorEl() {
- 28: function getStatusEl() {
- 31: function getConfirmationEl() {
- 34: function getPasswordConfirmEl() {
- 37: function getPasswordRequirementsEl() {
- 40: function evaluateEmailPasswordRequirements(password) {
- 49: function findFirstMissingEmailPasswordRequirement(password) {
- 53: function updateEmailPasswordRequirements(password) {
web/python-web-app/static/js/index_core.js
- File type: JavaScript
- 1:function mergeSupabaseAuthHeaders(extra) {
- 11: function themeColor(variableName, fallback) {
- 51: function resolveThemeToken(tokenKey) {
- 79: function refreshUiThemeTokens() {
- 151: function initAIDataSharingAgreementGate() {
- 174: function setError(message) {
- 180: function setGateMode(mode) {
- 192: function updateSettingsAccessClass() {
- 198: function openSettingsTab() {
- 206: function resetNoticeScroll() {
web/python-web-app/static/js/index_settings.js
- File type: JavaScript
- 14: function isWebSubscriptionUIEnabled() {
- 18: function readSupabaseJwtEmail() {
- 40: function _resolveSignedInUserLabelFromSessionUser(user) {
- 53: function refreshAllSessionUI() {
- 54: function updateSettingsHubAccountSubtitle(signedInLabel) {
- 64: function applySignedInState(label) {
- 145: function refreshSettingsAccountPanel() {
- 154: function showSettingsHub() {
- 167: function openSettingsSection(sectionId) {
- 208: function loadProSubscriptionStatusForSettings() {
web/python-web-app/static/js/index_soundboard.js
- File type: JavaScript
- 28: function getClipControlsPinnedPreference() {
- 36: function setClipControlsPinnedPreference(isPinned) {
- 46: function syncClipControlsPinnedState(isPinned) {
- 64: function initializeClipControlsPinToggle() {
- 78: function soundboardMediaCacheKey(categoryId, kind, filename) {
- 82: function soundboardDurationCacheKeys(audioUrl, filename = null) {
- 93: function rememberSoundboardDuration(audioUrl, filename, durationText) {
- 104: function getRememberedSoundboardDuration(audioUrl, filename = null) {
- 112: function rememberSoundboardDurationSeconds(audioUrl, filename, seconds) {
- 119: function getRememberedSoundboardDurationSeconds(audioUrl, filename = null) {
web/marketing/auth/callback/index.html
- File type: HTML