Showing preview only (8,242K chars total). Download the full file or copy to clipboard to get everything.
Repository: dotnet/eShopSupport
Branch: main
Commit: 1a772ff84f75
Files: 302
Total size: 22.5 MB
Directory structure:
gitextract_9atq3bqx/
├── .config/
│ └── dotnet-tools.json
├── .editorconfig
├── .gitignore
├── CODE_OF_CONDUCT.md
├── Directory.Build.props
├── Directory.Packages.props
├── LICENSE
├── README.md
├── SECURITY.md
├── docs/
│ └── Architecture.pptx
├── eShopSupport.sln
├── nuget.config
├── seeddata/
│ ├── DataGenerator/
│ │ ├── .gitignore
│ │ ├── ChatCompletionServiceExtensions.cs
│ │ ├── DataGenerator.csproj
│ │ ├── Generators/
│ │ │ ├── CategoryGenerator.cs
│ │ │ ├── EvalQuestionGenerator.cs
│ │ │ ├── GeneratorBase.cs
│ │ │ ├── LocalTextEmbeddingGenerator.cs
│ │ │ ├── ManualGenerator.cs
│ │ │ ├── ManualPdfConverter.cs
│ │ │ ├── ManualTocGenerator.cs
│ │ │ ├── ProductGenerator.cs
│ │ │ ├── TicketGenerator.cs
│ │ │ ├── TicketSummaryGenerator.cs
│ │ │ └── TicketThreadGenerator.cs
│ │ ├── Model/
│ │ │ ├── Category.cs
│ │ │ ├── EvalQuestion.cs
│ │ │ ├── Manual.cs
│ │ │ ├── ManualPdf.cs
│ │ │ ├── ManualToc.cs
│ │ │ ├── Product.cs
│ │ │ ├── Role.cs
│ │ │ ├── Ticket.cs
│ │ │ ├── TicketThread.cs
│ │ │ └── TicketThreadMessage.cs
│ │ ├── Program.cs
│ │ └── appsettings.json
│ ├── dev/
│ │ ├── categories.json
│ │ ├── customers.json
│ │ ├── evalquestions.json
│ │ ├── manual-chunks.json
│ │ ├── products.json
│ │ └── tickets.json
│ └── test/
│ ├── categories.json
│ ├── customers.json
│ ├── evalquestions.json
│ ├── manual-chunks.json
│ ├── products.json
│ └── tickets.json
├── src/
│ ├── AppHost/
│ │ ├── .gitignore
│ │ ├── AppHost.csproj
│ │ ├── Ollama/
│ │ │ ├── OllamaResource.cs
│ │ │ └── OllamaResourceExtensions.cs
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── Python/
│ │ │ └── PythonUvicornAppResourceBuilderExtensions.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
│ ├── Backend/
│ │ ├── Api/
│ │ │ ├── AssistantApi.cs
│ │ │ ├── CatalogApi.cs
│ │ │ ├── TicketApi.cs
│ │ │ └── TicketMessagingApi.cs
│ │ ├── Backend.csproj
│ │ ├── Data/
│ │ │ ├── AppDbContext.cs
│ │ │ ├── AsyncEnumerableExtensions.cs
│ │ │ ├── Customer.cs
│ │ │ ├── ManualChunk.cs
│ │ │ ├── Message.cs
│ │ │ ├── Product.cs
│ │ │ ├── ProductCategory.cs
│ │ │ └── Ticket.cs
│ │ ├── HttpContextUserIdentityExtensions.cs
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── Services/
│ │ │ ├── ProductManualSemanticSearch.cs
│ │ │ ├── ProductSemanticSearch.cs
│ │ │ └── TicketSummarizer.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
│ ├── CustomerWebUI/
│ │ ├── Components/
│ │ │ ├── App.razor
│ │ │ ├── Layout/
│ │ │ │ ├── FooterBar.razor
│ │ │ │ ├── FooterBar.razor.css
│ │ │ │ ├── HeaderBar.razor
│ │ │ │ ├── HeaderBar.razor.css
│ │ │ │ ├── MainLayout.razor
│ │ │ │ ├── MainLayout.razor.css
│ │ │ │ ├── UserMenu.razor
│ │ │ │ └── UserMenu.razor.css
│ │ │ ├── Pages/
│ │ │ │ ├── Error.razor
│ │ │ │ ├── Home.razor
│ │ │ │ └── Support/
│ │ │ │ ├── Ticket.razor
│ │ │ │ ├── Ticket.razor.css
│ │ │ │ ├── TicketCreate.razor
│ │ │ │ ├── TicketCreate.razor.css
│ │ │ │ ├── TicketList.razor
│ │ │ │ └── TicketList.razor.css
│ │ │ ├── Routes.razor
│ │ │ └── _Imports.razor
│ │ ├── CustomerWebUI.csproj
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ └── wwwroot/
│ │ └── css/
│ │ ├── app.css
│ │ └── normalize.css
│ ├── DataIngestor/
│ │ ├── DataIngestor.csproj
│ │ ├── EvalQuestionIngestor.cs
│ │ ├── ManualIngestor.cs
│ │ ├── ManualZipIngestor.cs
│ │ ├── PathUtils.cs
│ │ ├── ProductCategoryIngestor.cs
│ │ ├── ProductIngestor.cs
│ │ ├── Program.cs
│ │ └── TicketIngestor.cs
│ ├── Evaluator/
│ │ ├── .gitignore
│ │ ├── EvalQuestion.cs
│ │ ├── Evaluator.csproj
│ │ ├── Program.cs
│ │ └── appsettings.json
│ ├── IdentityServer/
│ │ ├── .gitignore
│ │ ├── Config.cs
│ │ ├── HostingExtensions.cs
│ │ ├── IdentityServer.csproj
│ │ ├── Pages/
│ │ │ ├── Account/
│ │ │ │ ├── AccessDenied.cshtml
│ │ │ │ ├── AccessDenied.cshtml.cs
│ │ │ │ ├── Create/
│ │ │ │ │ ├── Index.cshtml
│ │ │ │ │ ├── Index.cshtml.cs
│ │ │ │ │ └── InputModel.cs
│ │ │ │ ├── Login/
│ │ │ │ │ ├── Index.cshtml
│ │ │ │ │ ├── Index.cshtml.cs
│ │ │ │ │ ├── InputModel.cs
│ │ │ │ │ ├── LoginOptions.cs
│ │ │ │ │ └── ViewModel.cs
│ │ │ │ └── Logout/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── LoggedOut.cshtml
│ │ │ │ ├── LoggedOut.cshtml.cs
│ │ │ │ ├── LoggedOutViewModel.cs
│ │ │ │ └── LogoutOptions.cs
│ │ │ ├── Ciba/
│ │ │ │ ├── All.cshtml
│ │ │ │ ├── All.cshtml.cs
│ │ │ │ ├── Consent.cshtml
│ │ │ │ ├── Consent.cshtml.cs
│ │ │ │ ├── ConsentOptions.cs
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── InputModel.cs
│ │ │ │ ├── ViewModel.cs
│ │ │ │ └── _ScopeListItem.cshtml
│ │ │ ├── Consent/
│ │ │ │ ├── ConsentOptions.cs
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── InputModel.cs
│ │ │ │ ├── ViewModel.cs
│ │ │ │ └── _ScopeListItem.cshtml
│ │ │ ├── Device/
│ │ │ │ ├── DeviceOptions.cs
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── InputModel.cs
│ │ │ │ ├── Success.cshtml
│ │ │ │ ├── Success.cshtml.cs
│ │ │ │ ├── ViewModel.cs
│ │ │ │ └── _ScopeListItem.cshtml
│ │ │ ├── Diagnostics/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ └── ViewModel.cs
│ │ │ ├── Extensions.cs
│ │ │ ├── ExternalLogin/
│ │ │ │ ├── Callback.cshtml
│ │ │ │ ├── Callback.cshtml.cs
│ │ │ │ ├── Challenge.cshtml
│ │ │ │ └── Challenge.cshtml.cs
│ │ │ ├── Grants/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ └── ViewModel.cs
│ │ │ ├── Home/
│ │ │ │ └── Error/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ └── ViewModel.cs
│ │ │ ├── IdentityServerSuppressions.cs
│ │ │ ├── Index.cshtml
│ │ │ ├── Index.cshtml.cs
│ │ │ ├── Log.cs
│ │ │ ├── Redirect/
│ │ │ │ ├── Index.cshtml
│ │ │ │ └── Index.cshtml.cs
│ │ │ ├── SecurityHeadersAttribute.cs
│ │ │ ├── ServerSideSessions/
│ │ │ │ ├── Index.cshtml
│ │ │ │ └── Index.cshtml.cs
│ │ │ ├── Shared/
│ │ │ │ ├── _Layout.cshtml
│ │ │ │ ├── _Nav.cshtml
│ │ │ │ └── _ValidationSummary.cshtml
│ │ │ ├── Telemetry.cs
│ │ │ ├── TestUsers.cs
│ │ │ ├── _ViewImports.cshtml
│ │ │ └── _ViewStart.cshtml
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── appsettings.json
│ │ └── wwwroot/
│ │ ├── css/
│ │ │ ├── site.css
│ │ │ └── site.scss
│ │ ├── js/
│ │ │ ├── signin-redirect.js
│ │ │ └── signout-redirect.js
│ │ └── lib/
│ │ ├── bootstrap/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ └── dist/
│ │ │ ├── css/
│ │ │ │ ├── bootstrap-grid.css
│ │ │ │ ├── bootstrap-reboot.css
│ │ │ │ └── bootstrap.css
│ │ │ └── js/
│ │ │ ├── bootstrap.bundle.js
│ │ │ └── bootstrap.js
│ │ ├── bootstrap4-glyphicons/
│ │ │ ├── LICENSE
│ │ │ ├── css/
│ │ │ │ └── bootstrap-glyphicons.css
│ │ │ └── maps/
│ │ │ ├── glyphicons-fontawesome.css
│ │ │ └── glyphicons-fontawesome.less
│ │ └── jquery/
│ │ ├── LICENSE.txt
│ │ ├── README.md
│ │ └── dist/
│ │ ├── jquery.js
│ │ └── jquery.slim.js
│ ├── PythonInference/
│ │ ├── PythonInference.pyproj
│ │ ├── main.py
│ │ ├── requirements.txt
│ │ └── routers/
│ │ ├── classifier.py
│ │ └── embedder.py
│ ├── ServiceDefaults/
│ │ ├── Clients/
│ │ │ ├── Backend/
│ │ │ │ ├── CustomerBackendClient.cs
│ │ │ │ ├── DevToolBackendClient.cs
│ │ │ │ └── StaffBackendClient.cs
│ │ │ ├── ChatCompletion/
│ │ │ │ ├── ChatCompletionServiceExtensions.cs
│ │ │ │ ├── PreventStreamingWithFunctions.cs
│ │ │ │ ├── ServiceCollectionChatClientExtensions.cs
│ │ │ │ └── TestCachingChatClientBuilderExtensions.cs
│ │ │ ├── HttpClientExtensions.cs
│ │ │ ├── PythonInference/
│ │ │ │ └── PythonInferenceClient.cs
│ │ │ └── QdrantHttpClientExtensions.cs
│ │ ├── Extensions.cs
│ │ └── ServiceDefaults.csproj
│ └── StaffWebUI/
│ ├── Components/
│ │ ├── App.razor
│ │ ├── Layout/
│ │ │ ├── LoginDisplay.razor
│ │ │ ├── LoginDisplay.razor.css
│ │ │ ├── MainLayout.razor
│ │ │ ├── MainLayout.razor.css
│ │ │ ├── ThemePicker.razor
│ │ │ ├── ThemePicker.razor.css
│ │ │ └── Title.razor
│ │ ├── Pages/
│ │ │ ├── Account/
│ │ │ │ └── AccessDenied.razor
│ │ │ ├── Error.razor
│ │ │ ├── RedisSubscribingComponent.cs
│ │ │ ├── Ticket/
│ │ │ │ ├── Ticket.razor
│ │ │ │ ├── Ticket.razor.css
│ │ │ │ ├── TicketAssistant.razor
│ │ │ │ ├── TicketAssistant.razor.css
│ │ │ │ ├── TicketAssistant.razor.js
│ │ │ │ ├── TicketAssistantMessage.razor
│ │ │ │ ├── TicketAssistantMessage.razor.css
│ │ │ │ ├── TicketAssistantMessage.razor.js
│ │ │ │ ├── TicketDetails.razor
│ │ │ │ ├── TicketDetails.razor.css
│ │ │ │ ├── TicketMessages.razor
│ │ │ │ └── TicketMessages.razor.css
│ │ │ └── Tickets/
│ │ │ ├── Columns/
│ │ │ │ ├── LinkPropertyColumn.cs
│ │ │ │ └── LinkTemplateColumn.cs
│ │ │ ├── SatisfactionIndicator.razor
│ │ │ ├── SatisfactionIndicator.razor.css
│ │ │ ├── Tickets.razor
│ │ │ ├── Tickets.razor.css
│ │ │ ├── TicketsFilter.razor
│ │ │ └── TicketsFilter.razor.css
│ │ ├── Routes.razor
│ │ └── _Imports.razor
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── StaffWebUI.csproj
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── wwwroot/
│ ├── app.css
│ ├── manual.html
│ ├── pdfjs-4.2.67-dist/
│ │ ├── LICENSE
│ │ ├── build/
│ │ │ ├── pdf.mjs
│ │ │ ├── pdf.sandbox.mjs
│ │ │ └── pdf.worker.mjs
│ │ └── web/
│ │ ├── viewer.css
│ │ ├── viewer.html
│ │ └── viewer.mjs
│ └── theme-info.js
└── test/
├── E2ETest/
│ ├── ChatCompletionCache/
│ │ ├── 5AF0103EF2560BEC4FE94D21D18E3A1945C5202F7B452834A8FFC891322F321A.json
│ │ ├── 6981B02D1211D89EAD2B18D2A00BC2CC55A0CAA06E294C0318ADBB35112EB9D7.json
│ │ ├── 973247AA1FE93490986EF3435E4C6D88928EC469857A873D0899EB4389672BB0.json
│ │ ├── C70A33FF52171DCD96D2BF8F41BC45DE1FA308FAF38030F5EFE5764FDA6F787A.json
│ │ ├── E55E8743B91B9650A9C60E7DF7627B0B5C39C8CD35093DF9D6F6EE4CF476FE87.json
│ │ └── F7F43C2AD0BFAB1D1CEECA1454D8C1DD286336B9E097A32FA1A8FFEEA785937E.json
│ ├── E2ETest.csproj
│ ├── GlobalUsings.cs
│ ├── Infrastructure/
│ │ ├── AppHostFixture.cs
│ │ ├── AppTestCollection.cs
│ │ ├── LoginExtensions.cs
│ │ └── PlaywrightTestBase.cs
│ ├── TicketAssistantTest.cs
│ └── TicketsListTest.cs
└── EvaluationTests/
├── AnswerScoringEvaluator.cs
├── EvalQuestion.cs
├── EvaluationTests.cs
├── EvaluationTests.csproj
├── README.md
├── Settings.cs
└── appsettings.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .config/dotnet-tools.json
================================================
{
"version": 1,
"isRoot": true,
"tools": {
"microsoft.extensions.ai.evaluation.console": {
"version": "9.3.0-preview.1.25126.9",
"commands": [
"aieval"
],
"rollForward": false
}
}
}
================================================
FILE: .editorconfig
================================================
###############################
# Core EditorConfig Options #
###############################
root = true
# All files
[*]
indent_style = space
# XML project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
# XML config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
indent_size = 2
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
insert_final_newline = true
charset = utf-8-bom
###############################
# .NET Coding Conventions #
###############################
[*.{cs,vb}]
# Organize usings
dotnet_sort_system_directives_first = true
# this. preferences
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_event = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
###############################
# Naming Conventions #
###############################
# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# Use PascalCase for constant fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
dotnet_naming_symbols.constant_fields.required_modifiers = const
###############################
# C# Coding Conventions #
###############################
[*.cs]
# var preferences
csharp_style_var_for_built_in_types = true:silent
csharp_style_var_when_type_is_apparent = true:silent
csharp_style_var_elsewhere = true:silent
# Expression-bodied members
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
# Null-checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# Expression-level preferences
csharp_prefer_braces = true:silent
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_prefer_local_over_anonymous_function = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
###############################
# C# Formatting Rules #
###############################
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true
###############################
# VB Coding Conventions #
###############################
[*.vb]
# Modifier preferences
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
Resources:
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
================================================
FILE: Directory.Build.props
================================================
<Project>
<PropertyGroup>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
================================================
FILE: Directory.Packages.props
================================================
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<MicrosoftExtensionsVersion>8.6.0</MicrosoftExtensionsVersion>
<AspireVersion>8.2.2</AspireVersion>
<MicrosoftExtensionsAiVersion>9.4.4-preview.1.25259.16</MicrosoftExtensionsAiVersion>
<MicrosoftExtensionsAiEvaluationVersion>9.4.4-preview.1.25259.16</MicrosoftExtensionsAiEvaluationVersion>
</PropertyGroup>
<ItemGroup>
<!-- Version together with Aspire -->
<PackageVersion Include="Aspire.Azure.Storage.Blobs" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.Azure.Storage" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.Qdrant" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.Redis" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.StackExchange.Redis" Version="$(AspireVersion)" />
<PackageVersion Include="Azure.Identity" Version="1.12.0" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.1.0-beta.1" />
<PackageVersion Include="IdentityModel" Version="7.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.10" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="$(MicrosoftExtensionsAiVersion)" />
<PackageVersion Include="Microsoft.Extensions.AI.Evaluation" Version="$(MicrosoftExtensionsAiEvaluationVersion)" />
<PackageVersion Include="Microsoft.Extensions.AI.Evaluation.Quality" Version="$(MicrosoftExtensionsAiEvaluationVersion)" />
<PackageVersion Include="Microsoft.Extensions.AI.Evaluation.Reporting" Version="$(MicrosoftExtensionsAiEvaluationVersion)" />
<PackageVersion Include="Microsoft.Extensions.AI.Ollama" Version="$(MicrosoftExtensionsAiVersion)" />
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="$(MicrosoftExtensionsAiVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="$(AspireVersion)" />
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="1.0.1" />
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.O200kBase" Version="1.0.1" />
<!-- Version together with ASP.NET -->
<PackageVersion Include="Microsoft.AspNetCore.Components.QuickGrid" Version="8.0.10" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.10.0" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components" Version="4.10.3" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.DataGrid.EntityFrameworkAdapter" Version="4.10.3" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="4.10.3" />
<PackageVersion Include="Microsoft.Playwright" Version="1.48.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.16.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.Qdrant" Version="1.16.0-alpha" />
<PackageVersion Include="Microsoft.SemanticKernel.Core" Version="1.25.0" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.16.0" />
<!-- Open Telemetry -->
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
<PackageVersion Include="PdfPig" Version="0.1.9" />
<PackageVersion Include="SmartComponents.AspNetCore" Version="0.1.0-preview10148" />
<PackageVersion Include="SmartComponents.LocalEmbeddings" Version="0.1.0-preview10148" />
<PackageVersion Include="SmartComponents.LocalEmbeddings.SemanticKernel" Version="0.1.0-preview10148" />
<PackageVersion Include="StatefulReconnection" Version="0.1.0" />
<PackageVersion Include="Markdown2Pdf" Version="2.2.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageVersion Include="System.Text.Json" Version="9.0.2" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="Duende.IdentityServer" Version="7.0.8" />
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageVersion Include="System.Runtime.Caching" Version="8.0.1" />
<PackageVersion Include="System.Memory.Data" Version="8.0.1" />
</ItemGroup>
</Project>
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) .NET Foundation. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
================================================
FILE: README.md
================================================
# eShopSupport
A sample .NET application showcasing common use cases and development practices for build AI solutions in .NET (Generative AI, specifically). This sample demonstrates a customer support application for an e-commerce website using a services-based architecture with .NET Aspire. It includes support for the following AI use cases:
* Text classification, applying labels based on content
* Sentiment analysis based on message content
* Summarization of large sets of text
* Synthetic data generation, creating test content for the sample
* Chat bot interactions with chat history and suggested responses
<img width=400 align=top src=https://github.com/user-attachments/assets/5a41493f-565b-4dd0-ae31-1b5c3c2f6d22>
<img width=400 align=top src=https://github.com/user-attachments/assets/7930a940-bb31-4dc0-b5f6-738d43dfcfe5>
This sample also demonstrates the following development practices:
* Developing a solution locally, using small local models
* Evaluating the quality of AI responses using grounded Q&A data
* Leveraging Python projects as part of a .NET Aspire solution
* Deploying the application, including small local models, to the Cloud (coming soon)
## Architecture

## Getting Started
### Prerequisites
- A device with an Nvidia GPU (see [workaround for running on the CPU](https://github.com/dotnet/eShopSupport/issues/19))
- Clone the eShopSupport repository: https://github.com/dotnet/eshopsupport
- [Install & start Docker Desktop](https://docs.docker.com/engine/install/)
- [Install Python 3.12.5](https://www.python.org/downloads/release/python-3125/)
#### Windows with Visual Studio
- Install [Visual Studio 2022 version 17.10 or newer](https://visualstudio.microsoft.com/vs/)
- Select the following workloads:
- `ASP.NET and web development` workload.
- `Python Development` workload.
- `.NET Aspire SDK` component in `Individual components`.
#### Mac, Linux, & Windows without Visual Studio
- Install the latest [.NET 8 SDK](https://dot.net/download?cid=eshop)
- Install the [.NET Aspire workload](https://learn.microsoft.com/dotnet/aspire/fundamentals/setup-tooling?tabs=dotnet-cli%2Cunix#install-net-aspire) with the following commands:
```powershell
dotnet workload update
dotnet workload install aspire
dotnet restore eShopSupport.sln
```
- (Optionally) Install [Visual Studio Code](https://code.visualstudio.com) with the [C# Dev Kit extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit)
#### Install Python requirements
From the Terminal, at the root of the cloned repo, run:
```powershell
pip install -r src/PythonInference/requirements.txt
```
**Note:** If the above command doesn't work on Windows, use the following command:
```powershell
py -m pip install -r src/PythonInference/requirements.txt
```
### Running the solution
> [!WARNING]
> Remember to ensure that Docker is started.
* (Windows only) Run the application from Visual Studio:
- Open the `eShopSupport.sln` file in Visual Studio
- Ensure that `AppHost` is your startup project
- Hit Ctrl-F5 to launch .NET Aspire
* Or run the application from your terminal:
```powershell
dotnet run --project src/AppHost
```
then look for lines like this in the console output in order to find the URL to open the Aspire dashboard:
```sh
Login to the dashboard at: http://localhost:17191/login?t=uniquelogincodeforyou
```
> You may need to install ASP.NET Core HTTPS development certificates first, and then close all browser tabs. Learn more at https://aka.ms/aspnet/https-trust-dev-cert
# Contributing
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# Sample data
The sample data is defined in [seeddata](https://github.com/dotnet/eShopSupport/tree/main/seeddata). All products/descriptions/brands, manuals, customers, and support tickets names are fictional and were generated using [GPT-35-Turbo](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/chatgpt) using the included [DataGenerator](https://github.com/dotnet/eShopSupport/tree/main/seeddata/DataGenerator) project.
================================================
FILE: SECURITY.md
================================================
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.9 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet) and [Xamarin](https://github.com/xamarin).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->
================================================
FILE: eShopSupport.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7306A281-C46A-4EE3-948D-513D56B1BD34}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Backend", "src\Backend\Backend.csproj", "{96F30B32-9DE5-450F-B54F-CFDFACC91AFF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StaffWebUI", "src\StaffWebUI\StaffWebUI.csproj", "{D77F3443-68A2-4F6A-ABB8-0E7CA32643FA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppHost", "src\AppHost\AppHost.csproj", "{BEE4A236-2112-44BF-8013-00542A07E4FE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceDefaults", "src\ServiceDefaults\ServiceDefaults.csproj", "{D69799F9-BE09-4303-A67D-323A60AA8C0A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataIngestor", "src\DataIngestor\DataIngestor.csproj", "{E0886BA7-F33C-4FB4-80D1-93FCC1C4A513}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "seeddata", "seeddata", "{2B17496A-5870-4676-927B-6B45871C7BBA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dev", "dev", "{B3CDC49A-D71A-4C0D-945F-8DD69FC1B066}"
ProjectSection(SolutionItems) = preProject
seeddata\dev\categories.json = seeddata\dev\categories.json
seeddata\dev\customers.json = seeddata\dev\customers.json
seeddata\dev\evalquestions.json = seeddata\dev\evalquestions.json
seeddata\dev\manual-chunks.json = seeddata\dev\manual-chunks.json
seeddata\dev\manuals.zip = seeddata\dev\manuals.zip
seeddata\dev\products.json = seeddata\dev\products.json
seeddata\dev\tickets.json = seeddata\dev\tickets.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomerWebUI", "src\CustomerWebUI\CustomerWebUI.csproj", "{AAA2257C-D227-404A-8EDF-7BF6C5592D51}"
EndProject
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "PythonInference", "src\PythonInference\PythonInference.pyproj", "{BAA14585-1716-40FB-A04E-F986F1038638}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{218618B1-A99C-4174-A13C-0C2CFD065D78}"
ProjectSection(SolutionItems) = preProject
Directory.Packages.props = Directory.Packages.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataGenerator", "seeddata\DataGenerator\DataGenerator.csproj", "{E2871C52-FBBF-44A4-A3CD-185E5F6AA7EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Evaluator", "src\Evaluator\Evaluator.csproj", "{A634C7D8-FD7D-49F5-A98E-626F0AEE145F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{9E677D76-414B-492C-AF74-1B091F940D00}"
ProjectSection(SolutionItems) = preProject
seeddata\test\categories.json = seeddata\test\categories.json
seeddata\test\customers.json = seeddata\test\customers.json
seeddata\test\evalquestions.json = seeddata\test\evalquestions.json
seeddata\test\manual-chunks.json = seeddata\test\manual-chunks.json
seeddata\test\manuals.zip = seeddata\test\manuals.zip
seeddata\test\products.json = seeddata\test\products.json
seeddata\test\tickets.json = seeddata\test\tickets.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{51031120-B48D-4680-8808-26B64F235CB9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "E2ETest", "test\E2ETest\E2ETest.csproj", "{F30843C3-AFB5-435E-8A7D-9B4C86A75E18}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityServer", "src\IdentityServer\IdentityServer.csproj", "{89404F66-90BC-4D45-9061-050334772CDC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EvaluationTests", "test\EvaluationTests\EvaluationTests.csproj", "{6BE0D6D5-F251-4628-9FB9-B19C565FC5EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{96F30B32-9DE5-450F-B54F-CFDFACC91AFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96F30B32-9DE5-450F-B54F-CFDFACC91AFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96F30B32-9DE5-450F-B54F-CFDFACC91AFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96F30B32-9DE5-450F-B54F-CFDFACC91AFF}.Release|Any CPU.Build.0 = Release|Any CPU
{D77F3443-68A2-4F6A-ABB8-0E7CA32643FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D77F3443-68A2-4F6A-ABB8-0E7CA32643FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D77F3443-68A2-4F6A-ABB8-0E7CA32643FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D77F3443-68A2-4F6A-ABB8-0E7CA32643FA}.Release|Any CPU.Build.0 = Release|Any CPU
{BEE4A236-2112-44BF-8013-00542A07E4FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEE4A236-2112-44BF-8013-00542A07E4FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEE4A236-2112-44BF-8013-00542A07E4FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEE4A236-2112-44BF-8013-00542A07E4FE}.Release|Any CPU.Build.0 = Release|Any CPU
{D69799F9-BE09-4303-A67D-323A60AA8C0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D69799F9-BE09-4303-A67D-323A60AA8C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D69799F9-BE09-4303-A67D-323A60AA8C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D69799F9-BE09-4303-A67D-323A60AA8C0A}.Release|Any CPU.Build.0 = Release|Any CPU
{E0886BA7-F33C-4FB4-80D1-93FCC1C4A513}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0886BA7-F33C-4FB4-80D1-93FCC1C4A513}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0886BA7-F33C-4FB4-80D1-93FCC1C4A513}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0886BA7-F33C-4FB4-80D1-93FCC1C4A513}.Release|Any CPU.Build.0 = Release|Any CPU
{AAA2257C-D227-404A-8EDF-7BF6C5592D51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAA2257C-D227-404A-8EDF-7BF6C5592D51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AAA2257C-D227-404A-8EDF-7BF6C5592D51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAA2257C-D227-404A-8EDF-7BF6C5592D51}.Release|Any CPU.Build.0 = Release|Any CPU
{BAA14585-1716-40FB-A04E-F986F1038638}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAA14585-1716-40FB-A04E-F986F1038638}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2871C52-FBBF-44A4-A3CD-185E5F6AA7EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2871C52-FBBF-44A4-A3CD-185E5F6AA7EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2871C52-FBBF-44A4-A3CD-185E5F6AA7EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2871C52-FBBF-44A4-A3CD-185E5F6AA7EB}.Release|Any CPU.Build.0 = Release|Any CPU
{A634C7D8-FD7D-49F5-A98E-626F0AEE145F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A634C7D8-FD7D-49F5-A98E-626F0AEE145F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A634C7D8-FD7D-49F5-A98E-626F0AEE145F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A634C7D8-FD7D-49F5-A98E-626F0AEE145F}.Release|Any CPU.Build.0 = Release|Any CPU
{F30843C3-AFB5-435E-8A7D-9B4C86A75E18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F30843C3-AFB5-435E-8A7D-9B4C86A75E18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F30843C3-AFB5-435E-8A7D-9B4C86A75E18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F30843C3-AFB5-435E-8A7D-9B4C86A75E18}.Release|Any CPU.Build.0 = Release|Any CPU
{89404F66-90BC-4D45-9061-050334772CDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89404F66-90BC-4D45-9061-050334772CDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89404F66-90BC-4D45-9061-050334772CDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89404F66-90BC-4D45-9061-050334772CDC}.Release|Any CPU.Build.0 = Release|Any CPU
{6BE0D6D5-F251-4628-9FB9-B19C565FC5EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BE0D6D5-F251-4628-9FB9-B19C565FC5EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BE0D6D5-F251-4628-9FB9-B19C565FC5EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BE0D6D5-F251-4628-9FB9-B19C565FC5EB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{96F30B32-9DE5-450F-B54F-CFDFACC91AFF} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{D77F3443-68A2-4F6A-ABB8-0E7CA32643FA} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{BEE4A236-2112-44BF-8013-00542A07E4FE} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{D69799F9-BE09-4303-A67D-323A60AA8C0A} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{E0886BA7-F33C-4FB4-80D1-93FCC1C4A513} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{B3CDC49A-D71A-4C0D-945F-8DD69FC1B066} = {2B17496A-5870-4676-927B-6B45871C7BBA}
{AAA2257C-D227-404A-8EDF-7BF6C5592D51} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{BAA14585-1716-40FB-A04E-F986F1038638} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{E2871C52-FBBF-44A4-A3CD-185E5F6AA7EB} = {2B17496A-5870-4676-927B-6B45871C7BBA}
{A634C7D8-FD7D-49F5-A98E-626F0AEE145F} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{9E677D76-414B-492C-AF74-1B091F940D00} = {2B17496A-5870-4676-927B-6B45871C7BBA}
{F30843C3-AFB5-435E-8A7D-9B4C86A75E18} = {51031120-B48D-4680-8808-26B64F235CB9}
{89404F66-90BC-4D45-9061-050334772CDC} = {7306A281-C46A-4EE3-948D-513D56B1BD34}
{6BE0D6D5-F251-4628-9FB9-B19C565FC5EB} = {51031120-B48D-4680-8808-26B64F235CB9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B2E71FD9-E3D5-450C-A9E0-318DAA986F31}
EndGlobalSection
EndGlobal
================================================
FILE: nuget.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceMapping>
<!-- key value for <packageSource> should match key values from <packageSources> element -->
<clear />
<packageSource key="nuget">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
</configuration>
================================================
FILE: seeddata/DataGenerator/.gitignore
================================================
appsettings.Local.json
output/
output-demo/
================================================
FILE: seeddata/DataGenerator/ChatCompletionServiceExtensions.cs
================================================
using Microsoft.Extensions.DependencyInjection;
using System.Data.Common;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.AI;
using Azure.AI.OpenAI;
using System.ClientModel;
using OpenAI;
namespace eShopSupport.DataGenerator;
public static class ChatCompletionServiceExtensions
{
public static void AddOpenAIChatCompletion(this HostApplicationBuilder builder, string connectionStringName)
{
var connectionStringBuilder = new DbConnectionStringBuilder();
var connectionString = builder.Configuration.GetConnectionString(connectionStringName);
if (string.IsNullOrEmpty(connectionString))
{
throw new InvalidOperationException($"Missing connection string {connectionStringName}");
}
connectionStringBuilder.ConnectionString = connectionString;
var deployment = connectionStringBuilder.TryGetValue("Deployment", out var deploymentValue) ? (string)deploymentValue : throw new InvalidOperationException($"Connection string {connectionStringName} is missing 'Deployment'");
var endpoint = connectionStringBuilder.TryGetValue("Endpoint", out var endpointValue) ? (string)endpointValue : throw new InvalidOperationException($"Connection string {connectionStringName} is missing 'Endpoint'");
var key = connectionStringBuilder.TryGetValue("Key", out var keyValue) ? (string)keyValue : throw new InvalidOperationException($"Connection string {connectionStringName} is missing 'Key'");
builder.Services.AddSingleton<OpenAIClient>(_ => new AzureOpenAIClient(
new Uri(endpoint), new ApiKeyCredential(key)));
builder.Services.AddChatClient(builder => builder.GetRequiredService<OpenAIClient>().GetChatClient(deployment).AsIChatClient())
.UseFunctionInvocation();
}
}
================================================
FILE: seeddata/DataGenerator/DataGenerator.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>eShopSupport.DataGenerator</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdown2Pdf" />
<PackageReference Include="Microsoft.Extensions.AI" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="SmartComponents.LocalEmbeddings" />
<PackageReference Include="Azure.AI.OpenAI" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.Local.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
================================================
FILE: seeddata/DataGenerator/Generators/CategoryGenerator.cs
================================================
using eShopSupport.DataGenerator.Model;
using System.Text.RegularExpressions;
namespace eShopSupport.DataGenerator.Generators;
public class CategoryGenerator(IServiceProvider services) : GeneratorBase<Category>(services)
{
protected override string DirectoryName => "categories";
protected override object GetId(Category item) => item.CategoryId;
protected override async IAsyncEnumerable<Category> GenerateCoreAsync()
{
// If there are any categories already, assume this covers everything we need
if (Directory.GetFiles(OutputDirPath).Any())
{
yield break;
}
var numCategories = 50;
var batchSize = 25;
var categoryNames = new HashSet<string>();
while (categoryNames.Count < numCategories)
{
Console.WriteLine($"Generating {batchSize} categories...");
var prompt = @$"Generate {batchSize} product category names for an online retailer
of high-tech outdoor adventure goods and related clothing/electronics/etc.
Each category name is a single descriptive term, so it does not use the word 'and'.
Category names should be interesting and novel, e.g., ""Mountain Unicycles"", ""AI Boots"",
or ""High-volume Water Filtration Plants"", not simply ""Tents"".
This retailer sells relatively technical products.
Each category has a list of up to 8 brand names that make products in that category. All brand names are
purely fictional. Brand names are usually multiple words with spaces and/or special characters, e.g.
""Orange Gear"", ""Aqua Tech US"", ""Livewell"", ""E & K"", ""JAXⓇ"".
Many brand names are used in multiple categories. Some categories have only 2 brands.
The response should be a JSON object of the form {{ ""categories"": [{{""name"":""Tents"", ""brands"":[""Rosewood"", ""Summit Kings""]}}, ...] }}.";
var response = await GetAndParseJsonChatCompletion<Response>(prompt, maxTokens: 70 * batchSize);
foreach (var c in response.Categories)
{
if (categoryNames.Add(c.Name))
{
c.CategoryId = categoryNames.Count;
c.Brands = c.Brands.Select(ImproveBrandName).ToArray();
yield return c;
}
}
}
}
private static string ImproveBrandName(string name)
{
// Almost invariably, the name is a PascalCase word like AquaTech, even though we told it to use spaces.
// For variety, convert to "Aqua Tech" or "Aquatech" sometimes.
return Regex.Replace(name, @"([a-z])([A-Z])", m => Random.Shared.Next(3) switch
{
0 => $"{m.Groups[1].Value} {m.Groups[2].Value}",
1 => $"{m.Groups[1].Value}{m.Groups[2].Value.ToLower()}",
_ => m.Value
});
}
private class Response
{
public required List<Category> Categories { get; set; }
}
}
================================================
FILE: seeddata/DataGenerator/Generators/EvalQuestionGenerator.cs
================================================
using System.Text;
using System.Threading.Channels;
using eShopSupport.DataGenerator.Model;
namespace eShopSupport.DataGenerator.Generators;
public class EvalQuestionGenerator(IReadOnlyList<Product> products, IReadOnlyList<Category> categories, IReadOnlyList<Manual> manuals, IServiceProvider services)
: GeneratorBase<EvalQuestion>(services)
{
protected override string DirectoryName => "evalquestions";
protected override object GetId(EvalQuestion item)
=> item.QuestionId;
protected override async IAsyncEnumerable<EvalQuestion> GenerateCoreAsync()
{
// If there are any questions already, assume this covers everything we need
if (Directory.GetFiles(OutputDirPath).Any())
{
yield break;
}
var numQuestions = 500;
var questionId = 0;
var outputChannel = Channel.CreateUnbounded<EvalQuestion>();
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 10 };
CompleteOutputAfterTask(outputChannel.Writer, Parallel.ForAsync(0, numQuestions, parallelOptions, async (_, _) =>
{
var item = await GenerateSingle();
if (!string.IsNullOrWhiteSpace(item.Question) && !string.IsNullOrEmpty(item.Answer))
{
item.QuestionId = Interlocked.Increment(ref questionId);
await outputChannel.Writer.WriteAsync(item);
}
}));
await foreach (var item in outputChannel.Reader.ReadAllAsync())
{
yield return item;
}
}
private static void CompleteOutputAfterTask<T>(ChannelWriter<T> writer, Task task)
{
Task.Run(async () =>
{
try
{
await task;
writer.Complete();
}
catch (Exception ex)
{
writer.Complete(ex);
}
});
}
private async Task<EvalQuestion> GenerateSingle()
{
var product = products[Random.Shared.Next(products.Count)];
var category = categories.Single(c => c.CategoryId == product.CategoryId);
var manual = manuals.Single(m => m.ProductId == product.ProductId);
var manualExtract = ManualGenerator.ExtractFromManual(manual);
var isQuestionWrittenByAgent = Random.Shared.NextDouble() < 0.75;
var questionPrompt = isQuestionWrittenByAgent
? """
Questions are short, typically 3-6 words, and are not always full sentences. They may look
like search queries or things typed in a hurry by a support agent. They are not polite or
verbose, since they are addressed to a machine.
Example questions might be "weight", "what are the dimensions", "how to shut down",
"can use on pets?", "what accessories does it come with?"
"""
: """
The question is actually an entire email written by a customer. It usually starts with a
greeting, some description of their situation, and then their question. The whole thing
may be up to 100 words long. It may contain spelling and grammar errors, and may be angry
or rude.
""";
var question = await GetAndParseJsonChatCompletion<EvalQuestion>($$"""
There is an AI system used by customer support agents working for an online retailer.
The AI system is used to help agents answer customer questions.
Your task is to write question/answer pairs that will be used to evaluate the
performance of that AI system. All the questions you write will be about actual products
sold by that retailer, based on information from the product catalog and manuals. The
questions should plausibly represent what customers and support agents will ask.
In this case, you are to write a question/answer pair based on the following context:
<product_name>{{product.Model}}</product_name>
<brand>{{product.Brand}}</brand>
<category>{{category.Name}}</category>
<extract_from_manual>{{manualExtract}}</extract_from_manual>
Questions are one of the following types:
- A pre-purchase question to help a customer who wants to know about the product
features, suitability for particular use cases, or other objective facts
- A post-purchase question to help a customer resolve an issue or understand how to
use the product
You must select an OBJECTIVE FACT from the product manual and write a question to which
that fact is the answer. Only select facts that are distinctive about this specific product,
not generic information about any product or warranty terms.
Always follow these style guidelines:
- {{questionPrompt}}
- Answers are short, typically a single brief sentence of 1-10 words. Never use more than
20 words for an answer.
- The "verbatim_quote_from_manual" is 3-6 words taken EXACTLY from the manual which are
the factual basis for the question and asnwer.
- If the provided context does not contain a suitable fact, set all the response properties
to null or empty strings.
Respond as JSON in the following form: {
"question": "string",
"answer": "string",
"verbatimQuoteFromManual": "string"
}
""");
question.ProductId = product.ProductId;
return question;
}
}
================================================
FILE: seeddata/DataGenerator/Generators/GeneratorBase.cs
================================================
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;
using System.Text;
using System.Text.Json;
using System.Threading.Channels;
namespace eShopSupport.DataGenerator.Generators;
public abstract class GeneratorBase<T>
{
protected abstract string DirectoryName { get; }
protected abstract object GetId(T item);
public static string OutputDirRoot => Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "output");
protected string OutputDirPath => Path.Combine(OutputDirRoot, DirectoryName);
protected JsonSerializerOptions SerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
WriteIndented = true
};
public GeneratorBase(IServiceProvider services)
{
ChatClient = services.GetRequiredService<IChatClient>();
}
public async Task<IReadOnlyList<T>> GenerateAsync()
{
if (!Directory.Exists(OutputDirPath))
{
Directory.CreateDirectory(OutputDirPath);
}
var sw = Stopwatch.StartNew();
await foreach (var item in GenerateCoreAsync())
{
sw.Stop();
Console.WriteLine($"Writing {item!.GetType().Name} {GetId(item)} [generated in {sw.Elapsed.TotalSeconds}s]");
var path = GetItemOutputPath(GetId(item).ToString()!);
await WriteAsync(path, item);
sw.Restart();
}
var existingFiles = Directory.GetFiles(OutputDirPath);
return existingFiles.Select(Read).ToList();
}
protected string GetItemOutputPath(string id)
=> Path.Combine(OutputDirPath, $"{id}{FilenameExtension}");
protected abstract IAsyncEnumerable<T> GenerateCoreAsync();
protected IChatClient ChatClient { get; }
protected async Task<string> GetCompletion(string prompt)
{
// Instructing it to end the content with END_OF_CONTENT is beneficial because it often tries to add a suffix like
// "I have done the task, hope this helps!". We can avoid that by making it stop before that.
var response = await ChatClient.GetResponseAsync(
prompt,
new ChatOptions { Temperature = 0.9f, StopSequences = ["END_OF_CONTENT"] });
return response.Text ?? string.Empty;
}
protected async Task<TResponse> GetAndParseJsonChatCompletion<TResponse>(string prompt, int? maxTokens = null, IList<AITool>? tools = null)
{
var options = new ChatOptions
{
// MaxOutputTokens = maxTokens, // TODO: Re-enable when https://github.com/dotnet/temp-ai-abstractions/issues/294 is fixed
Temperature = 0.9f,
ResponseFormat = ChatResponseFormat.Json,
Tools = tools,
};
var response = await RunWithRetries(() => ChatClient.GetResponseAsync(prompt, options));
var responseString = response.Text ?? string.Empty;
// Due to what seems like a server-side bug, when asking for a json_object response and with tools enabled,
// it often replies with two or more JSON objects concatenated together (duplicates or slight variations).
// As a workaround, just read the first complete JSON object from the response.
var parsed = ReadAndDeserializeSingleValue<TResponse>(responseString, SerializerOptions)!;
return parsed;
}
private static async Task<TResult> RunWithRetries<TResult>(Func<Task<TResult>> operation)
{
var delay = TimeSpan.FromSeconds(5);
var maxAttempts = 5;
for (var attemptIndex = 1; ; attemptIndex++)
{
try
{
return await operation();
}
catch (Exception e) when (attemptIndex < maxAttempts)
{
Console.WriteLine($"Exception on attempt {attemptIndex}: {e.Message}. Will retry after {delay}");
await Task.Delay(delay);
delay += TimeSpan.FromSeconds(15);
}
}
}
private static TResponse? ReadAndDeserializeSingleValue<TResponse>(string json, JsonSerializerOptions options)
{
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json).AsSpan());
return JsonSerializer.Deserialize<TResponse>(ref reader, options);
}
protected virtual string FilenameExtension => ".json";
protected virtual Task WriteAsync(string path, T item)
{
var itemJson = JsonSerializer.Serialize(item, SerializerOptions);
return File.WriteAllTextAsync(path, itemJson);
}
protected virtual T Read(string path)
{
try
{
using var existingJson = File.OpenRead(path);
return JsonSerializer.Deserialize<T>(existingJson, SerializerOptions)!;
}
catch (Exception ex)
{
Console.WriteLine($"Error reading {path}: {ex.Message}");
throw;
}
}
protected IAsyncEnumerable<V> MapParallel<U, V>(IEnumerable<U> source, Func<U, Task<V>> map)
{
var outputs = Channel.CreateUnbounded<V>();
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 5 };
var mapTask = Parallel.ForEachAsync(source, parallelOptions, async (sourceItem, ct) =>
{
try
{
var mappedItem = await map(sourceItem);
await outputs.Writer.WriteAsync(mappedItem);
}
catch (Exception ex)
{
outputs.Writer.TryComplete(ex);
}
});
mapTask.ContinueWith(_ => outputs.Writer.TryComplete());
return outputs.Reader.ReadAllAsync();
}
}
================================================
FILE: seeddata/DataGenerator/Generators/LocalTextEmbeddingGenerator.cs
================================================
using Microsoft.Extensions.AI;
using SmartComponents.LocalEmbeddings;
namespace eShopSupport.DataGenerator.Generators;
public class LocalTextEmbeddingGenerator : IEmbeddingGenerator<string, Embedding<float>>
{
private readonly LocalEmbedder _embedder = new();
public EmbeddingGeneratorMetadata Metadata => new("local");
public void Dispose() => _embedder.Dispose();
public Task<GeneratedEmbeddings<Embedding<float>>> GenerateAsync(IEnumerable<string> values, EmbeddingGenerationOptions? options = null, CancellationToken cancellationToken = default)
{
var results = values.Select(v => new Embedding<float>(_embedder.Embed(v).Values)).ToList();
return Task.FromResult(new GeneratedEmbeddings<Embedding<float>>(results));
}
public object? GetService(Type serviceType, object? key = null)
=> serviceType == typeof(IEmbeddingGenerator<string, Embedding<float>>) ? this : null;
}
================================================
FILE: seeddata/DataGenerator/Generators/ManualGenerator.cs
================================================
using eShopSupport.DataGenerator.Model;
using System.Text;
namespace eShopSupport.DataGenerator.Generators;
public class ManualGenerator(IReadOnlyList<Category> categories, IReadOnlyList<Product> products, IReadOnlyList<ManualToc> manualTocs, IServiceProvider services)
: GeneratorBase<Manual>(services)
{
protected override string DirectoryName => $"manuals{Path.DirectorySeparatorChar}full";
protected override object GetId(Manual item) => item.ProductId;
protected override IAsyncEnumerable<Manual> GenerateCoreAsync()
{
// Skip the ones we already have
var manualsToGenerate = manualTocs.Where(toc => !File.Exists(GetItemOutputPath(toc.ProductId.ToString())));
return MapParallel(manualsToGenerate, GenerateManualAsync);
}
private async Task<Manual> GenerateManualAsync(ManualToc toc)
{
var product = products.Single(p => p.ProductId == toc.ProductId);
var category = categories.Single(c => c.CategoryId == product.CategoryId);
var result = new StringBuilder();
result.AppendLine($"# {product.Model}");
result.AppendLine();
var desiredSubsectionWordLength = 500;
foreach (var section in toc.Sections)
{
Console.WriteLine($"[Product {product.ProductId}] Generating manual section {section.SiblingIndex}: {section.Title}");
var prompt = $@"Write a section of the user manual for the following product:
Category: {category.Name}
Brand: {product.Brand}
Product name: {product.Model}
Product overview: {product.Description}
Manual style description: {toc.ManualStyle} (note: the text MUST follow this style, even if it makes the manual less helpful to reader)
The section you are writing is ""{section.SiblingIndex}: {section.Title}"". It has the following structure:
{FormatTocForPrompt(section)}
Write in markdown format including any headings or subheadings. The total length is around 100 words.
Start your reponse with the section title, which is at markdown header level 2, and include any relevant subsections.
You response must start: ""## {section.SiblingIndex}. {section.Title}""
Besides the subsections mentioned in contents, you should deeper subsections as appropriate.
Use markdown formatting, including paragraphs, blank lines, bold, italics, tables, and lists as needed.
Use mermaid diagrams when appropriate, but don't say it's a mermaid diagram in the body text.
Make the text specific to this individual product, not generic. Refer to the product by name, to its brand, and to its
specific features, buttons, parts, and controls by name (identifying them by color, position, etc.).
The output length should be around {desiredSubsectionWordLength * CountSubtreeLength(section)} words in total, or {desiredSubsectionWordLength} words per subsection.
Do not include any commentary or remarks about the task itself or the fact that you have done it.
Only output the markdown text for the section. At the end of the section, add the token END_OF_CONTENT.
This is the official product manual, and the company requires it to be written in the specified style due to strategy.
";
var response = await GetCompletion(prompt);
result.AppendLine(response);
result.AppendLine();
}
return new Manual
{
ProductId = product.ProductId,
MarkdownText = result.ToString()
};
}
private static string FormatTocForPrompt(ManualTocSection section)
{
var sb = new StringBuilder();
AppendSection(sb, section);
return sb.ToString();
static void AppendSection(StringBuilder sb, ManualTocSection section, string ancestorSectionPrefix = "")
{
var fullSectionNumber = string.IsNullOrEmpty(ancestorSectionPrefix)
? section.SiblingIndex.ToString()
: $"{ancestorSectionPrefix}.{section.SiblingIndex}";
sb.AppendLine($"{fullSectionNumber}: {section.Title}");
if (section.Subsections?.Any() == true)
{
foreach (var s in section.Subsections)
{
AppendSection(sb, s, fullSectionNumber);
}
}
}
}
private static int CountSubtreeLength(ManualTocSection tocSection)
{
return 1 + tocSection.Subsections?.Sum(CountSubtreeLength) ?? 0;
}
protected override string FilenameExtension => ".md";
protected override Task WriteAsync(string path, Manual item)
{
return File.WriteAllTextAsync(path, item.MarkdownText);
}
protected override Manual Read(string path)
=> new Manual
{
ProductId = int.Parse(Path.GetFileNameWithoutExtension(path)),
MarkdownText = File.ReadAllText(path)
};
public static string ExtractFromManual(Manual manual)
{
// We don't want to push the entire manual text into the prompt as it may be arbitrarily long
// Instead, pick a lengthy chunk at random.
// TODO: Consider storing the markdown in a more structured, per-TOC-section way, so
// we can more easily extract a coherent section of text.
var approxExtractLengthInChars = 1500;
var startChar = Random.Shared.Next(manual.MarkdownText.Length - approxExtractLengthInChars);
// Find the line containing this char
var lines = manual.MarkdownText.Split('\n', StringSplitOptions.RemoveEmptyEntries);
var lineIndexContainingStartChar = 0;
for (var numCharsSeen = 0; numCharsSeen < startChar; lineIndexContainingStartChar++)
{
numCharsSeen += lines[lineIndexContainingStartChar].Length;
}
// Add lines until we have enough text
var extract = new StringBuilder();
for (var i = lineIndexContainingStartChar; i < lines.Length; i++)
{
extract.AppendLine(lines[i]);
if (extract.Length >= approxExtractLengthInChars)
{
break;
}
}
return extract.ToString();
}
}
================================================
FILE: seeddata/DataGenerator/Generators/ManualPdfConverter.cs
================================================
using eShopSupport.DataGenerator.Model;
using Markdown2Pdf;
using Markdown2Pdf.Options;
using System.Text.RegularExpressions;
namespace eShopSupport.DataGenerator.Generators;
public class ManualPdfConverter(IReadOnlyList<Product> products, IReadOnlyList<Manual> manuals)
{
Markdown2PdfConverter CreateConverter(Product product) => new(new()
{
DocumentTitle = product.Model,
MarginOptions = new()
{
Top = "80px",
Bottom = "80px",
Left = "75px",
Right = "75px",
},
TableOfContents = new()
{
ListStyle = ListStyle.None,
MinDepthLevel = 2,
MaxDepthLevel = 4,
PageNumberOptions = new()
{
TabLeader = Leader.Dots,
},
},
CustomHeadContent = @"<style>
h1 { padding-top: 300px; font-size: 4rem !important; page-break-after: always; border-bottom: none !important; }
h2 { page-break-before: always; }
</style>",
HeaderHtml = "",
FooterHtml = $"<div style=\"width: 100%; padding: 30px 75px; display: flex; justify-content: space-between;\"><span style=\"color: gray\">(c) {product.Brand}</span><span class=\"pageNumber\"></span></div>",
});
public async Task<IReadOnlyList<ManualPdf>> ConvertAsync()
{
var results = new List<ManualPdf>();
foreach (var manual in manuals)
{
var outputDir = Path.Combine(GeneratorBase<object>.OutputDirRoot, "manuals", "pdf");
var outputPath = Path.Combine(outputDir, $"{manual.ProductId}.pdf");
results.Add(new ManualPdf { ProductId = manual.ProductId, LocalPath = outputPath });
if (File.Exists(outputPath))
{
continue;
}
Directory.CreateDirectory(outputDir);
// Insert TOC marker after first level-1 heading
var firstMatch = true;
var markdown = Regex.Replace(manual.MarkdownText, "^(# .*\r?\n)", match =>
{
if (firstMatch)
{
firstMatch = false;
return match.Value + "\n[TOC]\n\n";
}
else
{
return match.Value;
}
}, RegexOptions.Multiline);
using var inputFile = new TempFile(markdown);
var product = products.Single(p => p.ProductId == manual.ProductId);
var converter = CreateConverter(product);
await converter.Convert(inputFile.FilePath, outputPath);
Console.WriteLine($"Wrote {Path.GetFileName(outputPath)}");
}
return results;
}
private class TempFile : IDisposable
{
public string FilePath { get; }
public TempFile(string contents)
{
FilePath = Path.GetTempFileName();
File.WriteAllText(FilePath, contents);
}
public void Dispose()
=> File.Delete(FilePath);
}
}
================================================
FILE: seeddata/DataGenerator/Generators/ManualTocGenerator.cs
================================================
using eShopSupport.DataGenerator.Model;
namespace eShopSupport.DataGenerator.Generators;
public class ManualTocGenerator(IReadOnlyList<Category> categories, IReadOnlyList<Product> products, IServiceProvider services) : GeneratorBase<ManualToc>(services)
{
protected override string DirectoryName => $"manuals{Path.DirectorySeparatorChar}toc";
protected override object GetId(ManualToc item) => item.ProductId;
protected override IAsyncEnumerable<ManualToc> GenerateCoreAsync()
{
return MapParallel(
products.Where(p => !File.Exists(GetItemOutputPath(p.ProductId.ToString()))),
GenerateTocForProductAsync);
}
private async Task<ManualToc> GenerateTocForProductAsync(Product product)
{
// An issue with current LLMs is that, unless strongly prompted otherwise, they tend to write
// in a very insipid, bland style that is frustrating to read. A mitigation is to offer strong
// and even surprising style guidance to vary the results. Some of the following styles may sound
// silly or unprofessional, but this level of hinting is necessary to get the desired variety.
var styles = new[] {
"normal",
"friendly",
"trying to be cool and hip, with lots of emojis",
"extremely formal and embarassingly over-polite",
"extremely technical, with many references to industrial specifications. Require the user to perform complex diagnostics using specialized industrial and scientific equipment before and after use. Refer to standards bodies, formal industry specification codes, and academic research papers",
"extremely badly translated from another language - most sentences are in broken English, grammatically incorrect, and misspelled",
"confusing and often off-topic, with spelling mistakes",
"incredibly negative and risk-averse, implying it would be unreasonable to use the product for any use case at all, and that it must not be used even for its most obvious and primary use case. Do not admit any design or manufacturing faults. Do not apologise that the product is unsuitable. No matter what the user may be trying to do, emphasize that the product must not be used in that specific way. Give examples of harms that came to prior users.",
};
var chosenStyle = styles[Random.Shared.Next(styles.Length)];
var category = categories.Single(c => c.CategoryId == product.CategoryId);
var prompt = @$"Write a suggested table of contents for the user manual for the following product:
Category: {category.Name}
Brand: {product.Brand}
Product name: {product.Model}
Overview: {product.Description}
The manual MUST be written in the following style: {chosenStyle}
The table of contents MUST follow that style, even if it makes the manual useless to users.
The response should be a JSON object of the form
{{
""sections"": [
{{
""title"": ""..."",
""subsections"": [
{{
""title"": ""..."",
""subsections"": [...]
}},
...
]
}},
...
]
}}
Subsections can be nested up to 3 levels deep. Most sections have no subsections. Only use subsections for the most important, longest sections.";
var toc = await GetAndParseJsonChatCompletion<ManualToc>(prompt, maxTokens: 4000);
toc.ManualStyle = chosenStyle;
toc.ProductId = product.ProductId;
PopulateSiblingIndexes(toc.Sections);
return toc;
}
void PopulateSiblingIndexes(List<ManualTocSection> sections)
{
for (var index = 0; index < sections.Count; index++)
{
var section = sections[index];
section.SiblingIndex = index + 1;
if (section.Subsections is not null)
{
PopulateSiblingIndexes(section.Subsections);
}
}
}
}
================================================
FILE: seeddata/DataGenerator/Generators/ProductGenerator.cs
================================================
using eShopSupport.DataGenerator.Model;
namespace eShopSupport.DataGenerator.Generators;
public class ProductGenerator(IReadOnlyList<Category> categories, IServiceProvider services) : GeneratorBase<Product>(services)
{
protected override string DirectoryName => "products";
protected override object GetId(Product item) => item.ProductId;
protected override async IAsyncEnumerable<Product> GenerateCoreAsync()
{
// If there are any products already, assume this covers everything we need
if (Directory.GetFiles(OutputDirPath).Any())
{
yield break;
}
var numProducts = 200;
var batchSize = 5;
var productId = 0;
var mappedBatches = MapParallel(Enumerable.Range(0, numProducts / batchSize), async batchIndex =>
{
var chosenCategories = Enumerable.Range(0, batchSize)
.Select(_ => categories[(int)Math.Floor(categories.Count * Random.Shared.NextDouble())])
.ToList();
var prompt = @$"Write list of {batchSize} products for an online retailer
of outdoor adventure goods and related electronics, clothing, and homeware. There is a focus on high-tech products. They match the following category/brand pairs:
{string.Join(Environment.NewLine, chosenCategories.Select((c, index) => $"- product {(index + 1)}: category {c.Name}, brand: {c.Brands[Random.Shared.Next(c.Brands.Length)]}"))}
Model names are up to 50 characters long, but usually shorter. Sometimes they include numbers, specs, or product codes.
Example model names: ""iGPS 220c 64GB"", ""Nomad Camping Stove"", ""UX Polarized Sunglasses (Womens)"", ""40L Backpack, Green""
Do not repeat the brand name in the model name.
The description is up to 200 characters long and is the marketing text that will appear on the product page.
Include the key features and selling points.
The result should be JSON form {{ ""products"": [{{ ""id"": 1, ""brand"": ""string"", ""model"": ""string"", ""description"": ""string"", ""price"": 123.45 }}] }}.";
var response = await GetAndParseJsonChatCompletion<Response>(prompt, maxTokens: 200 * batchSize);
var batchEntryIndex = 0;
foreach (var p in response.Products!)
{
var category = chosenCategories[batchEntryIndex++];
p.CategoryId = category.CategoryId;
}
return response.Products;
});
await foreach (var batch in mappedBatches)
{
foreach (var p in batch)
{
p.ProductId = ++productId;
yield return p;
}
}
}
class Response
{
public List<Product>? Products { get; set; }
}
}
================================================
FILE: seeddata/DataGenerator/Generators/TicketGenerator.cs
================================================
using eShopSupport.DataGenerator.Model;
namespace eShopSupport.DataGenerator.Generators;
public class TicketGenerator(IReadOnlyList<Product> products, IReadOnlyList<Category> categories, IReadOnlyList<Manual> manuals, IServiceProvider services) : GeneratorBase<Ticket>(services)
{
protected override string DirectoryName => "tickets/enquiries";
protected override object GetId(Ticket item) => item.TicketId;
protected override async IAsyncEnumerable<Ticket> GenerateCoreAsync()
{
// If there are any tickets already, assume this covers everything we need
if (Directory.GetFiles(OutputDirPath).Any())
{
yield break;
}
var numTickets = 500;
var batchSize = 10;
var ticketId = 0;
string[] situations = [
"asking about a particular usage scenario before purchase",
"asking a specific technical question about the product's capabilities",
"needs information on the product's suitability for its most obvious use case",
"unable to make the product work in one particular way",
"thinks the product doesn't work at all",
"can't understand how to do something",
"has broken the product",
"needs reassurance that the product is behaving as expected",
"wants to use the product for a wildly unexpected purpose, but without self-awareness and assumes it's reasonable",
"incredibly fixated on one minor, obscure detail (before or after purchase), but without self-awareness that they are fixated on an obscure matter. Do not use the word 'fixated'.",
"a business-to-business enquiry from another retailer who stocks the product and has their own customer enquiries to solve",
];
string[] styles = [
"polite",
"extremely jovial, as if trying to be best friends",
"formal",
"embarassed and thinks they are the cause of their own problem",
"not really interested in communicating clearly, only using a few words and assuming support can figure it out",
"demanding and entitled",
"frustrated and angry",
"grumpy, and trying to claim there are logical flaws in whatever the support agent has said",
"extremely brief and abbreviated, by a teenager typing on a phone while distracted by another task",
"extremely technical, as if trying to prove the superiority of their own knowledge",
"relies on extremely, obviously false assumptions, but is earnest and naive",
"providing almost no information, so it's impossible to know what they want or why they are submitting the support message",
];
while (ticketId < numTickets)
{
var numInBatch = Math.Min(batchSize, numTickets - ticketId);
var ticketsInBatch = await Task.WhenAll(Enumerable.Range(0, numInBatch).Select(async _ =>
{
var product = products[Random.Shared.Next(products.Count)];
var category = categories.Single(c => c.CategoryId == product.CategoryId);
var situation = situations[Random.Shared.Next(situations.Length)];
var style = styles[Random.Shared.Next(styles.Length)];
var manual = manuals.Single(m => m.ProductId == product.ProductId);
var manualExtract = ManualGenerator.ExtractFromManual(manual);
var prompt = @$"You are creating test data for a customer support ticketing system.
Write a message by a customer who has purchased, or is considering purchasing, the following:
Product: {product.Model}
Brand: {product.Brand}
Category: {category.Name}
Description: {product.Description}
Random extract from manual: <extract>{manualExtract}</extract>
The situation is: {situation}
If applicable, they can ask for a refund/replacement/repair. However in most cases they
are asking for information or help with a problem.
The customer writes in the following style: {style}
Create a name for the author, writing the message as if you are that person. The customer name
should be fictional and random, and not based on the support enquiry itself. Do not use cliched
or stereotypical names.
Where possible, the message should refer to something specific about this product such as a feature
mentioned in its description or a fact mentioned in the manual (but the customer does not refer
to having read the manual).
The message length may be anything from very brief (around 10 words) to very long (around 200 words).
Use blank lines for paragraphs if needed.
The result should be JSON form {{ ""customerFullName"": ""string"", ""message"": ""string"" }}.";
var ticket = await GetAndParseJsonChatCompletion<Ticket>(prompt);
ticket.ProductId = product.ProductId;
ticket.CustomerSituation = situation;
ticket.CustomerStyle = style;
return ticket;
}));
foreach (var t in ticketsInBatch)
{
t.TicketId = ++ticketId;
yield return t;
}
}
}
}
================================================
FILE: seeddata/DataGenerator/Generators/TicketSummaryGenerator.cs
================================================
using eShopSupport.DataGenerator.Model;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace eShopSupport.DataGenerator.Generators;
public class TicketSummaryGenerator(IReadOnlyList<Product> products, IReadOnlyList<TicketThread> threads, IServiceProvider services) : GeneratorBase<TicketThread>(services)
{
protected override object GetId(TicketThread item) => item.TicketId;
protected override string DirectoryName => "tickets/threads";
protected override IAsyncEnumerable<TicketThread> GenerateCoreAsync()
{
var threadsNeedingSummaries = threads.Where(
thread => string.IsNullOrEmpty(thread.ShortSummary)
|| string.IsNullOrEmpty(thread.LongSummary)
|| !thread.TicketStatus.HasValue
|| !thread.TicketType.HasValue);
return MapParallel(threadsNeedingSummaries, async thread =>
{
await GenerateSummaryAsync(thread);
return thread;
});
}
private async Task GenerateSummaryAsync(TicketThread thread)
{
// The reason for prompting to express satisfation in words rather than numerically, and forcing it to generate a summary
// of the customer's words before doing so, are necessary prompt engineering techniques. If it's asked to generate sentiment
// score without first summarizing the customer's words, then it scores the agent's response even when told not to. If it's
// asked to score numerically, it produces wildly random scores - it's much better with words than numbers.
string[] satisfactionScores = ["AbsolutelyFurious", "VeryUnhappy", "Unhappy", "Disappointed", "Indifferent", "Pleased", "Happy", "Delighted", "UnspeakablyThrilled"];
var product = products.Single(p => p.ProductId == thread.ProductId);
var prompt = $@"You are part of a customer support ticketing system.
Your job is to write brief summaries of customer support interactions. This is to help support agents
understand the context quickly so they can help the customer efficiently.
Here are details of a support ticket.
Product: {product.Model}
Brand: {product.Brand}
Customer name: {thread.CustomerFullName}
The message log so far is:
{TicketThreadGenerator.FormatMessagesForPrompt(thread.Messages)}
Write these summaries:
1. A longer summary that is up to 30 words long, condensing as much distinctive information
as possible. Do NOT repeat the customer or product name, since this is known anyway.
Try to include what SPECIFIC questions/info were given, not just stating in general that questions/info were given.
Always cite specifics of the questions or answers. For example, if there is pending question, summarize it in a few words.
FOCUS ON THE CURRENT STATUS AND WHAT KIND OF RESPONSE (IF ANY) WOULD BE MOST USEFUL FROM THE NEXT SUPPORT AGENT.
2. A shorter summary that is up to 8 words long. This functions as a title for the ticket,
so the goal is to distinguish what's unique about this ticket.
3. A 10-word summary of the latest thing the CUSTOMER has said, ignoring any agent messages. Then, based
ONLY on that, score the customer's satisfaction using one of the following phrases ranked from worst to best:
{string.Join(", ", satisfactionScores)}.
Pay particular attention to the TONE of the customer's messages, as we are most interested in their emotional state.
Both summaries will only be seen by customer support agents.
Respond as JSON in the following form: {{
""longSummary"": ""string"",
""shortSummary"": ""string"",
""tenWordsSummarizingOnlyWhatCustomerSaid"": ""string"",
""customerSatisfaction"": ""string"",
""ticketStatus"": ""Open""|""Closed"",
""ticketType"": ""Question""|""Idea""|""Complaint""|""Returns""
}}
ticketStatus should be Open if there is some remaining work for support agents to handle, otherwise Closed.
ticketType must be one of the specified values best matching the ticket. Do not use any other value except the specified ones.";
var response = await GetAndParseJsonChatCompletion<Response>(prompt);
thread.ShortSummary = response.ShortSummary;
thread.LongSummary = response.LongSummary;
thread.CustomerSatisfaction = null;
thread.TicketStatus = response.TicketStatus;
thread.TicketType = response.TicketType;
var satisfactionScore = Array.IndexOf(satisfactionScores, response.CustomerSatisfaction ?? string.Empty);
if (satisfactionScore > 0)
{
var satisfactionPercent = (int)(10 * ((double)satisfactionScore / (satisfactionScores.Length - 1)));
thread.CustomerSatisfaction = satisfactionPercent;
}
}
private class Response
{
public required string LongSummary { get; set; }
public required string ShortSummary { get; set; }
public string? CustomerSatisfaction { get; set; }
[JsonConverter(typeof(JsonStringEnumConverterWithFallback))]
public TicketStatus? TicketStatus { get; set; }
[JsonConverter(typeof(JsonStringEnumConverterWithFallback))]
public TicketType? TicketType { get; set; }
}
private class JsonStringEnumConverterWithFallback : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
=> typeToConvert.IsEnum;
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var closedType = typeof(ErrorHandlingEnumConverter<>).MakeGenericType(typeToConvert);
return (JsonConverter?)Activator.CreateInstance(closedType);
}
private class ErrorHandlingEnumConverter<T> : JsonConverter<T> where T: struct
{
public override bool CanConvert(Type typeToConvert)
=> typeToConvert.IsEnum;
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
{
return default;
}
var enumString = reader.GetString();
return Enum.TryParse<T>(enumString, ignoreCase: true, out var result)
? result
: default;
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
=> throw new NotImplementedException();
}
}
}
================================================
FILE: seeddata/DataGenerator/Generators/TicketThreadGenerator.cs
================================================
using eShopSupport.DataGenerator.Model;
using System.Text;
using System.ComponentModel;
using System.Numerics.Tensors;
using Microsoft.Extensions.AI;
namespace eShopSupport.DataGenerator.Generators;
public class TicketThreadGenerator(IReadOnlyList<Ticket> tickets, IReadOnlyList<Product> products, IReadOnlyList<Manual> manuals, IServiceProvider services) : GeneratorBase<TicketThread>(services)
{
private readonly IEmbeddingGenerator<string, Embedding<float>> embedder = new LocalTextEmbeddingGenerator();
protected override object GetId(TicketThread item) => item.TicketId;
protected override string DirectoryName => "tickets/threads";
protected override IAsyncEnumerable<TicketThread> GenerateCoreAsync()
{
// Skip the ones we already have
var threadsToGenerate = tickets.Where(t => !File.Exists(GetItemOutputPath(t.TicketId.ToString()))).ToList();
return MapParallel(threadsToGenerate, GenerateThreadAsync);
}
private async Task<TicketThread> GenerateThreadAsync(Ticket ticket)
{
var messageId = 0;
var thread = new TicketThread
{
TicketId = ticket.TicketId,
ProductId = ticket.ProductId,
CustomerFullName = ticket.CustomerFullName,
Messages = [new TicketThreadMessage { AuthorRole = Role.Customer, MessageId = ++messageId, Text = ticket.Message }]
};
var product = products.Single(p => p.ProductId == ticket.ProductId);
// Assume there's a 1-in-3 chance that any message is the last one in the thread
// (including the first one, so we might not need to generate any more).
// So the number of messages in a thread is geometrically distributed with p = 1/3.
const double p = 1.0 / 3.0;
var maxMessagesInThread = Math.Floor(Math.Log(1 - Random.Shared.NextDouble()) / Math.Log(1 - p));
for (var i = 0; i < maxMessagesInThread; i++)
{
var lastMessageRole = thread.Messages.Last().AuthorRole;
var messageRole = lastMessageRole switch
{
Role.Customer => Role.Assistant,
Role.Assistant => Role.Customer,
_ => throw new NotImplementedException(),
};
var response = messageRole switch
{
Role.Customer => await GenerateCustomerMessageAsync(product, ticket, thread.Messages),
Role.Assistant => await GenerateAssistantMessageAsync(product, ticket, thread.Messages, manuals),
_ => throw new NotImplementedException(),
};
thread.Messages.Add(new TicketThreadMessage { MessageId = ++messageId, AuthorRole = messageRole, Text = response.Message });
if (response.ShouldClose)
{
break;
}
}
return thread;
}
private async Task<Response> GenerateCustomerMessageAsync(Product product, Ticket ticket, IReadOnlyList<TicketThreadMessage> messages)
{
var prompt = $@"You are generating test data for a customer support ticketing system. There is an open ticket as follows:
Product: {product.Model}
Brand: {product.Brand}
Customer name: {ticket.CustomerFullName}
The message log so far is:
{FormatMessagesForPrompt(messages)}
Generate the next reply from the customer. You may do any of:
- Supply more information as requested by the support agent
- Say you did what the support agent suggested and whether or not it worked
- Confirm that your enquiry is now resolved and you accept the resolution
- Complain about the resolution
- Say you need more information
Write as if you are the customer. This customer ALWAYS writes in the following style: {ticket.CustomerStyle}.
Respond in the following JSON format: {{ ""message"": ""string"", ""shouldClose"": bool }}.
Indicate that the ticket should be closed if, as the customer, you feel the ticket is resolved (whether or not you are satisfied).
";
return await GetAndParseJsonChatCompletion<Response>(prompt);
}
private async Task<Response> GenerateAssistantMessageAsync(Product product, Ticket ticket, IReadOnlyList<TicketThreadMessage> messages, IReadOnlyList<Manual> manuals)
{
var prompt = $@"You are a customer service agent working for AdventureWorks, an online retailer. You are responding to a customer
enquiry about the following product:
Product: {product.Model}
Brand: {product.Brand}
The message log so far is:
{FormatMessagesForPrompt(messages)}
Your job is to provide the next message to send to the customer, and ideally close the ticket. Your goal is to help resolve their enquiry, which might include:
- Providing information or technical support
- Recommending a return or repair, if compliant with policy below
- Closing off-topic enquiries
You must first decide if you have enough information, and if not, either ask the customer for more details or search for information
in the product manual using the configured tool. Don't repeat information that was already given earlier in the message log.
Our policy for returns/repairs is:
- Returns are allowed within 30 days if the product is unused
- Defective products may be returned within 1 year of purchase for a refund
- There may be other warranty or repair options provided by the manufacturer, as detailed in the manual
Returns may be initiated at https://northernmountains.example.com/support/returns
You ONLY give information based on the product details and manual. If you cannot answer based on the provided context, say that you don't know.
Whenever possible, give your answer as a quote from the manual, for example saying ""According to the manual, ..."".
If needed, refer the customer to the manufacturer's support contact detail in the user manual, if any.
You refer to yourself only as ""AdventureWorks Support"", or ""Support team"".
Respond in the following JSON format: {{ ""message"": ""string"", ""shouldClose"": bool }}.
Indicate that the ticket should be closed only if the customer has confirmed it is resolved.
It's OK to give very short, 1-sentence replies if applicable.
";
var manual = manuals.Single(m => m.ProductId == product.ProductId);
var tools = new AssistantTools(embedder, manual);
var searchManual = AIFunctionFactory.Create(tools.SearchUserManualAsync);
return await GetAndParseJsonChatCompletion<Response>(prompt, tools: [searchManual]);
}
public static string FormatMessagesForPrompt(IReadOnlyList<TicketThreadMessage> messages)
{
var sb = new StringBuilder();
foreach (var message in messages)
{
sb.AppendLine($"<message role=\"{message.AuthorRole}\">{message.Text}</message>");
}
return sb.ToString();
}
private class Response
{
public required string Message { get; set; }
public bool ShouldClose { get; set; }
}
private class AssistantTools(IEmbeddingGenerator<string, Embedding<float>> embedder, Manual manual)
{
[Description("Searches for information in the product's user manual.")]
public async Task<string> SearchUserManualAsync([Description("text to look for in user manual")] string query)
{
// Obviously it would be more performant to chunk and embed each manual only once, but this is simpler for now
var chunks = SplitIntoChunks(manual.MarkdownText, 200).ToList();
var embeddings = await embedder.GenerateAsync(chunks);
var candidates = chunks.Zip(embeddings);
var queryEmbedding = (await embedder.GenerateAsync([query])).Single();
var closest = candidates
.Select(c => new { Text = c.First, Similarity = TensorPrimitives.CosineSimilarity(c.Second.Vector.Span, queryEmbedding.Vector.Span) })
.OrderByDescending(c => c.Similarity)
.Take(3)
.Where(c => c.Similarity > 0.6f)
.ToList();
if (closest.Any())
{
return string.Join(Environment.NewLine, closest.Select(c => $"<snippet_from_manual>{c.Text}</snippet_from_manual>"));
}
else
{
return "The manual contains no relevant information about this";
}
}
// Note: this is not very efficient. Consider using a chunking library.
private IEnumerable<string> SplitIntoChunks(string markdownText, int maxLength, SeparatorMode mode = SeparatorMode.Paragraph)
{
string[] separators = mode switch
{
SeparatorMode.Paragraph => ["\n\n", "\r\n\r\n"],
SeparatorMode.Sentence => [". "],
SeparatorMode.Word => [" "],
_ => throw new NotImplementedException()
};
var currentChunk = string.Empty;
var blocks = markdownText.Split(separators, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
for (var blockIndex = 0; blockIndex < blocks.Length; blockIndex++)
{
var block = blocks[blockIndex];
if (currentChunk.Length + block.Length <= maxLength)
{
if (!string.IsNullOrEmpty(currentChunk))
{
currentChunk += separators.First();
}
currentChunk += block;
}
else
{
if (currentChunk.Length > 0)
{
yield return currentChunk;
currentChunk = string.Empty;
}
if (block.Length <= maxLength)
{
currentChunk = block;
}
else
{
// This block alone is too big to fit in one chunk, so use a narrower split
SeparatorMode? nextMode = mode switch
{
SeparatorMode.Paragraph => SeparatorMode.Sentence,
SeparatorMode.Sentence => SeparatorMode.Word,
_ => null
};
if (nextMode.HasValue)
{
foreach (var chunk in SplitIntoChunks(block, maxLength, nextMode.Value))
{
yield return chunk;
}
}
else
{
// Even a single word is too long
for (var pos = 0; pos < block.Length;)
{
var chunkLength = Math.Min(maxLength, block.Length - pos);
yield return block.Substring(pos, chunkLength);
pos += chunkLength;
}
}
}
}
}
if (currentChunk.Length > 0)
{
yield return currentChunk;
}
}
private enum SeparatorMode { Paragraph, Sentence, Word }
}
}
================================================
FILE: seeddata/DataGenerator/Model/Category.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class Category
{
public int CategoryId { get; set; }
public required string Name { get; set; }
public required string[] Brands { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Model/EvalQuestion.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class EvalQuestion
{
public int QuestionId { get; set; }
public int? ProductId { get; set; }
public required string Question { get; set; }
public required string Answer { get; set; }
public required string VerbatimQuoteFromManual { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Model/Manual.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class Manual
{
public int ProductId { get; set; }
public required string MarkdownText { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Model/ManualPdf.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class ManualPdf
{
public int ProductId { get; set; }
public required string LocalPath { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Model/ManualToc.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class ManualToc
{
public int ProductId { get; set; }
public string? ManualStyle { get; set; }
public required List<ManualTocSection> Sections { get; set; }
}
public class ManualTocSection
{
public int SiblingIndex { get; set; }
public required string Title { get; set; }
public List<ManualTocSection>? Subsections { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Model/Product.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class Product
{
public int CategoryId { get; set; }
public int ProductId { get; set; }
public string? Brand { get; set; }
public required string Model { get; set; }
public required string Description { get; set; }
public decimal Price { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Model/Role.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public enum Role { Customer, Assistant };
================================================
FILE: seeddata/DataGenerator/Model/Ticket.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class Ticket
{
public int TicketId { get; set; }
public int ProductId { get; set; }
public required string CustomerFullName { get; set; }
public required string Message { get; set; }
public string? CustomerSituation { get; set; }
public string? CustomerStyle { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Model/TicketThread.cs
================================================
using System.Text.Json.Serialization;
namespace eShopSupport.DataGenerator.Model;
public class TicketThread
{
public int TicketId { get; set; }
public int ProductId { get; set; }
public required string CustomerFullName { get; set; }
public required List<TicketThreadMessage> Messages { get; set; }
public string? ShortSummary { get; set; }
public string? LongSummary { get; set; }
public int? CustomerSatisfaction { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public TicketStatus? TicketStatus { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public TicketType? TicketType { get; set; }
}
public enum TicketStatus
{
Open,
Closed,
}
public enum TicketType
{
Question,
Idea,
Complaint,
Returns,
}
================================================
FILE: seeddata/DataGenerator/Model/TicketThreadMessage.cs
================================================
namespace eShopSupport.DataGenerator.Model;
public class TicketThreadMessage
{
public int MessageId { get; set; }
public required Role AuthorRole { get; set; }
public required string Text { get; set; }
}
================================================
FILE: seeddata/DataGenerator/Program.cs
================================================
using eShopSupport.DataGenerator;
using eShopSupport.DataGenerator.Generators;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddJsonFile("appsettings.json");
builder.Configuration.AddJsonFile("appsettings.Local.json", optional: true);
builder.AddOpenAIChatCompletion("chatcompletion");
var services = builder.Build().Services;
var categories = await new CategoryGenerator(services).GenerateAsync();
Console.WriteLine($"Got {categories.Count} categories");
var products = await new ProductGenerator(categories, services).GenerateAsync();
Console.WriteLine($"Got {products.Count} products");
var manualTocs = await new ManualTocGenerator(categories, products, services).GenerateAsync();
Console.WriteLine($"Got {manualTocs.Count} manual TOCs");
var manuals = await new ManualGenerator(categories, products, manualTocs, services).GenerateAsync();
Console.WriteLine($"Got {manuals.Count} manuals");
var manualPdfs = await new ManualPdfConverter(products, manuals).ConvertAsync();
Console.WriteLine($"Got {manualPdfs.Count} PDFs");
var tickets = await new TicketGenerator(products, categories, manuals, services).GenerateAsync();
Console.WriteLine($"Got {tickets.Count} tickets");
var ticketThreads = await new TicketThreadGenerator(tickets, products, manuals, services).GenerateAsync();
Console.WriteLine($"Got {ticketThreads.Count} threads");
var summarizedThreads = await new TicketSummaryGenerator(products, ticketThreads, services).GenerateAsync();
Console.WriteLine($"Got {summarizedThreads.Count} thread summaries");
var evalQuestions = await new EvalQuestionGenerator(products, categories, manuals, services).GenerateAsync();
Console.WriteLine($"Got {evalQuestions.Count} evaluation questions");
================================================
FILE: seeddata/DataGenerator/appsettings.json
================================================
{
// REMEMBER NOT TO COMMIT YOUR API KEYS TO SOURCE CONTROL
// To reduce the risk, copy this file as appsettings.Local.json and make your changes there,
// since that file overrides anything configured here and will be ignored by Git.
"ConnectionStrings": {
//"chatcompletion": "Endpoint=https://TODO.openai.azure.com/;Key=TODO;Deployment=TODO"
}
}
================================================
FILE: seeddata/dev/categories.json
================================================
[
{
"CategoryId": 1,
"Name": "Solar Power",
"NameEmbeddingBase64": "SabWv7X47T8/yLw\u002B9FtpP3Tzpj7DYZM/yAmSP2rGgb9FhIc\u002Bzk8aP0LTqz8WMbe/YKWmO6o16T8bVYU/gRqDPjSqhD9jDRs/g/Sgv1sc6D4siCBAIk7\u002BvwwTwb\u002BWism\u002BJ4jSP0jxurwMhLY\u002Bn5Q1Pk2Ohb8rMCTADhzcvT7Ltb9a7Ym/bGfYPvSRUr4qm3y//leLvQamJ8D4ROy/VPfxPrURFr\u002BZZjXAX2lUvkgwZz45FBLAAEn2PiCIMD/mW4C\u002BwGy8P9ALPb\u002BRW\u002BU/MXk/v/jeEb8QUiE/eq5MPigjLD\u002BYCZI/dyLnPzbBDUCzWDq\u002Bmn67Pu3pCUDP3KrACiFsP4/zGEB6kZU\u002BsfCqvp\u002BBJT8dtVS/hA46vza2iT7cbGq9KfAzv0O\u002BZL9ppaa/sYe6P0ezG8AdcLm/8Dj9v62crb9EjGY\u002BmME0v1I/kr\u002BiJEY/JamqP35vAEDI73o/xlWbP9vtsz/QKAlAhPabvzK8Jr13ORq/jonaP49lvL\u002Bdh/u\u002BH6vEPwpQ3b/6GAW/NnunQMZ0o73McZc/6JlnP7Slp74Hwji\u002BT1Bov51/Xj5cwTY/eIaCPD77tr8f40G\u002BVcbAPp3WDb8k/aW/mnkGQGKRn76OZtm\u002BT2VNP1rcBMBgXiA/h6aNv5T7aj8KgTxA5u0YP0qSmT9Qn3O\u002B9mQUQFYW\u002Bz9RyZC\u002BvmGvPzg8Ij9yGc6/iamTv4Q5Oz8BIyw/7okJPzj6hD\u002BNLUq/k/S2P0SfpL4jEKo/4UV/PRVz1z7GKmPASHyaP41akr\u002BbwyE/g4qpPxiZq7\u002BygWw/6NhPveAZ7z\u002BlZ68/kVdGv8a/rj8lYl0/wm42voRpnz6ALZo\u002BSg2fvm6qmz\u002BROxBA5HWgvyYqM0AdLA4/3Qs3wP6MAD9EaQu/lzxIPhhiFz/3vN8/T34ZQAx3xDy48te/iIcfQGNEB79GDWS/JJaivluF079Vbso/9rq8Pa2fkD9KnWQ/aleiv6fa4z6kb0S9mtVhv55f/z7deuq/INyfPqlobcCtUSM/di99Pnxgqj9Mc0G\u002BCHUav\u002BOdmr9yJhjAuZpNP4h53r/nL6Q\u002BmO1Av6WfhL//HClAFuVUP8bNBL42Dvi/zFH7Pv4jpr\u002Bq/wQ/1BOLPzQmlr92j7s/eMaUP1lrhcCkAKM/wRS1PlKrqD4ysNk/DnW0vhZZlj\u002BAE9e/0x4LwJx7t8BSIgm/Vxk/v9o1UL\u002BrJ3E/xh98v\u002BzOdT8LLsi/J9nFv9DIqL86thpAqpdnv8TEKj5g66C/fDwnvnsGWT9CN1w/Kp2nv1jcIz741Rq/VCj4vl/1uD/6gG9AYDjcv7lMlz/Scpy/HoI4QFBEgz\u002Bk6rc/8T1mv7vQfL\u002B19x6/C9DCPpB9KL94dQQ/R06FPzxmFj/6FZ0/746Pv6xyOz6mUdY/SrJXP744\u002BL/8pMM9RfJrP\u002B26t7/hviQ\u002BFporPqvzgT/0qfe//x0AQMIUfL8F9om/hdigvzitE0BypTo\u002BUfIIwFNIW0D4Z0u9i\u002ByWPo/6s7\u002B4/\u002B8\u002BOnQyv2hAvb4BLXM/OOGwPuKpoL5JIms/N9thPtKZtT7AX5S/MIfmP9CuHL4gNya9qrFHP85E3r7hbGI/vDTCvAnunj88lae/cNP6vEJYCL/0Dt8\u002BwLaRO7SBGb78KQo9vY/FvuQzJr4Qu0C/QfeDv9U5Q74Hf8Q\u002BOBbdviBKBbwN6R5AvSqSP2qTs8B5qbM/JyAEv6hUY78IdNe/WeP0vQ4z6T/KY5U/UC6ZviB8lD9b/wnAYoTWPipDPL9cOJ0/hOMDP0zmzzwlXJ8\u002B8e52vpWIRb5YhoI9QVQNQOKa2T5muF1Aa3aSv7RbbL4ppl8//hJ\u002Bvx0pBUBWw5U9ROQBvzH8hL8lVgW\u002BWk4Nvh6xzz4uLba\u002BrzRgP8grJT9SQuS/t2O8PzUfkr\u002B2WIa/s\u002BsGQKwqQ7wzDcO\u002Bu1qBP6OWKMBYfK49sHERwCyxNb9jTU2/OP9gvzgubLx\u002BlgXAwIvAPRC9rb\u002B4xK6\u002BnnN7vx4QDcDccwQ//oOovwZAzz9pZP0\u002BkeWdP3Zf4b96UGs/"
},
{
"CategoryId": 10,
"Name": "Lighting Solutions",
"NameEmbeddingBase64": "QpCAv3TUSr774zU/V3oVPlnoqz9yzxI/wfKQPWSZGD5sZi29\u002BJXyPxzc1z7Aqvy8kN\u002BYv/iE6D9nW0U/SMT4PZAFuz8apBQ//\u002B66v8oRbL/WM5Q/kZdov6jbJcBOsp2/W8AzPtogGL\u002Btnkg/pgDZv7wsPD1FfyjAGZSRv2g8LrwXtRs/auGcPpPBCz\u002Bx/A2/LakXv\u002BOUDr/Vvdy/ffNfv/zU6D983vm/8IATv8W93b\u002ByIh\u002B/Ui1vv4gr\u002BjzyyUe/vdPbverpkb9WXq4/x2o5v0xJNb7W/5e9JkicPgYRFD9etac/OEMAQOR8rj\u002BgK5M7AkaYvQNGIkDCyIPAgNIGQLjXYD6bp\u002BU\u002B9jaqPaY8XL9W3L0\u002BvgkEP9ZR/L44n7y/dguKPkw7WL6235a/rfNAPfRxTL3Aetu/lUWnv11Fpb9YLR4/2sZVv37XXb80XtA\u002BBNSKPgEQ4z8Pt2y//G3avcoeTT\u002B7Hq4/i8mBv/J6Nj5T9PK/JxS\u002Bv\u002BKpnT1AZAbATGkzvuBLmb\u002B\u002Bl8i\u002BfrbKQNBpOr33TrU9Z4bzPx5t7r9jKEs/Tz41v1JVrD7IGGw9tAGVv0Qb0D\u002B44AG/WjYgv1D7Grw\u002Bd1K\u002BD5mcP0RfqD0B9oW/NaBrP4ysTb/uhqK/AMhCOm6yKkCQA0pA7B00vo4QlT92GbW\u002BvghAP5Z0MECkE32/yxRbP5lLtD5gfjm/tdI1Py6hvL7Fsy6/zAydP0VUNj/AhIE8eLW8vTs0GUDnBVY/ovuDPnbbrD8z9\u002BS/BvfMPgpD6z/whC0\u002ByD9AQJHR679Rx02/aOBhPrRm9Dx0FYU/fkFDvrMijz\u002BQZ1I/RpnOPxegKb8n6cE\u002BAJDzP0bHkT8UH6E/wt2ev4B6akC2mYi/8EJawOE0Tz/mCMm/480jwDpiVr\u002B8f3q/YqIzQBFmA0A4aOm9kqvlPxKnmj3t7Wa\u002BP40Xv5RJlb\u002BwVZE/mWgxP/GEIL90aAu\u002BtikgP3ZBqj8ZNs\u002B\u002B4iAfP9aYnj8kd7O/vm0OQFve57\u002BxlYG\u002BaNvXPDX/vz/rYqU\u002BPAtGvWEUP8DSqSnA2kuaPxYMEb8Sw5M/E\u002BWGv66yvL6uOqu/4CkNQKj49r5SBEa/0qZCP5jT8DwOcaU\u002BjIbWvwHvfb8GtFVAVlujPijfH8DufdY\u002BK08Av6aBcT/YF2a\u002Bg49gP4JQrT6jO/s\u002BCgqzvyg0pMAsG\u002BI/KpHFvqSLx7\u002Bxcik/E5TIv\u002Bwgxb7\u002BqrC/F4UhwCif7T/igyNAbjW\u002BPhaDMj8CVNO/gsTIPgZH975X/ia/JIWJv477y75uuMy/SunavUx01j4LqQ9AvHckwN9N0b5yyAY/z32NQEpAUj9cPZ091mDtvnQpSj1\u002BbZy/KuwBv6tub78ibbY/Do2sP2Bxzj\u002BipbU\u002BAIZWPirIWb8YX9E/hyO7P4bsGsC8HmK\u002BMmCtPi2Oxb/1WpA/bGHMvhQEXL7ULS6/DGCNP/H6lL53Zm8/QbdFP8E57T7\u002BE12/kl2/v84lmz/ARJq80\u002BDIv\u002BrSor7Aq2i/OoJbP81RBMCy1g5AcDUFP/\u002BtyD7cXDK9tjpLP29Iw74k1ce/Um8RQHbru78kS8I/gP1aPxJZmj/9aN8/wnYav3K9Kj\u002B\u002BJAu/oSQxv63vxr\u002BalZY\u002Ba00SP9Ls0z4fGpG\u002BuMfev9b2V7/9\u002Bak\u002BY0znPtKanr\u002B7SEe/nqiPvcQAer9HgLU9JzW7P/pCqMA0qhg/HBqQPGzsH8A6hxbAceSDP3UkFz\u002B97eg/Di9ZP5wQtz5k4lDAklPpPuwj17/0xdM\u002BkeGjPzrJmD1MSWY/uknnvxAWgb0Y4fe\u002BKG3APhuqpD60SJNAeLojwH19Mb8SMW8/R/WLPxUfEL/nmoo\u002B0W1\u002BPzIp9T6OjhtAXURbP/FqHr8wJtk/wNjpPA7Hvj4RGH\u002B/5T1zvrT0Fj/pOhw/jbqHP2ZNg79WZaO\u002Bv4JnP2DgXr8XuIC\u002BCDqzvqz8rL6/Awm/66wGv1k8LL8GHu8\u002BTGc\u002BP0ym4T0YuqA8q1Y6wO5M9j7\u002BNoE/SsErvyhFFb57hhPAddbXPsCdXT1VKQFA"
},
{
"CategoryId": 11,
"Name": "Action Cameras",
"NameEmbeddingBase64": "wo32vn4K0L6oshG9jpCtv/RZjD9J8iNAOSvcPyyryj42aE\u002B/73gDQPpfIT/JKQ2/qkMdvoKbAUDUUzA/TkQhPkvvzD/t\u002B72\u002BJYgwv3gEVT/cMqC/41ycv87\u002BCUDY4yK9lNgcvxvYI7/Jtkc/IT9uv6ncI78xmhrAIslPPhASqL2gn\u002BY/kVqIPlqggr6sll6/RvG0v51BAb85QjnAW8\u002BEP7ZDoj7Txyk/pk0TPdOTBMDe21k\u002BmlkMv\u002BBCeD/nS8\u002B/InwBP3xOub/udMA\u002BF1oWwFyUMT\u002BURBu/OpkRv8aFy79jC64\u002BIPNbP0rN8D8z\u002BPW\u002B7R0iQIo/Yj8njoHAzC0BPr9Urb/n0bY/xxznPxaUmT2mz70/WlJYv4JM3r9sKo4/t0ApP0x2KD\u002B/vgC/5mDKvhk7H78hwf6\u002BNmhcv2yBG8DIUbA\u002BqSqtv1TjkD\u002BsgyU/ilI3Psfcjr9sukw/Uybnv\u002BZW0T/gEXo/Dk5kv9jmuz9s5f6/uu\u002B6PjA7wL/OQak\u002BxuAkPkn61L5wULu\u002BBPTkQG7MSr9gNK8\u002BUrfKP1KjV78dRGc/RaiEv1uFSr\u002B3pwe/5Cfdv0Cnvj/yA5g/mlnivpK66L1T8Ng\u002B/ByNP0QJCz9Rvq\u002B\u002BO5iaP\u002BLKx74Q7/\u002B/rkmtPwrRKL8uaIU/\u002BuCrvxSyj79IpK2/iR5NP0AfeUBW78c/Z4ZAP0qRsD1gcR6/UHHqvU\u002Brhr8mS1U\u002BvPS6P5Qpvj/p0BU/hvOXPpghsT4\u002Bl7I\u002BNKpWPqWm9z/Q7c\u002B/rrjsvo4K\u002Bz75UmO/AGyoPGp9wT4JFdW\u002BQcxhPyTsDkBe8yY/CSbCP/Nbgj\u002B\u002BnIi\u002BhzPcP3ZsLL91RY\u002B/Z6mWPgSBzb/JOIS/N9Dovu628z8cp9e9om5QwCcqrj\u002BoGO\u002B/lYSDv2yitj/Kk5G/udkLv9ZhOL5oymy7asgcP4pOkT5ege\u002B/pkMtP85QkL9SZe4\u002B0vD3Piv3yb9O0FY/BZgtv6nguz7U3Bk9zsdlPWaSab4UxII/bCMiQI0\u002BR7\u002BQ3hM9jyxWvoR2mT8UzC\u002B9ejNLP3aRNr90ape9GVJpv\u002BU4x79kaNI/CZJav8Y12b7SBeI\u002BOD8vPzXnsb8AMS/AsiE\u002BPwUY2L\u002BwYaM/qtngvjFOhz\u002Bs2DBA7KADvy2V6L8i35q\u002Bu2JEvzgwTj9zOx/ALJ2QPIIqk7/gM2u8qPLrP2yswcAeuh8\u002BQKf2v9cZ2D4obek9eND8v0KhIL4YTiQ9xmhmP3znBUACm0BAZ23Yv9TuIz4IDy0\u002Bg2vcPqMa3D/k6ye/JXHBP7LmsL/4hAe/szVIvwARSj91Bbs\u002BGpMQwGWFVz/b8Sm/DL6KQC7erT9c/Pw/Rj7jPwDwKbg5S60/pKPnv1BCQr8cBE\u002B9vNJ8v5B5/j/ct9E/md8RPlSRwr/5n26\u002BunP2vhDYmD8DsRPAnxiTP0DFob6AkZi/qMTdP3Dlib/XfkPAcCiMP3GUG742Kq8\u002Bb0Fuvyz2TT1mUsE/UCRdPBbYTj9Ox90\u002BcZqWP\u002BeJlL/KuKo9XpwzP1bMA8Ady0NAOEwRvg6OxD5HePa/QCeUP0ntlT8twMI9dm8UQPbOBj6E1Xs\u002BuVP2Pzx0VD92Y3M/Eo2dvzzLA8BRU6\u002B/jE0svkEY6T5uhnG/c/U\u002BPgSqez\u002BoDo2/R/loP4Hm2r9qI\u002BC9Gy5Zv35MPT8Z\u002BaA\u002BrDK9v6RULT0FkWI/vkdgvm0vqMBw0ju/WhotPxSTe7\u002BOsqm/jfAFvxqiAUBOHuY9\u002B93xPQ4lA0ADmLC/tOjOPxdrn77Ldak//\u002BBxv5A8lD8WS4Y/DUYWP3MYIUD4UgHAF/yYP8KokT9sc8M/B/BDv3LO/76AaNk6a7KSvx23DL/ilgY/BqDAv5qUHz\u002BtvO2/aCKfPlNAoD3AT4W7Bv\u002BiP6dxUT92CLC\u002Bwua\u002Bvz3tbz8oNz2/ed0Zv4/Q1D8wSje/46qUP\u002BPzKL9oVGk96fucPqJBCcAeT74/fy5xPtBNub9C9ly/e1kNP6AfBkDS5Uw/jivcv6T/kj/sSha/hNNQvTe1sj8Itu2/ojVvP89E47/l73a/"
},
{
"CategoryId": 12,
"Name": "Excavation",
"NameEmbeddingBase64": "mpmVvwS4nj94zT8/INQJP7ODyL4ks0O/Fpu8viObHb80bDq/wqinvloAYz/A/xrAxoKyPVZB1z9pIJ892EMLP6/PWr\u002Bc3QFA9qltP6a1tr/C75w/JDSiv2mBiD99ae2/e8q7vy5Mnj/zJ2K/jM6XvwrVBz7tOAHAIuKFvqCOQb4WVLw/7aKePlibmD\u002BQuvs/Luu3v1MLm774zSC/BEWJP2b63z4QNkM/6I4Tv4Zxs780XnI\u002BvQTCvh\u002BJXz6YUIS/WLVSP7ynOL7V6h8/6Fk7v7q0lj6ObeQ9PP7aPMA0Fz\u002B9zuM/F5ngPrI1Cj\u002Bm\u002B7k8jJvqP8B6tz6rFErAPMqHPlLSbz8YOBm\u002B5PkyvxsRqr8pq3E/hpxHP4X7IT8X0lk\u002BwIzqu5b3tz7Wxrs/px1FP6Tp9768AEA/vNyKv47yHb\u002B22pg/sElSPzvnib0ejjg/lIjDvzRcWr6laIy9wM5MPcAITj5yGeQ/CBNbPzDvo77ophG/xuFqP\u002BDuMb\u002BipKu\u002Bph5jv1h19z9QkpC\u002ByuPEQAgMc7/1TrM/HDwXP52yI76gyxA/HhkcPp1BM77XS6i\u002Bzv\u002BTvmI9CT8DaPw\u002BYkDrPf4o0r\u002Bj6wG\u002BDl8QPpAoNj\u002BAbC8/GoKpPkmOY7\u002Bvd3C\u002BxoZ/vvQEgDzKwps/3GuFv6IDkL0CAOe9xOaIPgSA\u002Bj9Q0T0/g8TfPjX16L7Iy8W/bDjcvraxLT9ceBu/O/e9P0f9\u002BD6Y8Hu\u002BAj99vwA3hj00jMK/kLJIv7iyZj8jGbC/7Yeuv1kQgj/Etqk\u002BrI26vhC0lL7iG4y/KBTHvxAL0bxTbABA8nrXPj7dnz/rNAm/\u002BBxXv5OBFb/yNIa/d1Hivk\u002BKnD3\u002BMwm/kVWGv9ULHUCR5wFA5CCwv2wRgL9FnVA\u002BkrEFP5mNVr9OLIo/FzQzP\u002Bo9Vr\u002BC7em\u002BLkPGP4g0yD1EAsy/\u002BCt4PiBgO78v\u002BnM/5t8dP9ZryL8ariq/ozilP/7l\u002B73nPJu/GS2Xvl6Axz7KhUo/lItGPph1lj12Rkk/BEBtv08jS7/Q0y4/siQCP7Zhqz7xPZw/TB/5v2DLZj/SOTC9AXYivwHVLr9oIFQ8cu5ZP1bimz9ebcy\u002BbkKAPwQ2x76TzQg\u002B6H6HPT4PFb9szEk/tHoFv8AWjj8hOmm/uDaxP7Z7Or8BuSK/JezCPp\u002B/Lb9noeC/DaZ\u002BPg6wqMDaPpq\u002BRtiXP0yJOT9u2IU/7MTvvv5GRD8liO6\u002BHEwSv/xJjL\u002BYXL0/3MYZPZD/cjwpSaI\u002B\u002BHbIvndHGT/B6Sk/Gohxv94bbr/HaxC/5/gYP3ivjb1il5Y/tu8PwPb1/L8s/Ci\u002BSA4rQKyFhD/qnaq9ZkSav9e3GT81zlu/Z70fPz3JQsDI6qS9XGaAvvYIsT8tt8M/rJhlPoyRZz57eoe/gMQbP23zjD80aQjACEyDPoBKN7wYN7m/lgLJv2Swuz8dlvW9YAQJP2aqBD/N8rE/CI4wPuwp2r9lPto\u002BSqqrvKwe4L5Qu6C/MBBSv50K7L6moIG/cL4tP\u002B80I78kKVQ/jdiPPiQfJL9BFGA/tGa7PUy7uL/BGp0/hrXmPnKAFr/MWvE\u002BACK2v3dvrL0mGb2\u002BjhNKPlBAZj9Mq5u/VUNDP6G/tz6oz5E9Aw92P1Q7Pz/a\u002Blk//14ZP5ckpb7UHI4\u002BpQEWvthTnb6G2Ck9YtEfvqq1ob8b248\u002BzE4nvljulcCcNoA/1CeEP\u002B\u002BESb9qjoi/xNAiv6h5vjzOOOU/eE0rQActJj/VI0S\u002BpAV3vgpBnj4OTRS/LnL/vNgwkD/y5IQ/rILLPnUdc7\u002BoWAbAHgt0vh/Xnz\u002BG8SFAhA6zPr5h2j8PYti\u002BM5i/v5iQSr4FUV4/Tngiv0rDhr7oh8a7YhcJQLxMlL4Fk9k\u002BAKmGP/h/nrvM\u002BoE/Cp1jv7sJOr9wXA3AP0LIvk4xr79M25A/qhFdP7Lkf7\u002BX31g/Wobgv8D9Zz\u002BlI7y\u002BoigivrvKXz\u002B7Kpo\u002BQmPkPez7Zj8I7Zs/Vvj\u002BvlPIwr4KtVa9XBUIvUV1XD8I2ZA\u002BQOjpPg14kb/p4pe/"
},
{
"CategoryId": 13,
"Name": "Portable Power",
"NameEmbeddingBase64": "dBdbv6/vUj9eVHQ/4cVcv2B/lTzwpdc\u002BH2ARPyT/4j5eIYu\u002BTY1jv4DxzD/FzeO\u002BWFS0vId9YD/GHww/Prb1Pume7j\u002BR0Aq\u002B\u002BQ9sv7lf0762JY8/se8LwHZfbr\u002BRcB\u002B\u002BsYVKPw7lb78iw5o/NJC3Pkjj0T24RVrAkrcFvwyxs76yUrO/xTikPpgQFb4e\u002Bwk/bQnSP4Xkcr8KeHO/JN5QvgWDzT4ollI\u002BSGw\u002BPlq0W77wig8\u002Bdp\u002Bqv5PTOb7yOpy/g49CQGynmb6y96A/6GIOPgRLs715KPO\u002BWnSiPiimuz\u002Bp2PY\u002BPHaPP/Iyqj9hwge/ob0XP3KpJ0AaPlHA3yyLPzzkTz\u002BRULQ/Cr6LPo42JD8AtPi8\u002BE0Tv4AL9jxkr549d8Y8Pzpotj8Klgu/T6NgP6c8lr8fZam\u002BkcfBvyyg5b2w8am\u002BwqLovwLUg7\u002BN0BU/eNB0v4x7fj9neXg/2DSrPLuunr/CVpA/4mQNwBRVZz8NacI\u002Blo\u002B\u002BP\u002BDT5r916ti/VBZbPSFF/r/eWPO/ojOtQFS3QL6ioY89pKS5PxlYur/4\u002BLG/qGFwv2jBPj\u002BagsM\u002Bw5qCv7bBAr/DUgg\u002BqNMsvnQgwb\u002BIB0q/UL3cP5awBD64mH6/xuVsP8NAsb9sn6k\u002BXjIUwFvDtj/0fuU/APQyv0Qi2D/Sd3G/3gTHP\u002BYrDUBIuba\u002Bypm6P2nysj3mCx09HKiuPRb62T48myM/HeeaPhKGgj9EhqC\u002BvoX8Pybsvz\u002BGsrU\u002BAxOJPtHoHz\u002B8tyTAoC3dPbqiwr5MjEs/0W88PvGPBb/OCvS\u002BJ25fP5Gjqj9X5Ks/Bb6ev4Zbpz8j2nc//GisPzrqOj85jBC\u002BfCCivnCNxz4mzHc/IEc5vxJboD8kKok/KMJPwGgTNj68Y5u\u002BCnFQPzfn779AyVU8EgnUPmDxw77sE0G/GNqdP6gIiLwBvh8/eF\u002BJP5ZaJcCg2Ei9\u002Bc1Ev1O4KT8e9\u002BC\u002Bc1TBvsPyn76Q/q4/5z7qvqy5lr8NsVM/KkJ3QJCfD8CCJAVAI\u002BBfPyZcGT/XVaC\u002BtBUAvxq78r\u002B2mHG/xUlNP/vnvr8tinY/cyt0vz/Xlr6Cabs/3iYnQJh8LD5dlOu/jZECPzD0X7\u002BKisU\u002BeLKBP2Dmrjs\u002BtyxAog\u002BQPnG2/b\u002B4uK6/uJyJvnDG1zxksg0\u002Bq\u002B9vv0FSkz6\u002Buh/A6rXrvlq/scDI70W/3kaUPBGDBD83unc\u002B5cWNvxNMrD9\u002BvpK\u002BIs6tvyqNDb8YuCVAdiCyvz5lSb9F/LE/kG2mvxx/3z/ovKI/ccDGv9vUm79VACA/38sfP\u002BgqmT8cWmY/MmF2PgDMeL97wZi/GxOLQPv7hr\u002BO6cU/Ac0Kv4g6yT/EL/E\u002BakQXv4y2xL8rK66\u002BedY1vq2wy79jcAm\u002B7ubjPsvApj8\u002Bvke/XFURQHdZDD\u002BcItK/dE5Av50wIb\u002B4EA6\u002BDPrAvxLEBr9\u002Bv6k\u002BVm6HP5QPBr\u002BUwyy/7z26vyhqcj9AT6y/qDelvzCGEEA3UGS/iKxWPbhucr91Q14\u002B1dndv9VN/L5UAdM\u002B6LGlPtY87r5bNUY/AU0jP1CCKL4OqLY\u002B\u002B4qNPzOjEz8jjARAPvAbQP6b3r9N6vM/sOxhP8IQ1j5/iz\u002B/VoJdvzGpJz9uLPU\u002BRN01PXf/Gr8RiQm/kN\u002BNvPxr4T\u002B4o8E\u002Bb2rpvs\u002BSTb8i91g/TtrnP64SmrzMgp4/27Y3P\u002BpNycDI9HA/EAS1vijPLL9ef6S/ZnoqP3d2Nj\u002Bl13M/Dpm9vzTUlT9Hp\u002BC/nE8fPwSA5L3AsKg/hIslP5mAyj59vJ0\u002BXSPOv6ltc756Ri/AW3wjP5zrkr22b1BAPo4CwFLYcT\u002BjQQM/5GOPPzc34z/ekVm9nAsPvkdKlr/gNRO/INQOQK9Exr/4PoQ\u002B4kOhv1SOvr9uZF0\u002BsgSsP8dGpr8\u002Borm\u002BOGx7P9dqX7/KfWy/wrzfP/2uE8Cj5O6\u002B/ie3vzEdhb/AcxC7NBfvPbn6I7\u002Bf3jy/3hqNPkUJkz/m6os\u002BcAt5v0ZGb76OOtu\u002BGXTfv7bmoD/n1Hq\u002BedKmP19gy79FOi1A"
},
{
"CategoryId": 14,
"Name": "Backcountry Cookware",
"NameEmbeddingBase64": "Lt42wOzoY76es7w/mMYIwGmVlT9PiYW/3LJVP70ChT9j9yvApzKEwF7ACcDLknfAbanPv7kyIECWzRK/2rEGwORFfD8Ku5o/6rdyPxxRpj2nyRdAxp04wIZ7Fb8RDqu/QUrTP1JSKT\u002BQQJG\u002BKx9fv3KegMDOVhHBH8DCP\u002B0glj4UEDy/2EkFvuJzqb76vBE/YUADvuOvqb/6shXAq39PQE3VJz/RfpA\u002BR4vTPpqtMb2SGJo\u002BdO1FPnjkyr9vfQC/PlDFQOHqCz8KUJI/ldnGvw2MUb92nV2\u002BaYVJQCP7eUCEMk\u002B\u002BUKE8P9yK0D/qLrC/hh9jQP4o5T7cPR/BDs7tP1JUwj4c5sO90IzOPpSe4j9fSP8/xKo9viS2DT67i1Y/ziWgP6aEKUCB5gK/Wu9UP3gxUD9Tjh7AJ\u002BouwFA\u002BAEBUz9u/CNq6vpKxdz9O4bk9gnsJwPZpccC\u002B5eq\u002BJ6T3vpTAhUDp/yS/HFC1P6ImuL/RNxm\u002BJkFPv1Gvn8BgOEXAEd1DQC\u002BMTD8dtwM/WhwOQYmOJ8BJOP\u002B\u002Bkq8gQMhjP78a6tA/LgIbv/OwKT8iIQA/kB8WwJDJ6b\u002BZ0tM/jX\u002BhP4FMBsD3yRRAA/j1P4zcnb9CSfo/kCRmPFabvb\u002Bev2s\u002BQNx2v9zGGD99\u002BTNAUCBGwPfVAkACzBe/SS3WPou8nEBIiwu/SSC6QDDHOT7cNwi\u002Bu0Wfvmhd4b8YmKa9KMooQKMzB0Cbcou\u002BSulGQLqcJb9KEzrAdJxAv/vDNUA4G4nA9arRPw\u002BcAUCLkFk\u002BXi3iP2Xv\u002Bb/KbGHA3UOmP8SszT\u002B6sF6/3cFivxShvz/ERG9AoJQGvuiZ6L11SgXAWSs/QFS4\u002Bj/YaNS\u002B\u002BlFUv4A2WL0b2JE/aBXuwHa8Mj87DeI/DifQPkzHgz301dy9GEB/PgGPF8ASg4u/EnKJQPMpUj\u002BxqDvACoGhv\u002Bd7BcAtvo8/zrtsv3d0i78UOUO/PSbUP0D75D8YqGXABEtzP\u002BO2jsCDTL0\u002B8nxgQFQIBsB7VLC/EN2Hv7JnqD\u002Bi\u002BCk/Lvjcv52Cc79eTls/4tQmPxCRNMBl2hlAHEYywJrdhD8ELoo/vDXoQGqqjj96Oci\u002BCCuIPewGOL4wW8M/N2kivsqhNj5TyzhA/pa9vwDZzL8pnaq/PkkBQJW3X0Ak3k\u002B/TOOwv/yxvT8ZrYbAjpRkwHkYF8G7YIw/N6Iwvi6xLT6EsyG//FyovrVHBr\u002B4OT8/EVCpP3bGBkAhZAtAaOspPgjn7D\u002BTc/Y\u002BWB0pvX8rK0DWFSZAfnW/vZrcGsCOPiE9yKufv7l3N7/83qI/Op9QwJQ00r8wRytAypfaQImatL8Jjt4/Uka/v6weub896Fo//Dbmv2UcrL/kadI/eNedP6CmJEA9VTtAziEzvzyctL/uE4\u002B/6IO3P4IohD6xu0TAeAfFP5A1HD\u002B2ASPAFExiwLy4M8BaUv8\u002BnY\u002Btvp6UN0D0d66\u002BEnvRP2X4gD91Hrs\u002B0YM1v5zAW74Amu6/cNAYQIqZAUCT22m/m4QNwF7GmL4G9DdAdi5lQPlVfD4pYJ09HLx7Pt1vJ8DsTV\u002B/vApevwQ9zT\u002BmG74\u002B\u002BHQBQPqCPb//YWc/IdkIwJYu4r\u002BS9wLAUEcsQPHPsb8aDFs/yv/2PzioYUBeXUk/9FMewHUJyT8elqw/QLYNvXiA3Ty9QCxAURh1wIoVuj47rIFAIya6Px4WScFS\u002B7Y/Y\u002BM7vmAvibzk3jdAbR7SP0ZG7r7PdoRA0tn1v7djgz57ORVArxwmQFbnpj9503y/IPzkPp42u78zNts\u002B4bARwCy9IEAlkS/AqDAwvrIFG0AG\u002BeZApgtyPzjaNMBiHj89MKkTP5L1BT/JqRZA\u002BtlPP9sAJkA5aCXAK7PPP2G07z8DWw5AtDxhQPfs5b8nOUC/FEYIQKbRir8bsXDA2ozMv18NZMAFmKs/pINmQJKqO7\u002B/3LO/GkqawGfmoD/i2vI/ROO3vgVFQb43ywfAMxioPlZ8Uz\u002BiWee/uOiawPY4hz6wOUTAms\u002BVP0pQHj2UIoTANmXqP7kYHD/fUQnA"
},
{
"CategoryId": 15,
"Name": "Hydration Systems",
"NameEmbeddingBase64": "M8rpv0\u002BgQT6oq8c/UYdnPueQWj4fKrO/qAUyQArPjz\u002Bwhug\u002Bu\u002Botv3J1yb2noAjAB4RHPzKHhL5MMfs\u002BEe\u002BSv0s\u002BxT8ajlBAOLVqv6CG3j8h0yY/QBoHwCoUOcAAqR3AoYlkvypwn70dGxU\u002BsAinvSRQIL\u002BKTIzAamrSvub0gT6mQs6\u002BH\u002BEWvzDKVD4RR0FAj9mqPhBiBL\u002B97qu/bo/QvwKNzb5YyF0/fZ1Yvwm5jD/wbSO\u002ByDm2v6BeGMCYvbA\u002BoFxiP9PC2L\u002Bz2ABA7FKXPviLhb9ZrwU/VtBdPzxZqj62P60\u002BSP5aQHB3qr9deVHAYESdP9UzbD\u002BynazAku0XQKcJWj/8B8A/3A5fv9AYBj\u002BBN0JAM3qjPyScn7\u002BaC1E/Fjm0voThCkD5c8E\u002B6m\u002BJvi60KT\u002BusjY/MQfGPTqV8z5xKBBA8mo5wBgNHL3bAYq/lEmkvqtHGb\u002BraCA/\u002BjvUviTizj93lPa\u002BsvqYv66/yb2EXqM/\u002BoIXQBTW4b\u002BCI3y/sggiPy7PSL\u002Bv7Ps/ojLXQJgcij50W40/qpTIP6Ngh7/svrs82HfgvwFX/b4axrG/0CW2v0ByZT49Vwc\u002BDbl9vgrDEkByTki/lgBpvnhUfj9yLtW\u002BzWD3P2DQJL94X6S\u002BYP2uv0tFJz\u002BN7/Q/K5RHP/1\u002BIb7vfYI/fFOKP\u002Bx5TUA2MiPA1aXSPyaHPb/32qG/NELjvv4qvb/KqA0/60d1PjibCT8vDhHAWssNP5V/HEAJkCXAMDTPPSApN0BekKvASzaCv9CQF0BE7Ki\u002BrwPSvxL28L921FE/5L0Av5hyFD\u002BmO6o/au3MP7b4cD8SeZQ\u002Bi2PLPwL01r7tAAzAceKTP3/BsL8cuYe/2VCZv8ODlEAsSQs/ID8EwA\u002BNxD/xgRS\u002BUtHKPtjl5j6In2O97N8IQJ\u002BnLz5gsA6/mjQDQGdrCr8Jfmm/8qcsP2rwJ780tfA\u002BlvHBPnPpiT9ld6k/hUqEP5S0J0Dsu3C/WcOkP8kTBL5IJE2/gDNBviNbg78IW3\u002B/XkVnv4iJVb9C9NE\u002Bvl2kvrQ89j1ZGre/bZpsv1ZJDr\u002BTDgZAnV5pP0KbhT7gkMI\u002B6dIGQI4D2T8iUx8/gDR5PCxWW8ANe0E/YE85vVJO4r6Zvq2\u002BTMrsv\u002BF5br/Cz6I/BcYgQPUeXj9SMiXAWPXhv/k7LUCliTy/BBIEwJMHqcBTOGc/IkSFP8kpxb9cr3BAxzKNv6YCyz9NL1q/fSr/vxamkr2Tt/0/dai7vovUxz\u002BMxjI/vVWdP3jxH76OTrY/kCfMPoj1JECYi7i9EMyVPzSuRD658kpAOFXPvy5jK8BNeBvAJn6eQFqGRT8wE8c9YOBXPiT\u002Bmb\u002Bp7Bi/wJKoP1rvF8AVW6s/OOg7P9Ncqr6KoK\u002B/ey5IPpa3IL\u002BEfry8DRY9QDDiDb\u002BY47C/f79XvsBvRb9aZXK/p8\u002Bmv5i0tr8eJWC/5I4NPvRSFkCDF26/\u002BJxFwJgs5T8y5WU\u002BQObuv0QvOz\u002B0CYe/Id0jvwqep7\u002BDPOa/FoYQvgJCFr8mXZ0\u002BHJiyvx62YL8bvlS/EYEZQCWk079THka/L1ZHQKPEC8A3P\u002BM/6I1LQHTNzj4THH\u002B/men5v\u002BxSjD7qgsE\u002BpDXsv8PRHMDh9dk\u002BdGN4Pw9quj\u002BfAwc/oskpv57XCL5UUAi/WV/fv44NKb/c7Z8/OvLiv8BIXj5jA05A2S\u002BlPxRL7sAblkG\u002B7denPx4YGcBUQQ6/\u002BlKIv5zg8z/Wx9s/rkbfv\u002BpYAUCdcb\u002B/PJh2PyZCor9dgYg/NY6WPxjHF0CuxhNARI6rvrBNUT\u002B2MRjAaaSWvn9vKD/AL65ABvBwv39\u002BI78m9TBAs80Yvm6JI0Bi728/UO5DP2g5b71Vtdk/XNGFPwzWsD6Asqu/pyMGQJgJGj\u002BaSwe/RO6tvcARZz/iTXe/jKRRwPRQwT2He4q\u002Bv600PwLiX78ZJFg/IXCjwJRtlj8GA7Q\u002BgMtNv2aNJD5dL3k\u002BX7tkv1HsFkDgWKI\u002BFG30vwUIMMAgivG\u002BhGYwwAB4ijwLrg/Arnn4P/FYj76ncgPA"
},
{
"CategoryId": 16,
"Name": "Snowsport Gear",
"NameEmbeddingBase64": "eLaHv4QlRz\u002B9IgFAGmiHv7NLAEDA5bY/l5wkQGVleD9dGD7AvsxXPx2lGb\u002BvTzDA3GwaQM9OqD\u002BrhwQ/qrlqvdpRGUAUU1M/LZYJP8cbTD\u002BENhY/6JajvyDTjzt2v52/iIwAQNk8oz/yDwO/lwWfvpGl\u002Bb8\u002B5GbAqHxuv\u002BBYtzwehd4\u002BakEuv7r2G8AMJxe\u002BiKSvvpH2Tr9d9h3A9KMSQEBrKTy65ak/FyFCwOQxEz6oBM8/XZnvvnmSqD4sIFc/cqEUQJdXGMB8jGs/GjfsvyaJBL7w9ga/iG/PP5i1OEA4OqY\u002BlNDJPkQmKEDdH7Y9DwwEP1gNej9ExOHAag/RP/qE9z5ASitAT3QMv7iO\u002Bz99boU94N6qvVjeAj\u002B0x/E\u002Bbj5hvulPG79yvKy\u002BUMPgPlNznT4emIE/fkjCv7Z7rL/TlrO/rqiwv5SpNz9jbLk\u002B6PuKvm3kzL4iyBi/rGzcv4727D\u002BAUYY/DmA8P1bwQL9c\u002Blm95bVKvn4bMcCYFcY/UEHtP7R7Cb9f0jY\u002ByKYIQeRIKr\u002BVLQk/JMMvP/7r7j/qORq/Qo5\u002Bv/AmxT7MTwG/XOIBwDsror7JJi9AbtkpvR5pwr\u002B41WE/0w13v4Rmzj8xoa2/JzpMQKDQyb7AKCNAtMVawAxs\u002Bb7v/Zc/gCySPFn2oL\u002BpxUq/zqw\u002BQEqSRkCWvcu\u002B3vJbQKycij9s2Q1A65vzv\u002BbMIb93QQtAf41ovw6zRz5k3/i/ffQ7Pqu//z8kjQbAMzMBwPCiMEBA2G/AdoEQv/AceL6\u002B7ljAA92Sv9BbUr\u002BdHcO\u002BzqyrvaI6cr\u002B\u002B9RK/j1SwvxWZIUAwvvM\u002BOG2iP767mj4LGay/eprhP97rXz5ufYo/gPyNP4Y7Kb/Hh4S/jXFrwMEF8z9cjUi9rOh6v8DL775MmMi/2KcXv571I7\u002Bq0XU/fPA/QDMPeb\u002BPt5q/uCpAvyzNxL\u002B\u002Boyw\u002BzTrUPtCrIr89TNE\u002BcLukPdRC1j/IwXM/AKHEvyUZBMCTzPc/J3adPw4JMT4VUbW/51geQJYXpL\u002Be5yO\u002BRttEQLa/X79xjpu//p8fQEWJUr/vOx8/fKiKvy/woj8bcva/D/BVP2/qcD\u002BfE36\u002BscoNwHRb0b8mC0u/eos8v4YWGsDhJum\u002BIsA9vywvG7\u002BUPDW9p/iVv1hIXj8QZ7y/Y4LSvrRSwL7IxMm\u002BFz9Sv5zIvsBSW5Y\u002BJoI0PraaID8h5cg/CGgMP\u002BxdCED4HT6\u002Bpt8nQOSbTD\u002BHnLBAzkcqvVKZmL86Jgq/94uxPjrF7D5wGVY8LEoKPu8M6r4KMy4/iKJivrQabUA4sRnAcGAHv2a0nb/mgmy//HWDQDIpYj9DYBxAq0oUwHz0fz/rpo2/om\u002BePzQ6HcCRee4/7n/WvmsoBUC\u002BT3K\u002BtqOqP9pTmT6kjXE9BA\u002BZQEWrRL8MioS/\u002BzGSP0oIEcAC56S/0aF2vqIVDcBs\u002BDi/tCtHP99l8T47A1BAXrlhv3vWoz/v3hTAeP\u002Byv5MU7D4ZMxZAuittPt5cRT9uJW\u002B/LDVLv36bAMASBec/ZvWhP3NQsr6u3J\u002B/ZE66PoqExL\u002BmoU6/sQUrvtmoPT5qT64/lepxP3uERj\u002BHB9Q/zrPovUMYDT\u002BoO1i/GHY9P6SyHsBPnhI\u002BGVvXP5NvP0Cp8ZU/jPU7vx8aMz\u002BIEd8/HH06v6U8g78HrFQ/9ByXPyid27\u002Bh63ZAL0jgvgbVAcG/DbO/WdZ9PzIpg789IIm/YoIFwOx3JL8AKWA/\u002BFElwPI4Gz9nwuG/nTCtP7hocT/L32Q/lCV8vwIzaz8VIJE/U8alv37yHj/jVh2/kJKFv3b3CkCki55ATnoYv4\u002BU4z\u002BXaRJAkuGdv2hs3r5K76S/To2oPxYHAEB85SC\u002BqorBPzVKCj\u002BW4o6/jPOGPxvTzD4qeJQ/QZPIPhAO7T7oFUu\u002B7qgDPnZy7r\u002BBaRY/qy6lPjb1sr8caGk9dbA3wH\u002BnSj6yvEA\u002BkefMvzl4oz56PhbA9k43v\u002BV5Ez4zoznA\u002BIvWPe5a378Q7Hm/oDYfwIDACj1HtU3ACnFvwMJQxD5ERbc9"
},
{
"CategoryId": 17,
"Name": "Off-Grid Communication",
"NameEmbeddingBase64": "sHDrv0y4QEDOtis/2B31vweIiz8JL8M\u002BOctMPquFrT8lAvC/puBbvzvE/L5kHJG\u002BQXUKvzx25D/8IUg\u002B3QsuQP26hj9fY4w/PduRP36toz9W9gdAr52CwE6K7r\u002BzCSo/IuAYQNLktj7eERzAnYCpv0MH3r\u002BE85vApaCWPoRhRD6q4d8/hv4dP2LLaj/yrgO\u002Bc9UXv4PI2L\u002BBqZfApwteP9qqWj8Uf7M/uPyzPmWgQL9\u002B/4q/mTg8wCf7Z770xrO9Zs0YvhjhYsCIY0g/CK/hP8MRY7/m6pU\u002BMrQWQLcF4T\u002BmsL8/DDmuPVkymL/rxbQ\u002B1vC6vhqnrD/A0NfA\u002BAjpP5Z1nD8Kcsy\u002BruUzv\u002BKbUT\u002BAROk/d/6xvvB\u002BSb455wi/0g6mPrN9yT/efuw/IxPCP5tATsB4YhA\u002BI4kZPt8wXr8P2BRAbklswJwGjD80/YE/pWSwv5wqwr/QkDlAnH0nv7az0j6UmAO/EKAiwD3LJUDny6c/ZuJ7Po7OgcAeGiu/rPqYPgC5X7y68uq/tK/6QBw3ab\u002BX7tW\u002BTKBKP4Cowj5fvcK\u002BIMsxwOE6J7/jgNe/5Rs/v6Qqvz/szKe/lAo1PztR6r/dQ8A/xOeJP5p5gj7IB/M/DsiCP2ok8L5mpYU/rl3iv1k/EED7SoM/6CBvvKr7Q0B6PoC/fMo/QG4UK0B\u002B/4e\u002BmCHdPqZVBD/3xpe/7Lj1P0T9mz8qOARAxmbAvdfL6z\u002B3zac\u002B5lRQPx5TPECaqbI/Jq0IPjBREr5LdYnAA4U8QIqIPEB4wTG/xqc8P8unDMByoV\u002B/cLidP2Cjuj8xbEtAk1Gtv\u002BBciT5kgpg91WsBPy9mpT9bGu\u002B/KzbDPwDfgb/KHG6/dxwtvsCLoEAu1PC\u002B35qQwIxWdD0VMKY\u002BFaoYvi6VqL8cAvC\u002BWJadvkwp2D9vtSDAOmQPQMLHecDiute/RCO/vdMU578Pk9k/6Ee7v3rlL7/CChg/47/NPxS3\u002Bb8MCsC/cnurvzR/Tr0ghcs/AMwxO\u002B0UXMAx0O2/nwUsQJIWjT897xvA/ae4vw/jkL\u002BW\u002BCm/NJjEPehKtr\u002BRjGQ/wcF5PqGEB8BktpE/sX9nv8gSAz9QooC8XewfP66Vwz/MbXNAHLaFPTgPLr\u002Bm9ylAR0oDP0OEvL86lUC/ItoDQGpGEkCScoe\u002BHDF3P7KgfT/ArKu/KWDcvzwaBMH8ts\u002B/ygP1v4Cb679Utja/TNcmwDy1FkCXhKS/rlhmP3TF2T9OgmFAE9tzPw4w/L80PDs/6jILvdwb\u002BD8KE6C/2srjv4wuob\u002B5lHi/kvLwvcODXEBoLuQ\u002BXg1AwHihQj2p5QW/OVK3QCiwYj6YN0VA8pfePpK16D\u002B0Lsk/JxICQD3PS8CMjY8\u002BrngjQHQOrz\u002BG36m\u002BmZG4P3QwkT9fYa4\u002BXl5tP\u002BCaoT5OGjnAEVUAv8/1nr8qpoq/T/pQwGmi1r\u002B0Bw3AHzWUP/Dt4r/iLDZA7HqYPxZe2D81tYA/VN3cvz269D0UF9a\u002BWfGdvxHh3L5TXho/KNmfvwPeYr9xVd0/J23yP5eKBr9L6VQ/H6i5P167Mz/n1FQ/g/Z1QDZMfL/kkJE/gk0wPtgkmr5xEMM/RiEAwCkDJsBCLgXA8jc2QGZs5r82oLM/SEG2P8sgKT5ImcA9l52av6PA\u002Bj\u002Bh8wa/tdG7vnewv79mCsM/uI6yvoSLK8DGc4FALakGwAIbAsF0kIu/4ZCIvx5smr8P9MS/RtqmP\u002B\u002B1Gz/jikRAS31IwNpZzj8M6wPA4BCkP9iI4j0iM0S/csLPP3HpZ0CSQCFABeQawAfDcb/uW/u/rjcaQA\u002BkzL4Kn6hAEFd2vPRB7z\u002BGP7m91b\u002Bnv6Bg0j8FPjg\u002BKuefvxHLQz8MjIO/wNL9P/8tzr\u002BNWXo/0CA6v3TTNj\u002BgziK/IKnlPbn/ScC/MQLAcH3OP2g3AEDGyqy/DogJQBznHb4Ku9u//dcrwNS/1D8Mc5a\u002BuoFMvWgYjL2O9y0\u002BKa5oP2LCXr9jSPk\u002BqCeuv8WdEMAgkzk/CiCsvhQ7XD99PzjARtekP33wm7/VToA/"
},
{
"CategoryId": 18,
"Name": "Camping Shelters",
"NameEmbeddingBase64": "\u002BnHJvimc1z/iKL8/WAoePkMfCUChYgxA6\u002ByqviZJ0r\u002BZqaG/6alJv7If6T6uSJK/0M81PnfuBkDGhAZAhHntPmMpRz\u002BgO5k/aMbGvqo9AkBS44U\u002B4MMzvjx4l7wceoi/tGGgvb\u002Bnu744XGq/Yq1pP1xtUL9IcrW/LhbxP4Lu279auuK/dblxvvBXSz\u002BNlMY/Z2kvP5CvE77AXWy/wk6iP7jqGz4QXpc/wdyDvkDHAL9zVc4\u002BRrHovhWRcr\u002B06h/A7PWmP7eQS7/I2gA/5vhiPl\u002B3ET7qZey\u002BZOOoPLRFH71ULgO\u002BjDfFPjwLDT60F5k/Wo9EvlyJjLxFT3fAHviYvuL\u002BUkBtpsA\u002BpNkFwMWz7D9P2ZE/orIgPylJdL/7XVk/3JQNPxDNjL/8dto\u002BaBRhvWoSeb4P03g/zBv3v1A0WT0yiDPA2YSHv25cgj\u002Bu7Ma8KsmZvlt6gD\u002Bru4I/pPacvwQvwT5AZ/w/HExlv7p/9r5BSgu/NRh5P9ZHM8DI9wy/lnGuPUXBJr5OUhbARQbcQHhbmT7qnIc/1\u002BQ9v95izT2Ml4W/XjE3wJ1HK74XEse\u002BupKbv0QDfr6qLPY\u002BH0SNvdBA3r4mT\u002Be8mvISv2iLLL9Q4YA/O8jAP93R\u002Bj6KzmFATCiHv50ed78Ht94/ZlZvv7nZ6T\u002BoE0g9y3cUPhytCEDCWKk/N4q\u002BP2WsiD/miiA/sC4fPXm3Kb\u002BF4ze/HpUQPxDtnj0ElGG/k0kzP/Djfr838w9Aw7zHv7iS4j\u002BAJ4DAcHkqP9KGD78iaTq/pNupP1uw2L9WIe\u002B\u002BFKNQPzyXzj6i6DBATVQkwIwQBECAXMw\u002BcAO6v3YTej9nf5I/wiW/Ps7oTT\u002BWzZo\u002BMnrpPqh9hj9QUUy/Blzwv1YyEb7I320/chs/vqophr\u002BeZlk\u002BDxMnP\u002BgTzj\u002BfgSe/2GnFP0RIt7843/\u002B/3OdfvzPlwL/gKAc/fvMpvxFcdb\u002BU\u002BwY/u1sVPw/KE7/qoEO/dds8v7KsEb\u002BH844/bOlSPe0O479DU/K/ElMYQGsVBMDlwJe92LpXP31Lhb8Ug1i/KE\u002BnP77Pvb9mXCdAuKzwPjlolr9q2lc/yI7APyJUrj9ErvM\u002BnBgRwPQsND8tD3I/DgObPxjlhr6DnYW\u002ByoGTv0oQMb\u002BGkpg/K3CEP2miMj/m78a\u002BDRgzPkP0CD9iKEPAJmnwvwZZr8CszzQ/Fl2IPzCNjj6W1lPAMIeFv808ND/v/N0\u002BWtpSwCDT3b68a5xAln4twMgDBD2dENk/4rMlP8Qzrj4gRPS8l0fKv4Pmmj\u002Bd3pA\u002BMXLhviIMVD0leQ9AcQQMP6Qfizx4YKm/GttkQGmvxT9y7s8/tFJVv02yTT9Ihxy\u002BpU2YP3p9VcDPYNY/vlkrP8DcA77Yxek/rOGLPxhHdT75nSm/mL2SQEW2H75SdgjA\u002B4SxvpSdnr\u002BIwAK/ECj7v4R5mr/Atbq/qBdyPzDHIb9cSR\u002B\u002BdIFhv\u002BO6GUBbKIS/NWW8v47/Vb9yXFS/s3fKPxoYPT\u002BpyVy/RzcSv3KZjr41yYY\u002BkD/dPlelib8jHdo\u002Bfd\u002BbPng4MsDkkVi/yjYNQFhRgr\u002Bkh6K/wYYgQJLXBr62nha\u002Bxxh2vp9FnT\u002BEzNu/QMITv5bE8j1kLn6/fFeTv2LIsz\u002B/5R5Ap6cswOcyCkDSy4e/QlPPvpiIQj4wNWc/jtHOvw7qZ79UjRZA/rhHvqKDvcD3KQw/nDpdvgF7SMCiUa6/cD/sPKgxX77ZgSVAPZ65P1i3VT5UNDs/038nQCRMSj/DmJ0\u002BytZiPpwU8D6Wr08/3QOyv5boSj4jV/C/UBo6PLkbD7\u002BWkVNAuIhOv7C0ijx7Ncg/PwucPlRccT\u002BdqaI/aE05PhKkCz\u002BhCe8\u002B6NUQvkqgU7\u002BJW1A/ylvcPkjckT\u002BENku\u002BQKaZPx7dib465AfAwIK1Prrzpz9\u002B88c9OMxWvmqgxr/yqq4/2WQRwFghFECH6pq/hAHavyYNQb5kZY\u002B/dO3fPgiSvD2vguU/c0yFvlrlXb\u002B0SwW/9nX7Pun25j7k7CK/QWUuvt1lI8AySto\u002B"
},
{
"CategoryId": 19,
"Name": "Outdoor Cooking",
"NameEmbeddingBase64": "\u002BF6hPa\u002B79b6NQOE/vzQMv9opoz\u002Bt1Y4\u002BiDzpvoRshL9Nw5C/9p\u002BDv/7tcb\u002BPK4q/3TMlvrakZD8ZqtA\u002BfLHUv2pkmz99B8M/OB5Av4qJ6T2TREw/hyOAv7V2u74yWLW/JvpoPY4Ewz/rrL2/dyiDP5KRRr98FSLAl3dSPgaMXb\u002BFGY2/ZFmjPYCc1r\u002BCeZC/AMYUPzS01b7ELQXALFuOP0nTiD5PdkU/GIqDPSaF376No5y/T8o3vnl4d79JUdW/GML1Pw7Gzb143SW/hmDEvcvQ0L/X5iy\u002BdJW5P/RsuT\u002Bcwz4/HpnyP0t\u002Bzr4WGhq/sIiTPydqtj\u002BcJo7A0weFP/BxcL2a5mU/2Jt4PYryCUCaJGY\u002B0wUlv1gn0r6lUe8/GP/QPzXKID\u002BG6nQ/IJyYvqRJ\u002BL/U\u002B6e\u002BFd85wGNihz9Nr3I/y69vvkSkzL4L4wM/WPqyv8Pz3D4VXdM\u002BB8uEv/1OB0Cq4ABAoMYYPEtDgb/6fxu\u002BvDlWPriNxL\u002BZMAS/bHpYPwAbhr\u002BQRS6/6iXpQLwjNsA8vOY\u002B/PO8PqB12Lx21rS\u002BPFsHv9vBo7/ImZC/8Jyuv\u002BbqM79IWxc/4LFRPOgYDsCRXo8/Xtr3vixOKr/e4xU/I7mDPvFlz7\u002BAsws/QArJv2pa0j5q/Ic/20VXPuT1pz861d\u002B\u002BeEmGPnCEHECZX4g\u002BsG0XQCYGKT\u002Bjesa\u002BbiCDPnyEx7/gDpq8Uai1PqJI1D9HC9g/UyKMP3l8jr7CNxg\u002BAlFWv05o6T9OvkDAOLpNQLNLir4Awqs6wMsdvEA0l7/oIUu/XvIGPz82Nj\u002BUQJQ/2CcVvtNTA0CpX3Q/9o\u002BjvyuNgb5gkoK9xALkPoIxxb46GhY/UuQeP2CUY76Nsea\u002BvxuHwAhvIL/slCI/fiQhP08QUL8fgcY\u002BvtXhvtoLFz8aKJI/GFKXP9Kehz\u002BgsUDA0drBPUyE9b\u002BM4/k\u002BRG/BP5B6bT6V\u002BhQ/wvZUP8S6pT36i2e/TNoBwAPLmL8MkKi/9pEvQEcl9L8yf9W/wxd/vzZZzT67faa\u002BZQNjP9Ra/z2JOt\u002B\u002Ba1nzP2r7nr\u002BKzQFApN8EwEElWb62Zii/gL07QEjYiL8eI1E/4rOsv7MRTj/zffU/aL36Pspmrz7Ujqk9s3o8v3iSOT5Ido0/EivGP2XMGT\u002Bh5vQ\u002BvQpjv3atLT/PCobA2L2hvxJud8CGdhLAqoPlP6f7cr5W1ho/mKyNv6baor\u002B\u002BQAy/8I1bPSmgdj8K\u002BQdA7AgdwICvwj9S/W0/ua4BP5qcwj99h/o/HSGVv6T/QD4aPoo/BLlDPySAnD6RCg0/m/mOvrEimz/e5f6\u002BsEx2QFaeWD4o7xJAyP\u002Bqvylsab\u002B\u002B2jU9GPlUP3U7JcAALIC\u002BMIynPpJm3z6kmge/1vUEwDIp1r/alHQ/XCkdQPoIUz7A2Fa/rLpfPfBPt79y8S0/rEjVvwYMdD9YQRLAwFspP8gwyD/alf8/Gconv9AjPD\u002BixF\u002B/Gzuev9Ncjj8TS06/C1q1vroFOD8xA0W\u002BdL7WPjAlmL99BANAQX0ZP\u002BXPU78vrh6/cXgXP889mD7S7Na\u002BEkQjvx46DD/m3Pa\u002BKudIP7Irwr7CNtg/v3cQP4/WMD/Y/CrAlQ8lQA6hgb\u002BVi\u002BQ/PCQ4P/XPtj6IrlO/RjHEv67P3z5q/Dm/o9ENv4TrUj7qtwG/dqMQwNDEkb\u002BBsmFA2NtzvU5dycA1lw4/GXF9PjDdrzzomtA\u002BNc1kPvi5jz2fC0tAETSwv6VMyD6Y4wg/BIhnvs5YjT8MR\u002B\u002B85WANP3hj2r66X4i\u002BF0lgP0b8iz\u002BlJ0G/FG7hP6qNJEBEAD9AqYmtvvSjvD7g0aQ/AJzlvlqtl78zOwi/8BiPPCrQrj8cqkC/s8/EPw0Ezb4uxu4/TVEDP9L3aD9S2Ay\u002BSuhlPlQTlb9Y/pq/OLLYvRQCfr4VIfo\u002BfbSQv\u002BJTS793s0c/jUiFv0BgZb8e2HM/CbNJPwo\u002BQ7/A2gHAas3UPmaCwb5CNAY/Dm2Rv5QHqT6ujdS/dHeEP9ugnj8nBErAuxv/PjqzTL94\u002BqA/"
},
{
"CategoryId": 2,
"Name": "GPS Navigation",
"NameEmbeddingBase64": "4O2QvG0uyL2DQyRAls0IwAEwfr86uL\u002B\u002BpcwbPwqMjT97JCC/qac9v3dRgz/cywnAGa4pP9LI\u002Bz\u002BP1w2/21HFvyfVWr8G9cI/awgYQKVAaj6Bk5s/4PBSvTAcr74sPVK/Zrorv\u002BuCUEBI4dO\u002BsoLMv8skxz2SKWnAJAp1P6BE978Dxx8/KycBP1xLNcDKMFc/4EnPvllpqD922uw\u002BskccPo/EA0ACOBw\u002BuM73v3o1Dz78D6O/6hG9v5KjCz/QxRY/ogcFPy2FiL/hx1u/dkYvPiXKlb8jXJE/Cq6BP6JV8T9w2TI/gkf3vn6m575/240\u002B0DyDP7bER79IRcfAUdEwPwZuAL\u002B3DhU/MktVPY1h3L9a6ri/kufpva4Maz4v/e8/5\u002BeMv3WZ7z58tvY\u002B42BHvYq1g7/sUNA\u002BvPxyvxhpbz8MFEg/EsXqPyy/MD/V9dk/YvJJP67G57/h2G6/4sETv5Pomz/iQom93ODMP3Kzmr\u002BGCcQ\u002BrI\u002BaPlJzib/07VG/IvGeP\u002Bz6jD9A0nQ/kibbQLlnMr\u002B84RZABLvoPZO71j9tmGY/D5WBv17aiz7kL/6\u002B7iOQv7tZgz\u002BntIo/XrIsv17jUz/IHI2\u002BrJsgwBZH1j8u7ne/GFooQBnytr49CRg/4DkKwMM7nL9hRT5A4HPJPk8KGkBJNgK/5rvrPyL\u002BC0AonRo8bEOpPxny4j9HPIW/QLelv21ZxD/NcR\u002B/h0KYPtHpmT8pFs6\u002BxMCTv8gC3j6\u002Bix/A3xTPPkfJB0AY\u002ByPAsGOgvn92SkClhXS/6uiRv/TUQz\u002BiVdq/K9C1vtZf8r4LcYI/JKQvP\u002BWEUr\u002B22Us/NiG/PzShPT/pNV/APY6pP6SD876GPxe/ATJ8vy6veEBZNq8/MA8iwH5HXj8YJJA/q8sRPgvW8j41TWw\u002BJRR0PjOfbz4H7Zw9F2EXQNJ7Xj7PSsO/wPKTP94/Yr/gXLm/eAiWv8xp5r\u002BUxEu\u002BsfXWvhBCIz0k5Mk\u002BNGSNvyQnKL\u002B4T7K\u002BH\u002BZxv5azCUCsprG8gHjlP1J3jL9Pc1S/Yr/WvhS31b/fzsa\u002Bh\u002BuGP90hlb92mr0/iuMnwEBI3brbIk8\u002BILrxP83KMr/xU4U/9v2tvx/gtL/hnwpAPGRJPy4HrT7WLkg/fqXdv0Desb49LALAHrLdPoBj8j3glgXAAtXLPzRnLL\u002BgSgs8m1Ohv/w\u002BscBfKfO/OkqVPikwdEBqwfy/mjNOv6/lLL/0jPU/vrO6P\u002BIEEsBuUW5AwrDtvV7eVz\u002B\u002Bdds/\u002BDKgvdCtJD7SOUW/MHeMP482dr6OFfm\u002BL6ryPvgCHT8lZtO/RhDYv0Pgyr58nTY\u002BAottQFSPaD\u002Bml1g/FJpmv6ZohT9E9qe/qb6zP6ABxr9gs6M8YKCIP9QasD88qqE/MTG3vu4\u002Bzb9kePS/9X3JP/g95T\u002B1nYM/Qd2bvgzKxD10OqG/9bOpv3H0lz8UCGs/fvsfPTnoSr9SbBy/argFwM6AAj/Mabe/haOEv14jrb8M7NW/3FyFP9h8kL990oS\u002B/usqP2MwTL/LL\u002B4/izulP1xHPj94H6A\u002BB0jBP/Dnuz16S9G9DK/WP\u002Bzq9r/qOuO\u002BIohXv9qfBMBBfSRA3kkzP/CxyD8MneG/G9ftvzFkCj/0\u002BY09NoSWPwpCar/RTKG\u002BWlCDP1amS7\u002BzehnA6vKcvyBGtL2Wrxe/FcVWP7T8a8BUlhJAh7GUvoRGr8DAtZG7u1MtvQDfPb\u002BCKOa/HLqqvzLEnj/o8GI/D\u002By4vxsIp74k4FW/Ri6WPzJArz2IguG/9CzFPfvZDkAF6xA/iPUIvvNzYj\u002BqSvW/rjf\u002BP\u002BcJ6j/ORW5A4isMPuC76bobl9g/\u002Bsn2v5a1xr/AEd89ps\u002BwvlSQi70xZBe/hDAsQLxPPj\u002BqXwVA4ZspQCehAD8NFEE/5Mcvvz8dSz/QHJE\u002Bxk1FP4ry1j9w72O97LU6QLFStb\u002BgyY6/YwlhPjhDnb449uc\u002BUF6dvt9nib9ala6/6I1tP/4qjT3Qm50/PxX9v6TErr\u002BDTV\u002B/DCyhv8a4Ez\u002Bv2CXA2vnSPyjGIMAGF/K\u002B"
},
{
"CategoryId": 20,
"Name": "Snow \u0026 Ice Gear",
"NameEmbeddingBase64": "uWA0wM/rgD80CE9A/tIPPrxzb0AUXKM/K7ohQDBBBT8DShrAdHZfvsK\u002BhL4VSYa/s0xsQCO6QD4FxLc/7GmgvrAu/j8FNhE/jZQFwJNBHEB7Cqk/rt\u002Biv6yL/j5Fgri/pHk6QNqoCkCrHBy/uS4nv4bqwT3334XASHQyPdJ7cj4kbb8/R5Ijv5HkNcDn1q6\u002BqT2xPhSuqb/chzLAF0TlPwzJD73g7gBA5UkMwLXZCr/gyuA/B1wQP1MC8r7z6/s\u002BHUoFQMeem79SdeE/Rimvv\u002BkOdL8aFzs/eegBQINhbkCk3/G9Gri/PY5P1T8kYSg/pSVSv3jSjz40FtrA1CtkQNMVYj\u002BFIE5Ai8Clv2qL\u002BD/CplE\u002BgQKCPw1G1r47KRlA1lgFP6x7kr4c95K/RqAwvh8h6L8YkYw/2ACTvz\u002BdNcBxQiDAmB6qv\u002BzBMUDHAi0/\u002BWhGv0Ikkr4wJpO\u002BR1L4v5g9tj/fciQ/rEQ0Pw9ZWL86Mco\u002B/ETMPx3ssr8t5RJAtLfrPxkI8b5qIfE92R0XQX356b/etba\u002B2T91v0TBTj\u002BaCHu/KI1rvxhhID8N\u002B8u/grurv9CsEL1ipR1AegOTv/C/8L8k6VY\u002Bx3B3P6D7Nr9GgVU\u002ByLtoQBPOiL9FQ64\u002Brt\u002BFwCE2h76J7ANALgdtPwJKNL9mDAbA0Z71P0glc0DmNQC/ulknQMa3yj8cMFA/v16UPubpm79Ocpc/unFevt/aer\u002Bm9jXASLBgP3i1sj/fOUO/wECyv\u002Bs8\u002Bz8jvYXAaOXQP6iLFj9ltYvAU7YJv0zk6L/n97G/NJLjvr6YBD98fwNAtuonv8MvpkAYAaa/E3UfQDiV3r6i6IW/VdCZP6p/dj9M/aU/q\u002BMZvtpnnj/XE/W/evqGwKuyBEBQG1S/6W\u002BIvpAqrr5Q3AO\u002B29BxvhgnU7/x2AI/aJSVQKOPD74sBijA\u002BBVev/khv78wk44/9Pc2PoGdib5j/p4/o/fTPl3G5T\u002BfUY4/zh8qPxRYxb/EfqI/WMCUvYKsPT9nlqq/2hKJQDg7uD5jYIa/BwkEQBI3qb\u002BGX3e/llEfQGc5HMA8k0JAbHmUvysb1j69IxXAzrstQNTKgb6SNDy/DlEmwL9Zqr9EF5I/6C/lPNH46L\u002Bq1uO/gIQIPllP\u002Br6AoHI82NpHP9DDMr0AwFfAyjEFv9lnwb56nC7A6HECPuCD/cB1ZFQ\u002Bf7YcP8mrqr8P\u002BIY/OPFUvykNX0DBCLi/1Kzqvf0arT8ogpJAhlbMvwb2k74pFw\u002B/aIwPP0Ik7z9dIb09wXgAvx6QyD/7EZw/jT8HwEAAYkCjV9G/lTvPvkgDxj4t1ty/bD3SQBZfLj5LZs4/3Nfxv9rPGr2pJkO/iEWYP8ytjcCY5wRA5jhBv3Cbbj9MrIo/bz9Fv5eZjD\u002BC82m\u002B\u002BWapQLi4or\u002BltH0\u002B9FATQGheN8DMQ0m/1iWsPZd6RcDO\u002BWnAZe\u002BBP1YYpb8oTApAEUD8vy5nP7\u002B3SiXA/7XKv7vc6j9gKlU/1pp0v5eKJUC23Oe/OCC9vlqqIsBU\u002BhZAFgMrPzolH782XWm\u002BS2mEvqLjEb/LUqe/7awOP8zb6b50Z9c/HfrvPy70pj8s96Y/g5\u002BjvxKV\u002Bb5Flpm/TrlAPtxJUMAsGMo8WA9sPiMdOUD85eS\u002BmMGtv\u002Bjwcz/9dd0/7Vriv71aQ79Zeq\u002B\u002B3T0AQE6qQcCvPaFAejEHvxcGFcGGhyu/\u002BC4dQDScxr/eTRPAiYDQvwNHtL\u002BX/oM\u002Bm4u7v6f2rD7cAwW/enjnP8oAiD8xCX8/DrSfv6gF3DwqdvI/YXT0v8i8dz8qs\u002B09yLFov5q5MEDWjeFAqk8kPtCg\u002Bb4\u002B6cM/a5SGP\u002B4U4j/8fRg/jbnxP2mRGkCETLK\u002Bz5njvux8Qj/HeZM\u002BTCI7QMdY1r6EouM/I2WwPwkyEj92m4m/KG08P/Jenb8cE0e9rsrmPVbAQsAAsRQ7cbF4wMVQRr9qhdk/cderv2VYpL7IGfG/yzYFv6vbjL/e8i/ALhdmv6wCm7/sFOW/MsBGwKbDjD9nZlTAUDiYwFpAAD96EvE9"
},
{
"CategoryId": 21,
"Name": "Emergency Gear",
"NameEmbeddingBase64": "Pozsv9LkXz/MPXg/MJlDvZg3NUAotoI/TIUiQHLv3z8Su\u002B2/vap1vivpc75m4sq\u002BLdJaPmBbzz9rb6w/lun3Ppj/FkB2uai\u002Br6irv7BmFkBvc5o/ryMLPwoEFz4gsIi88zOjP3ycvb6b/9I\u002Bi2N1P54ydr8K/13AYtWXv\u002Bee2D2sbcs/Qv6\u002BvttTWr4K/WY/Qh4WPpBA57z0772\u002BWYEPP7565D4ozmI/qJKmvn7N5r9W8\u002B2\u002BsMLyv2rZcj/y8CC\u002B3C1nQN7aOsANKDxAjNX\u002BvhPCuD5eGQY\u002BUtWkPiTf1L\u002B0zVe\u002B1L45v7SW3z76s\u002BU\u002BXqVaP/DrsD9mGm7AtnGhP3wBnL55s8Q\u002BxJzkPuayGj8L3/A/1FQ/v1S6s79UFM4\u002B7jcHP/lE6z/HtC\u002B/XOJRP5fPoD90YFq/ImnCvkSnsL8CgyG/E5Xavy4dlT5ggMY\u002BcV2cvudWXb\u002BbGm8/ygCWvwpaC7/b9bE/ashhvxp2Sz/CERw/Vo2WPyVQSz6yCOy\u002BNQDOvtJQiL\u002Bi9sG/xrn7QDTC676EbU6\u002BPi/IP8laHD4eF9M/fkYqwDh0hD98wrW/a7a5vwCOsz1sFJc/SkVovzbmgr5PpGe/QLngPkRiXT9t0pO/exbXPyd1Pb/8aJW/TkiXvrRHbD8ECuA//11iv6U5Oj6sCU2/Ok0dQESUNECKCLu\u002BPCfMP\u002BKs6z5C2E\u002B/hlaBPpa9V7\u002BXbTM\u002B0emmvuBaNT8PcK\u002B\u002B3vaiv4Wu4D\u002B2ZPI/wUQMv2T0871ecXLA1p8YP1g8hz8B5a\u002B/\u002BIYnvm2b674GfdS/QBmdvwbblD7yRVE\u002B1fGmvg1BiT8duUY/9sE/QCKQ6L7wh3C\u002Bzh8avzEEsD6p9Ym\u002BvqJevx1pEEDoWfm/bHMSwFYwAT8mSYm/oydMvrsuoL9r5IS\u002B930AP3yFGz9KPMk/mltSQHz3Aj3E/uY\u002BFLwZv/5yo78a6G0/hK3GPjiSz7/alKc\u002BEUPuP4C2FzsHt8E913yBvwaOmD7bqCk/sxPUP1RZAj6\u002BpTq\u002BlnAhQM4TDT88JZi/gST9PhMruL9tBhe/l/GLP40NAcC\u002BKJo/dPfvvi60DD9bN\u002Ba9vFPLPquKHz/YgZq/L/ZxvvlkKcA1O4g/JlknvpEUa7\u002BWeglAome0vsw/U7/MZNe\u002Bb/HAvibuAEDndIq/b2kgP6HFbD8i664\u002BwRTjPyQIrMBBVSI/g2MhP80YsL5M3Kc\u002BbSsqPxNVqz9p5UK\u002BGedivyEyGj8AtElArpygv5D6xr442Vq\u002B\u002BCUkP62PJkBsuCM\u002BAkUUwCFpbb80xmU/sDyfPgSy8D8m/TnAzG9zPyiPXL\u002Bo0K2/Of2DQCenLr94DBo/uIe1vzK0wL/kW5g\u002BHB7/PyxpGcBWS1I/wHj9vjK8cj6n1aI\u002B0Ggov/jR37w5YwTA8G3jP65heD6bF7G/MBeEP0iV/L9t3KW/\u002BtFpP/\u002BzAcAsU6C/EGvUP7dqPb\u002BBTBE/GfuRv5Dmnj/x//m/bUG\u002BvvO0Y74piYW/vyjjv83U5b68WYa8gG8cvwjzZb8qMHw/Xv\u002BSPjtxlr8ZVre9SoDavsrKH8AKShnA/EYEQERazb8Book/dw8MP4S7cD/SJLg\u002B6Hy1v/ibMz3rqRK/EcRPP9KHb75ZG609fBPRvlqWRD/531q/8Mfvvr9I5D9xhc0\u002BSDZrPjyYUb6U5z2\u002B6ukpv6I1g7/8\u002BRJANX6iv72u1MBnVuU/mt/fPmgO9r//XgLANSqIvr6hR79yaA\u002B92p7uPuEFkD\u002BiKVe/Qj6\u002BP8/zqT9vuoE\u002BWG0tPOggkz9Aqmi96W2vv\u002Biy\u002BLxCrGy/8Zsvv9C8sT/uXIpA4ibfvs4iUT\u002BJObI/t8mDPnRzFT9E\u002Bqw/RXyhP6zxJkCm3im/vKlmvjWghr58CYk\u002BFkYHwMwLVb0KA4E/siQ0P3e58j53RSK/zr//Pp/Skj5t6bI\u002BSVgbP51ltb\u002Bilg\u002B/Js7pv9iPp75kny6/YLZBvN6hEr\u002BvaV\u002B/mHLYvuCe1T6bBUe/zcPFvzq3bT8o23I/E1KNv7N7uz6S59a/XoMcv9TlFb9Uqeq\u002B"
},
{
"CategoryId": 22,
"Name": "Adventure Electronics",
"NameEmbeddingBase64": "UyHJvykdtD9S2\u002Bw/pnmfvwo5qr\u002BWClA/0vxcP9wHhz8351K/rGfAvtZQyD9OksI\u002BjEJ5P1PXsL4SK4w/0YdePpumyj9YkXC\u002BQWuEP1/7J0CdPRw/sNKTviIbjD/xtyK/GQ4dvyLU9D7UniS/RV5fv0LME7/wKyXAWA08vdLXfz677CK/vk7svtWccD7E4ZU/KNNvvwyBr7/oJk2\u002BT9ICP1xhj7/SG7M/SVxYP6gaFb9\u002BECK\u002BZvvnvxav0b4ZmP6/CjeVPzlshr81ocI\u002B4xE4P7hZpr1ma6u/UcdRv4BEuz\u002BYS0o/J6fxvpBGxT5f430\u002BtTZ1P2uukj\u002BowlLAFCktQOPqEr9Yovg/bqcAviDiprtfkNC\u002BjF0bwIIyWL\u002BC2ZY/9InAPie0lT8w5e4\u002BgN/ru94rfT4dI0C/CRGRvzKDVr9W/ai\u002BgxPav/oQFb/OroM/Aty5PyQtBz0SEb4/AGjfvtBNlz6UmIM/ADwmv9XJAT7WfZC/lR6UvhBByr\u002BNNfm\u002BLqxjPskuUb\u002BRScK/yHWyQLKBoj6hsCM/rAWZP/6XQT9cY7S9OjwkwGFvmb6xuhw/FlqZv1GHhL8MIgG/YIQEP3p0vT04c1\u002B8ai7XvxkPsT9onMG/1GU5Pyab0D5oK\u002Bu\u002BLMoTwIQ1\u002Bb5HQIQ/Jroavd6H4b7WB4C/w1NEQKU4RED5/ou/T217P6VVoL6NWIO\u002BnOMIvyOtNj/XffO\u002BPlH3PgwyvL1bZ8M\u002BRTgdP9HJ2D/FLaK/oCh3PyAcxj9bY13AMBZXPVx60r9CUqw//XM3v7zF7r0AG\u002B8\u002BIvvFPQoxQj85NzxADv4dvwJzOz\u002BqjYo/xMuOP6Kwdz/MZSHAey2LPyg6ub9A4pW\u002B5HJ/PxIic0DGHJw/Owl3wBQQpD8kexQ\u002B8JA\u002BPdowob84A2W/OJ\u002BCPxo6IL\u002BIYXs\u002BNHokQNm1Lj4KvZe/MEAbP3iu\u002Br8cFD8/KoPdP4Ac2L83xgM/T4oev6pRC76Omhu9sOqVPKQgKr/eC5k\u002BlOLfP56FGz7HV62/5AEVQALDkD8q3pc/Obz8PtCm8790Euq9CEaUvT4B3L9tSjU/8I3tv4UzN78PlApAPffTP7RSOD1ppcC9hICQv5gdcb\u002BlfUM/pkmSP5a/g79YndY/NrVlv7we87\u002Bkq6S/wMkzvYPvoz5Ayhm7U6zbP1hKGT2mQOc93zcBQJA4tsD8UI\u002B/27qTPts7hD9OpzDAsMYpvFj75z9VRO2\u002BLl26PgOsJL9aQMU\u002BYFTOv5xAuT42qQo/w2cAv8iHBkBqSKA/8kgfv\u002BnrUb5UDbE9YOjeu90MjT/gn6g\u002BcCupvHNXJD1SvQA/sdGTQAwCqj9Pmo8/Koifv8opHb5E/v0/3mQ0PeJydr5GiAs/a8NHP6DovD6ytQo/fPBuvvLojb/d7\u002Be/q3/6PwoXsz9RqHC/xLXEvlIi8L6RHq\u002B/c7juv8SYWr4u9Ue\u002B\u002BU4hP/hkfb5SZFk\u002B5WNgv13KaT9gOJC/pAO5v1cDTj/qCV2/VFpcPRkOZb8\u002BJ9W/pV8dvwwJXL9Y3ko/nts9Pwf\u002BMz\u002BUvlU/hhMFQE70rr9oUYa/vLTFP4JA0D6Y0lO94NrbO2ywJb8oOwpAKF9Av\u002B2BKUBgdvC8nCckvl7ReD8w7XQ/J3idPynp075M2Vi\u002BXbLavtLjib9QWfW/yIvJv21sML8056i/8gsGvymb8L4MNdE/OaKZPwVaosAeajK/W7mEvei5gL\u002BGSQrAjSqEPiBv5LsahGU\u002Bew0yvk3r9z8946i/g86yP3oVhL99ZsY\u002BBNhXP1142z8un7w/K0idv2CnVD8JTaS/Vd\u002BcPxPm6z9I6V1AYqLUPeZ/Tb/0lmA/vw6xPkXXFj9G/4y/qgGFv6KvtL62GMq/1eYAQCVMkj8cbS09Je/TP01mJb8iQKW/rv24Pu6bE77/CUO\u002BV9tTP8l0GT\u002BPsgm/nszKPxKMiL4EBTS/eBRgv75EFL/eC5g\u002B5P3Tv2Cbo79Qk7\u002B/YoUfv6f\u002BQr\u002BMvkE/CEFuv7QG8z4ZC5Q/iyYvwLT6Qb00WZy/9PsOvnrJBsCsB52/"
},
{
"CategoryId": 23,
"Name": "Mountain Biking Gear",
"NameEmbeddingBase64": "8CcGwIxLXT8T85I/VKhWPWOozr\u002BCwRI/28bDPztFfb7x8dG/iisrP7fn\u002BT2dKSnAv6EZQCktuj9GvYc/eWIKPghsfUDOcwFA\u002BpHEP\u002Bjl/z8i7GA\u002BwdQtPmF0Oj850Ec/gPmHQOyspz8gyhHAHiFBP69d\u002Br6ONmHAnAT1Plk0DECsc8K8ai1ov7k0BsBEEzE\u002BDkcCwK9I6L5He4nAZPHBP\u002BPu2D9tPfo/T5z1Po9Jcz4rybc/0QhDP6zaaD/Z5eO/0hgIQJ7gKMDHocA/yEgOwACFkz\u002BKUIm/UIpqPTv/hT/HPke/P87WPhieND9IXBE/wFzYOnhL2j8h5qbAsV/LP395xT/y0ZRAjIkovoXMqz9IOhK/l9KfP2qEnr70iG8/3mJtP3ezJz/MSSo/HEr5PnftxT7cr5e\u002Bw1zav7Te5L\u002Ba3SbA9m85wMgYGT\u002BQQDg9pml2P6Ghar4E4Ou8Ima2vmsA\u002Bz/jShBAiLfIvuk2mb88A5E/0wqOPmEmGcAQeQg//62DPxKYyr6g6ra\u002BnDsHQddFt7\u002B5tpg/rOPEP6lPwz/0aGk/hs8lwG7FuT7AHpG9Mut6v8DNoT9InT5AD3NKP\u002BnQs76\u002B06Q\u002BP5iav4b\u002BBkBAy/K/YnemPy77vL888uM/rQ9VwEVtDL6oU0c\u002BmcFOPlpP379nqde/ksPSP36AMkCmzcg/uN7kPyFP0T/m6jdA6/KFv8o2kr8pWRQ/\u002BzC\u002Bvzf5vz/bzQTA5plvvjP9yj9MY3K/X3YJv\u002BDcMkDplnHAFOQJv7a6z790mR6/WoAMv424mL\u002BJ6de\u002BxHdTv6JIn7\u002Bs9GG/lKbmvuIvwD/\u002BB00/gkKWPxw8P75AcIu/woLuPxarTL8qEhs/kHjMvblJsD8\u002BCh0/67VYwGiWMj3CVDC/p5HjvojNr7\u002Bx\u002BNy9ywtKP6pcCD8mzYE/Mp9lQBwlR7/HTELAquYivypCS8DA2qg7rK3rP8SLGr9An9q8CyhvvuBXlT/9Aum/NeZcwCv3bb9Eug1AVNT7P/hN9jxaos2\u002B0IJLvs7bW7\u002BUNxi/QNtiP/XNGcBC4La9bD5Mv0TjPj4Fe0dA2NFbv4xmJj\u002BsARU/AG52u77GfD\u002BpbgbAcw8QwAjIgr\u002BQ9jq8vlWxPyOxmb//Mts/F7ruP39gr74P2Q\u002B9bigWP7ZQID93JRrAJBbPvvz58L2cejG/yz4Tvm7vnMAcCv6/Q1U8QOe/E0AlMUJAeNKfPy9rdT8eC5q9WOqdP2buYr9D0IZALkh1vyd2B8AqmrO/hNCAvwPSGEAoep8/uTURwBwYEsAZCp\u002B/p\u002BclPjtlsD\u002BlPo/AhdeRP1N8EsCVOBc\u002BQBOUQB0FfT5i5Ns9yAF5vuBevr8SifC\u002BlHWcu8RjG8Acigc/uJKlv6FQ0T9pgPa/mPCEv6Vtbb8t71G/D7\u002BKQNShp77Gvvm/GoHrvrcAgz7uke\u002B/2oIjQHJZDL\u002BAFr\u002B/GPLLPta2jz8IEFNAj\u002BWSv/VRlT9JL0LAzocowP9GuL9ZugC/\u002B4ldvmb/Cb8xdYe/snFbvzPQbb/nxC1AGusKQMHzfL8oLxvAmHAJQD1Z7784\u002BW2/XPgnPgTwm70IT4U/\u002BvqQP7iqND8br5M/LvARP0fmM0CJvV\u002B/tKAPv5blqL96\u002B4c\u002BAaeoP6LFF764tjO/Rw41vzLrmT5I6cu8vo49P\u002BrFyz/mIm2\u002BzVIVPu1KAsA5oYdAjcTev1wRBsH0Jh\u002B/GAkcv9yp2784C7S/RrJhvr46LUDvgzZAmD7tv6FzPT\u002Bs4Wc/eBjZP64dB0ADq7C/DKOOPtxKvD\u002Bqfjw/S3ArvmaCmj\u002B2bc2\u002BMmqiv\u002BnpWEAutI5AB8Sxv\u002BTQ7D81zcw/IFfnvz488T6705O/ectQP3HrXj/WFRG\u002BMy4CQDHBqz4je7S/JacUvkosaT2yIqU/GP5tP2/aZT\u002BIGnO\u002BvFKgv8Hb0r86Dtk/OTz5P28msL\u002BmN1LAMNSdv592nz\u002BiELs\u002B6NQEwMv\u002B3D6YkFbARNBMPzNsz76CIM2/FlKKvpCQHb1Ri9S/uWqCv\u002BeHEz/fRua/ldRBwPEoSL9jhLK/"
},
{
"CategoryId": 24,
"Name": "Safety \u0026 First Aid",
"NameEmbeddingBase64": "SKSfv2DoA70Sm9w/kIkQwJ25NEDCKWM/8McZQMLOSkAagGa\u002BivpUv7nntb/CyZ6/t5V4vtQ89T9evK\u002B\u002B1hXLPj64az\u002BZ/q2/9JgTwI7UyT\u002BzmDo/YIdDPyDjmj8a1w3AxlSeP9vIaT\u002BeDCw/NA2DPuaT1T5SOprAUbuYvtGsM7\u002BOb5W9gHmhu0DgAr9z3IQ/YvjxP7QInj\u002BwsBo/rAIKPiuoqT/EEho9aN/\u002BPEz7Eb/oEv082i0\u002Bv7YpAkAS95O/SFBgQN3jHsDLHBZA7qsWP3tNej/N9m8/VFuAP9JVB8BZyIQ/FsSsv9t7l7\u002BJoHdAIOxlPxxsMb72gtDAIDEgQLYIoD/Yj2K\u002BgSeYvwS8IUAzWyFAIQ9TPyqT9r\u002BsPk09R/y3P7Vhwz8TEi3AKpXqvmxEtz\u002Bi4a6/RhprP6TNhT6ulEq/Ws4gwAhMr76IrAY/rX9CvsCjib\u002BoqLg/GBb6vqa8hj/0so69lPt9P7jsjb\u002BzVABAPPKBP2aALD\u002BAF\u002BK/lkpEv5OVpL/58Kq/tygGQfomeb/Eag4/wpNBv1Bwsj4a4RlAcavGv\u002BiZLkBS7kXA7KoUP6YCm74CAjBAJP1Iv8PMdz9YkYI9GXyLPkIViT\u002BIsnC9M5aivkpQeEBdriHAkClsP7UX8b\u002BkHShAyrUawCLPZL8QhgrAjZsFQOeVjkDq7w0/DhM1QKqngT\u002BtvLK/ZEhYPTm9lL\u002B0CnC/DL5UvdsCj7/ZsMs/ra/EvjNcej5\u002B36U/2z9FwHXpCcC\u002Bw7TAoJ3gPmBWtT/1TVbApQQkvqJ5478eode/W38RP2C2sL0rIBo/inmmPqTVEECbgpw\u002B384MQNfkB8DQEv0/9l4ZP1oOAj5CKq\u002B/OO6sv2c\u002BAkC/e\u002BC/WGqCwD5nlD9el9E9gKWZvVZGJr\u002BbYYE\u002BzM1iPb9ynj4ePki/GN28P2pSFj9cObq\u002BzNeyvjcggL888uw/8GIcPxyk37\u002BuFLK/g1WePkw64j4qAdw/fkehPQs6BL\u002BdXgU/GugSQGEhKD4CEMO\u002BfsmJPplt5D6YN2i/ZMwBP\u002B3VP8AKtZS/tE29v6ZRoL6EGNM/1neFPomwEL\u002BoS7c/tUsUQPBVtT3Go8A\u002BWNw1wDN8YT\u002BwQZ4/7oFuvz89Gz5NPcA/yLElwFWzBD77tqI/iIoJv8a0i0BLR5y\u002BSpj5P8zcN0Cwmmq/kEeMP/DMF8F928w\u002BkT2ePrRL4L9xrALAvlOEP2zs0T7ZNgPAqAuSwLEf5z5cMLdAzZ1vvzYXzL8MlRhAdlGFv2N2lj/1RI8\u002BsPeov5DBurwR6I6/0pbJvxzf4z/a/DC\u002BQj8rv6bfGcDYjsG/1rmmQA6qg7/nTHg/WiIxwBrYGcC/MTY\u002BMJ\u002ByPAydeMACFMs/DGPgPZlfG8DE1y69RlX9vxRbK7/rYEs/gpscPzjdmb4koea\u002BqPfJPeqTccCL1C3AIYWav8yLDcDKQWa/jp8VvoD3mr8kGCA/vP7cPqxUQ7\u002BlDDXAKRqPv4qjVT9BQzDANUQVwCj7Ir/vVzw\u002B8LHIP4uOdsDGGmI/ulfiPl1JAT9YSrk\u002B7lgkQG2cG7/i7k/AW98vQOg/kTzEKDS/JbIyPdt3dj86vIA/DgUTvyqflb\u002BpiW4/XqPCPwSISL80j5c/hwsgvxFpez/qJym\u002Bv1zhP65rJUDo9oQ\u002BKQXpv35eOz8JV96/VETCP1Y4C7\u002B\u002BICJA5BMQwGOiCsGu088\u002BGqi8PtN5nT6cTh/AeCnHPceDgz90amK/oKNVPxAzBD5\u002BW2m/dNRZQN/fJkDCbgRA56UCv3Gp\u002BT9xjuk/7hO5v\u002BSeBr8aLqu/PuJvPz5wO0Aqqc9Ayx2yP/Ti5r0E0VM/EOtVP774iD/J8sY/ksjFP8fx7T/81Tq9kQh8PzRIAsCdO\u002Bc/TASJP7g5o75XKnU/NhjpP0QWUz4GGg3A1aCXP4Of8j\u002BcVJm/7t0ZQGrCzb9mpz0/lItwwAhHl76gqdM\u002BWB4Ov9My176d8nI/no4rv6Csfj4d2MK/ADh7vlWBbj/CIsq\u002ByODCv8NvhT/wZwI/48s7v/IAV0BSDNW\u002B"
},
{
"CategoryId": 25,
"Name": "Outdoor Navigation",
"NameEmbeddingBase64": "XIZWvrq6mb9ON/k/CHOZv/U0zb1O1A0/pOxpP1AnnjxWVjS/NSUMv8ag8b06ofe\u002BFGKRPhpWmj/aNLk\u002BUjYWvwDivjzKUu0/R2uIP/3DgD\u002B8HuI\u002B5xUTv6KDbD5GGhO/\u002BXe4v/tOQUAPM4u/x5CIPruETD/Clz7A5/byvt1mQ7/aqd\u002B\u002BCJXgPl49M8CMD/I\u002BzP8avwAROT9YYxG922MtvpRVCz8xB88/jCLnvu0dQD6ARkG/672Tv8Yjcj6o/Ca/fD7/Pv3Lqb88QSu/w9/jvv3Qx7\u002Bi2rk\u002BNzEaP4fwDUAs00U/RVlxP\u002BZJnT5\u002BJ5E\u002BBHeEPyAEkbwh7KvARxqWP3Yk1D7QbbA/y75qvx\u002BFUz8wYNi\u002B6wU3vyYDgD4RMMo/KHQbvazp7j3GDIU/tLgvv3W9FMBbV0M/ixSVv/EN2b7YyZ0/Qd\u002B8PyRVab5Qrbw/91ACPyNc876v4Ue/jS1sv3hOBUAIfvM/vog7P07DEMCOywS\u002BNS7OPdwahr9PpCu/sU5mP02\u002Bcr95QkE/1CDVQH3Y3784JQ9A8IEXP5pTnz\u002BV/IE\u002BzIpYv\u002By6Bj00mOy\u002BHs2hv240Q75P1YY/GZh5v3pG3r2dshk/OBYZwM4GvD6diIm/zVziP0jgTr8qM2o\u002BCj8PwFPYZr9YG/4/E84UPxj8yz9nczC\u002BulXtP9fzHUA7dWU//lDdP1MwlD/QRLm\u002BuhEtPl5DiD5gdYi\u002BWRSqvu52UT/i6G2\u002BNt8WPmx/IT\u002BOJCO/IqLvPrXNA0BsYzbAKFEKP9/LsT8mb6e\u002BW8a5v26nA78fLZW/1wsMPl\u002BXjz6t0Xw/ThqmvtJpSr1544U/3WBdvhjZLD8RS3e/56HKPwKx3r5YcKO\u002BpO4XvdQEE0DgCVY\u002B01xlwOm99T7WteK\u002B3/kUv7ABMr24p0G/JwheviZ9SD85FghAFTghQNDogT9yCB3AVrUOP7os9L\u002B1P3a\u002BciovPtjOg7/2yWO\u002BcqBjP9e3mL79ewM/mKoPwIwbJr8Ajz6/LwVzPw5/S76eKb2/UckaPw\u002Bonr6zLZa/RN\u002BAP8yPML8fEai/MlCqP15DUT6sQxdArhcAwDmXAr9wYZQ83BoEQBKc1r7D3uw/v6w4v8i2fL\u002BSMUQ/tJxQPcpqwD8Q73c/\u002Bkm6v87QRD6puIe/rvo5P5j4Hj1NSHa/QsmCPtVIa78auzHAYumNvzEMpcBjQNi/Jj8dP/ZONUC\u002BggvAvJKyvwgzqL7FUmA\u002BU/rbPp6C7L9Uky9AKhSyv\u002BzbYz85PT4/UW8aP4YQxz\u002B0ZDY/5sSQPjpeqL7vQyY\u002B1elFP9UrAz\u002Baove\u002BME62v6moAb4A4jA6OgWDQJZbMz/AMXE/\u002BWY/v8VcCD8Ax/\u002B5/BXvPxQLEsCkNDW/agJcP/y6/T4JhMe995\u002B0v3Rewr9pRoo\u002B4Bs1QHxDkD9K7o2\u002BiSCzv3p1hb99RbS\u002BFP3pv2HpvT9LIOi/NQBkP8hFq77SC8g/VxiOv9D9Aj\u002Boabm/Ba8Qv/75R77vupW/6PTXPSjGm7546tC9rtAjPyJ8p7/6Ado/dlKHP5IE4L6oUCO/cGvIP9xYur4tc5e/BkiXPq6TVb8EBFu/PC4CPy6fH7\u002BRTKk/5ZEAQBPceT/cM9u/OmSavqBfTr8d0pg/qVq3P2OX7b4EekW98h9Ev2nLor8A2OO/b3ouv5SEyL7UeES9mlIwvzzSScB7hEFA/v3FPmC5zcC9oF6/DpsmvWMnQr8Swp2/MMcfP3jzBkDvrpw/D9/Xv3bQHD31gES/vESPPcKSHj/RlE2/fqhJP\u002BbEoj8kN3c\u002Bvq/2PkTU\u002Bz5j/Em/NSCvP1G2IEA34GhAg/9xv9IkRT9oM\u002BM/QrD4v/UBBcAeDLW/fM0bv/6yqD/kG0a/MMRDQGKr\u002B70w5aA/gmeLP32y4z5Dyzo/SHILvrJti75yk70\u002BsbKjP/1X8T\u002By/pI9SDYAP10BOL/2Dhw/7cgdP0I5gb0W1oI/zg6NPjzKlL\u002BI/tq/wVMvPzMy67270ls/fOqzvzkupL8CEtW/\u002Bd46vyoL9z4pMSLABAmLPnqU4b/My\u002BQ/"
},
{
"CategoryId": 26,
"Name": "Portable Shelters",
"NameEmbeddingBase64": "\u002BJoLvR7j6z1u2HU/NPhoP2bKKECuk/4\u002BIIYuPRzcnL9Co9m/BqAsv4joyj\u002BrRKy\u002Bxyc1P13lsz82aZ0/SO9kPpaz/z\u002BuGLQ/pjjKvn2Yhj\u002BoyE2/xCoLvUwqOL2VB6W/9dWqPih1Kb96aYO/oWrLPo2zQb77Pu\u002B/GpdKPxclir/02cW/miKCvmuUmj/V\u002B7o/ut6ePyCVz722Why/HrXYPycijT0UI5Q/qE8uPnnH8r4Ue8c/jLzFvyQqkb9TTrW/Kfm2P7KrF7\u002By7Hs/cAfgvRDjwDxmHUe\u002BQgdKPwIRWT/UQDi9QL9ePyDFVb84A/8\u002B0MfhPbSFej\u002BWtCnAWD4vPriVMUDyHcY/kbKavyJftz/yHGo/MprxPhB6Ur0G9Zg/pq4FP4x7HL0nBIY/osg3v20fpr2oxUM/nv/Lv\u002BYT876aLy3AgBrxv1/nHr8wZSM946kRwEB2FkCeegc/5gZov4EXvr5t3aY//LgHwOxxrj9BKT0/6CDVPwNYLcDGXs2/CA2/PfbcCr\u002BWMg7ATH7BQAlxMz/Wh6K9vJlzPnb6jL8EUPC\u002BbxGcvwivRD5y6Ki/rqQov6ARtb3MVBc\u002B6RTOvY1tcL\u002BM/JC/A2ukPrO8Db8xx9u\u002B5yqePxSzXz/z3ek/TfK0v1t\u002BNL532as/oGxZv3M9Cj\u002Bd7jM/yqtmP0orxj/OZ20//TzqP/xGoj/uzZQ/nxW1PkYJuj6VF/y\u002BPEr0P3UuQz/gj\u002B2/YHlBP4CSwz6K\u002B6M/mMu/v2rX9D9SV1HAoCarPcBtmD7Hjqq\u002BUFnWP\u002Ba9Ub8gNVW/6dAOP\u002BDAVT/seTBAgRcuv8gk6D9rKHa/U1VGvx9eDUB4iu89oPnVPQrUjz9Sb9s9iBexvYq/VD8lb12/gvMOwFh4Zr\u002B69po/CizWPnBlv78h2nC\u002BOhwBP0K7sj8MUiC/1qufP0xKqL\u002BIvdK/g6xjPyRe3L95\u002BqE9WCD6v/NZt79zjRC/3HuxP5RzAr\u002BwNr8\u002B6nacvtZTJ7\u002BGVZA/N9QaQOJz\u002B78VDvG8yiwdQGjZyb9w6lg9vluIPrF1gL8QIwG/igIjvvAF2LzEbV1AnF4Xvc7VtL9IMrW8EPnEPzfgkD6rnIy\u002BPIWXvz\u002BCUT\u002B4zom\u002B3jGIP32f8z7eGA8/oN8Vv0SSR761pwE/l80OPrSdXT5IqjE/18XzvsrveT8A2SnAykrtv1JRr8A8Zxs/HM9pPvcWzz4iohzAwvYmvxY3oz9Vorm\u002BHOgHwL2dhr\u002B6yq1Ae\u002BUqwNcfSL/OIaM/ZRCGPmAWhbzK62O7oTEWvwzXuL5tRzO\u002BrgjPPhpKPj3oOgI/I3ssP9nhCr9WX26/gL6AQNeWGL/AcBw/pS8FPphqkz/AJhI\u002B1NPKvpVdZ8DlphQ/S9JdPzYByr6tBQ0/LuBJPy5COj8pwui/psCKQJ35gD9epTLARggtv6PHHb\u002ByDJ\u002B\u002BcvZ4v9R/wb/8sWm/mOVZvvMHUj8/PgC\u002BSnw2vopjyT\u002BhVbG/sNT5vs39db\u002BUwYq\u002BUXmSPnD/yj6Edmy/VjVuv4xRAj6ezss\u002BQK9Svps4eb8xUg0/GKvHvfGzHMCoQl\u002B9pPQRQA3LH7/cCMw9FUP1P75mQb\u002Bb3UE\u002BOxsaP3GOPz5bgam/IA1tv/ne4r0n/iK/jm5EvY9AID/YAKI/\u002Bmjpv1iA7j/89d\u002B\u002BO7p7vlKjTz5S1\u002B8/KMmwPEH5pD7Ckbk/GxSHvYiGy8Aaqm4/PfUePivTUMAwvuS/j1AHP1pHI7/cZds/dIqtPuKPhr4ys0\u002B\u002BW\u002BXEP0KZiT8sMJ49dKVaP8D5oL56EA4/z4OCPvvspb9yRiXAAgFLvtIzfr6\u002BFH1AFlrPv/nftj3e5/Y/WdUgPr9lxT\u002BBP4K\u002B9gJbP7lcfL6LQoq\u002B\u002BrrZvlBBxL/oBBe/jAsTvxc7JL\u002BYnsU/Ih5nP/B56TwsnI6//lALP3C6rD0VUYa/yI5\u002BP7gF97/kx8k\u002BoDW0v3DJ3z9fGsy\u002BKF/0v8rkkr8zvcu\u002Bk\u002BuLvVSbMD9BRtY/xj0Lv2g4uLyrK6a/TAbXv1F/rT\u002BxsRS/bIodP3hAx7/IqjFA"
},
{
"CategoryId": 27,
"Name": "Smart Outerwear",
"NameEmbeddingBase64": "ytmVv4aCeT/e5SQ/4u7nvtGzB0BcqQs/5liKPxwoiD/sJAbAPhTRPJPaEL86mZW/7t/NPz2QpD/m1ek/5RXIPr\u002BwJEB4N5o\u002BwDduPvamEUAUroU/srCYv1xDwb8S\u002B6K\u002Bk9icv7tyCT/kq3i/29BtPky1qr9v93jA8Qjrvl6wnL/sDQpAUODKPfybhL7al7a\u002BhLEQP9wkxb5gwwY\u002Bhf1Pv72vvL82vA4\u002BMZQCwBHEqr469oE/bYCGv\u002BB/bD9sRee\u002BJtlkv801tr7AmfA/ynv2PhpK6b\u002BC2xI/4Vv/P1aCGz\u002ByfoK/nDKgvepRlT8\u002B3kS/Mi4PP19Czz/Ka3PAxOElQH3B6z\u002BU3fc\u002Ba7GEv5x\u002BT78ymfG\u002BdQhgv6UnBUAGbC0/l337PwZuCUCK/EM\u002BCrQ2QIDd\u002Bz30q\u002B6/glj6v5TPbz4wLMq8VEHGPjLmVD\u002Bs2Bo/jzD4vhOsmr8C7Lo/OjI4wA4yTD86EVM/bjC4v2ID4r15me2\u002BMkHgv1jMFD\u002Bf/pO/PAuhvmB79r8sJ5O/g1b\u002BQLyFk78MJKQ/AH0bQCjr576m8pc/hPe2v/LywT9lE4S/WxvFv4pPDj8okB\u002B/mKWNvyBuk7\u002Bsnkm/hpkIvlirJj962nW/GqfhP2u9/z/C3SQ/cmCfv5nd\u002BL8rdmg/FVe3v6avgT4LklQ\u002BZLw6QAubAED8woq/akoOQBcylb4SBr\u002B/JMRHPnihCT\u002BgBko\u002BTPBbPw1GKr/PnOs/HIT1vgz\u002BLL5SH5W\u002BIN41PzEoeED2SnbA0VJcQAVrtT\u002BQbBQ/gwgJv/KVZD2ESJS/IxaAvvshnD2dqbM/b9hQP9uaMr\u002B8cpW\u002B9L8WP9BhmD5i8lLAgn\u002B6P5yFsT6E57E/4\u002BxjP3XPPT\u002BboRLAPo6cwPzbRj/Kyn\u002B99qqIP\u002BhGiL9u4ak/Ppehvpx1GL9iULE/mp9dQD0PRz76Ms\u002B/joWzvxScVL9pwpU/hp6ev\u002BVUCcCRYP\u002B\u002BiMyJv9jffDx8J\u002B6/ngADvrzdnL\u002B9QLo/GHs0QGJagD95Mt2/OmRPPyGvh75QF6C\u002BxsokP4\u002Bisr8Apyg8JNxMPcia\u002B72BUq8/b4SCv\u002BRVs7wvCoE/KXSnP12IHT7ucAtAgMy2vzaIrz/U\u002Byu\u002B4RtCv1ofxr74eLo/8lWVvoImRr6G44m/2oHCvpJUFj\u002B477Y\u002BVLopv3KVPr/q59m\u002BoEljwBcR1MDUCJQ/E3NNP1yFNL/6gUG/Nkyavk7lYT/hfMC/hmrwPxqOHMDQsWdA9s9kP4KQiT7kH5c/C9aPv\u002BYJd0Ay9VZAGKqTv6hS/r9Qbis8E5iVv7wyg0AZln6/crCkv9bvur7cYao98\u002BmkQJAL0z\u002ByI1hArU5GPyzeOj6eGkJAw3NTP77pV8BiHyNARJ0iPw7FFz\u002BM7JS\u002BxAFtv5TdL7/09Ze/wfMpQPb83j7yEIe/ttyAPxp8fr9C8Nq/0OWlv9N8A8AQgJi8wHF4vwIJND/wcN0/p8jzPq6z7L/AO7u\u002ByBGxPDkNHb9R9wA/RHZqvQBYgL8nXW2\u002BtY6kv1c9yr9uk\u002BY/xJwRwC6Aoz0oKWq/LIIOPXxkrr\u002BEFKi/qEAKQHE98D4zV\u002Bm/\u002B50LwHp83b42eZo/axuYP9e6Ez8fNXy/2spxQByMNj/vY0A/ReY1v7AxZLyub2q/9qAWQLavq789zkY/mWQQv1o/lz5\u002BUWQ\u002BzympvlbGjr\u002BSZ9c/fBpKv1e63cCa4ZA9ox96v3sotj7abrq/XHtuPiqLVj8Oa6S9A1Ygv3hD3j9xLAHAkuU9Pwaarb29jcE\u002BeHS4vJQwtL/jpRxAueKpvySkND8aRDLA00CTP17PmT\u002B\u002B35dAmt5dPVR2N74mnuE/aHkqvxEyaL5QX7K/8G7EPmLMN0COxZU/2KxrP3cGaL\u002BAev\u002B7cs\u002BWPyHHir8yJS6/fWCMP26laL8ogLW8cMbFv/uhYL6/kT0/L9ImQFq91b\u002BwidK/UqiCPxr9sL4ml0Q/dzEFvyvY4r/OVCK/ki6sPuVrZb9a0Rm\u002BfMUqwCYJXb9ouRI8iv3Rv3EKRj9UbGzAeBhKwCrskb6wftA/"
},
{
"CategoryId": 28,
"Name": "Off-grid Cooking",
"NameEmbeddingBase64": "ashSvw/yJEDvIJU/YLeMv4CUfz8Y2IA/qrF8v2iklL6xLJa/JgSHv4Ra37/SfpG/lcawvwyssT\u002BMSoS/sa0AvxumFT8XreY/HPSav9hJSz3gUwBAFNhywDA2BcAU9Iu/WKcbQBYrjz/svui/l/lFv6Zv/L8TwLbAoLcOPxquPr5lL8\u002B\u002BNiymv5QSmz5o8Nm/KJNfvbUd5b6aEWzAWPIbPTg8/T9214k/jPQLvXlij7\u002BjU9i/5F0Hv4bn17/1hRm\u002BufQOQILYJ79rEo6/GIwJP7mt676QwwQ9e3BVQDw0uT8g7Fk/U2Utvy4Gyr6LRRM\u002BI1iFPrpbtj/IrcHAdgsOQMoihj\u002BIvkm/lOj\u002BvRpUqz9h8g9A2rgnP27KH79LgYA/isfSP9Zb6z960NE/EL4ou2Zd5r8k84C/dJ8kwE96rz/at9I/cIEawCfAwD\u002BAr7u6JH0EwACoir7ZiPY/nJhdv9Q3rT\u002BSNoe/YD3gv0xZgz\u002BcQsA/Zug/PoueRMBqyou/KSlCP5zeQT11PZS/cYkAQb36AcAh0p\u002B/GCJQP0\u002B1ej9gcbe8yCUFwO44v77GdCi/9mnZv5xOfr\u002BRqcm/BdCqP8dOHsDxY5I/b0jZP2DsEr/IHSJADm1vPgUWSj6VnrQ/bHD6vyxbO0Domy4/kRQJvxwL6j\u002Bzxaa\u002BulAuPwNPZEBkT0C/hARvP1J\u002BOz9i\u002Bry/FJ7rP5jzL79tOWE\u002Bs37SPo3qVEDA\u002BqA/EW8XQIugRT4YlpI\u002BLqtAPpqqrz9K1cbA8D2JQGENIEDdg2G/Fp/JP6RqBMAU21S/jlnBPf6psz/IJX8/bVmwv5KjKD8g5ag/sCPrvv2N0T4HwHC/HpBBP0ulHcC/ON\u002B\u002B0Jv/vhzX6z\u002BOQ4W/BVdwwJfI\u002Bb5OBt8/cnBiv4pt7b4YEdo\u002BKwe1vmYuyb9WYhLAfyQ6QMkiIsBPHQPALeCvPcFecr/266U/E/uSPyJlpb7qkVU/R7pVP2pUZT841K6/m3Gsv6HH4r8CI5q9KHbFP8YHh8AQDAzAHl7JPzmjwT/aO5S/VEFav2esGz6eVxe/oEbnP19DXsAqOI4/fiyJv4Klkr9aHfI\u002BDsMBQIf7L76Xzo6/MaakvudBCUBfrZFAcAIvPWPWzr6VSRdA3hgKPyMZ5L\u002BhEVg/nsU0QMpfDkCQlgY\u002BdE2HvtgNPkCupnbAmssDwI/xAcFQkzq//GWYvyg\u002B9L8Oive\u002BiakYwIhH6z60/gfAcpEvvxG5jj8cpgRACAyJv5GpCD4eoms\u002BypzBvRe1xT/icqE/mENAwBUNVb9QiTs/QAx3P3JCIkB4lZk/5PxJwEGjsj/1yik/R/LcQHKABD9sa6NAUSaZv7NzvT6rkYw/AWc2P2AbB8CC2o6\u002BluqrP/A6CUBdVve/kvcvvRatDL9iMn2\u002B/6cSQACBU7vPcGLAfhaEP\u002BVfrr8XVi4/w8w6wI/Csr\u002BCO2\u002B/0/5UPwSvzL8kaj4/3SMyvpCiuj90wzq\u002BHDkfwDqYsT\u002BIN/u/VvoMv6I37z0k3lI/UJDzvsT2D7/9Cqk/crf7PzQYWr8M/RY/h\u002BGyP\u002BIARj9Gefa\u002BSyDiPwWSyj/UG3U/hhzJPWJD7z4qVRNA0B6\u002Bvhuep7/woCPAkbkcQHaRkb\u002BOQCZAzuVaP2plYT/aCLc\u002B6gzcvyhm5z93//Y\u002BEGBnv6pfr75xuO8/vEY6wOFeHb5lYYpAURDqvfw6D8GoyjBA3MTivlwrFj4dWGU/aCTgPeRjrr9Pd1NAsdtJv4QMVD9FTMC/klDmP2rWzj9M7QK/7F5lP8gRxj6kaiJAHZaGv\u002B5K1D/Q5gvAj9oiQKsUkj\u002BySs9AexQZv1lstz5YvqQ9HjSevtKPmb95wHA\u002B5mk2PiDdUD3LMo6/bBynP7hCpL\u002BKz0RAdEbZPqcbCT/bAUy/7Hu\u002BP2irL8DAoYjAFAK5PO6b6b6Kw5\u002B/7bCeP3g2mL9u8CC/2ZQgwNh7Gr6sOxA/0hkHQJDppj09y\u002BC\u002BMIQNQHZnqL6FR80\u002Bwp6Dv3\u002Brhr/mpJI/TL9nP3j0jz/KR1LAaQUZQIlN476yXR\u002B/"
},
{
"CategoryId": 29,
"Name": "Water Purification",
"NameEmbeddingBase64": "7VI7vzP1Zb9CVjS9onSpv2rIEj9QuPm/pIoNQCAokj/WBzS/knjhPY4UQL\u002BYAm7AhjgpP/oupL9Ty6Y/gmkOP7Lh5D\u002B5Utk/GRkkwCpwjz8deaE/DLhGv3Pbob9ZfUW/sHOYPYAmODtGIeI\u002BDLyVvttEqj/vEkLAjLZpv7XcEb\u002Bh4lw/sNBou5Sjdz6SWrY/PtMMP45zHT7S3KK/vtkLvka7EL\u002Bq08A93Om9v3YGHj/68NO9COcRv1oOXz8quOe\u002B\u002BvMMQKHj/L/QvIw/6tefvluk3r8adIQ/mtZ9Pwg9rzzIZKc/dFiwPz6wPj9GWWi/SrB9P8ZIYz\u002BCklfAnmMMQBxAVT/5tQxAivEcPly2ibzukPA/E\u002B6XPhNdXb9GFog/5LGwP0RrrD68Pww/6kKwvppCrr6AJIM\u002BJasTv67Fhz8KNJQ/zsu9vzg73j6yxoC9F7efv9IqsD/y3kM/rhGDP9jlh71yrgk/h0ucvx/HhL9/t7A/tnfLP2V/Tb76EIi9GCu6vsk25b6UMMg\u002BtlDnQGj0FMB243E/TPcEPzb4BcCkKek/mn\u002Bsv74Rm7/kqhK/jgAvP5rSgD\u002BQp8E8MD0ov2dVqz94y9y/a81uPh17gT\u002B862I91j\u002Bhv/hgk78g7yW8ddlfvzbAY79KCNE/0JLxPgytwT\u002BLHYY/QGiYP7KrEkBn5wrAflAHQGThO74yp4O/eXwAv7D1H7wMUBo/e14/v04QoT\u002B2Liy/FgAPv9s\u002BOz/YFta/dnoov1hl0j5AhEbADQyPP70OyD9aQo2\u002BBOjvv05XtD3CP4q/72VLv/ZwR0CG0L8\u002B8CtPvQKFyT5lYro\u002BFGO9P3oA1r3k4TG/37KbP05fJb\u002ByAVy/ZUN2v9lXLkC4WpO\u002Bbqx8v6Qt371c\u002BSO/Wq4AwIQDL0DuxTK/XO4FPzgqUD/sX/0\u002BqLA2P169k79MsB6\u002B5psJPzqFbD7K002\u002BGD\u002B/vzKGLD9rItq\u002Bx/sVPyevgT\u002BJjwS/qkgxP15eoz0cj3u/2uDdPwhA3b\u002BsEhA/ugkHP1pVXz7t/GA/WCB7P5ANLL\u002BaBKC/rS9Tv7mgAsAdoC8/wN6Jv/Ls0L8JpYq\u002B1t5RP\u002Bal6j/Oepk/whk9P2telr6rwilAHzoBv/HiSz4GNki/zfUGv/ysWr1rnVs\u002B0w0sQHWAFj\u002BKB0Q\u002B8wfGv1vG7T\u002BcBhPA3xUdwKDLqsCCLY6\u002Bd3s4P0x2V7/8Wvk/qIrKv37bgz0zbEG/WmOFv9tkRT4sxMU/RMfkPq54qz7SC2m\u002BRobdvkWIgr\u002BWN2ZAGuKRPkOJWz87IJa\u002BVu1lP8iKOD\u002BGLPE/qU2yPyQAQL8ytG6/n2dCQNA3rT8fllU/rPidP6Cwor8l1BI/MCypP5tgLcBUvLG/M9gvP5ytUL/OVLC\u002BoWSrvrkxzb\u002BGHWQ/pghcP7wErb8hpNi/0zczvmfJir9sh72\u002B7i4bP9hg2b8mHsO/FdWZP56ubD9VDjA/mJnpvJaywT3kFmU/9bVev4oOST80mhjACgn2v5i\u002B0D5etYc\u002BBVMqPtVg1b8NzAo/44O\u002BvpKpQ7/7p9g\u002BQZXGP7xHw74IEoG/svOFP3lKqr8FWak/gBogv\u002BABvT82tFO\u002BwvsNwJ4n0D5yOQXAmA6BP/4Vqr9rw5s/2BY9P3uTxD/YVNE/C/Uqvwgy1TvLELe/gMqyu0Jhij525FS/KguDv0YDtb8wbbE/NsVMP3LjssAOYoW/kB/EPxg/vr9EHBK/UKZzPVykZD5oPYk/fdR4vot/KUCA05a/tZOFP8qGfL9OnJ6\u002Bm\u002BpavsFe7z4MWg0/vRaMv\u002BTSoz2hp8u9FMceP9iyTD\u002BbhF1ApZbVv1Wenj5YROI/CLj0PW4C3z5C1VU\u002BrvC/PQofWz9e9qY/WhI9QFTZYb\u002BC2pW\u002BpB4tP1hkxr5CyIs\u002BYqG0vnBLDcA\u002B0LS/ZoOBv5iOkb8MvrW/UvlPPlbG0L/EAV4/igcmwC2pXj6TiYs/6qPCv2ZKT786/PU/\u002BApKPXKROT9TVeY\u002BXF/6v4UPqr\u002BMlX69o78wv5pVMD93I1q/dW58P9p4jD3\u002BQia/"
},
{
"CategoryId": 3,
"Name": "Technical Backpacks",
"NameEmbeddingBase64": "efwyv3QNBUBBo7k/85JAvwI0uD8QjLy/zHPUP2rtHUD2f9W/eNiZvzdRjD7HOx7A4BNIv9TIvz/GHw9A4mgxP\u002BmZGkCjL78\u002B9RjjP6qVfj8qWgRA/Qm6vmSXfj4QrUW/Upcqvz\u002BJbj7vCcA\u002Bn8eVvziBG7//GoXA7F38vnSN7L\u002BSnZS/AMuBvva5FT\u002B5ojg/oAb3vHNBjT4SwqW/5vKLvwSpgb/0FN8/D\u002BEZwLYin78CYgc/uczwv3u/hb\u002B4r5e/Of9mP6lt175CCH2\u002ByJkmvmha5D/k5bi\u002BUrcUwAFRzz\u002Ba\u002BY8/Fr/3Pw30yz8TVuq/qhUmQI\u002BEfz4S4prA7CUbQPLV6z\u002BA6tU/nFmkv/5uC0CfTjFALY/yPlfnir4\u002B8v0\u002BbKylP5oM/D\u002BDjnw/huZeP6RsCUDxxG6/pHKcv4tO9r9kr4I9nv6Svw7dgT6Ql1U/oKmevwoVlD7G\u002Bpu/FPSsvcSSW73\u002BwqK/sVBGv9pA4r8qCbA/qrp8PwoRgsBiBFu/VgJJP5xF971Jo\u002B4/5lDmQPAJVr9d\u002BJw/n8J5QP\u002BmHj8y38U\u002BnJAewFLKvz/zN86/ZPnQv50\u002BlT7QYjM7r3apv7pLEr9o4ng\u002BvDCHPdAEWj6WTMy//1QhP5LO5r5ibP8/eFYswGukij\u002BlexVAoF42v0UZ8b7msDM\u002BsmrtP4Al9T9yNwi\u002BvURCQBgpp7719ktAMvdGvz/TY7\u002BQZ5Q/\u002BGW8P2CRAcC6vgLATANNv052zD\u002ByWGq/DqecPzTcrT8RdmPAVvHYv6RAJz8DfCI/KKt2v/URgb8PS0S/mNY7P1TTBb0EAOY/3qAMvzpo8L5d8xBASDA\u002BP9psxr1wCq\u002B9W3qgPw9SIb9M96O/gbsQv\u002BWM5T\u002BDJpE\u002B/kVIwOKrNL9\u002BI6G\u002BMr\u002BZP2cSj7\u002B0/Xe/gGUWPCKUJz/apgM\u002BCNUNQC2GI79NYjXAPAJ9v2XhBsAsDZI/d9QDQMNUg7/Te9q\u002BxBkVP7rqtD9/Qo8/4AAAvw//DcDFX9I/oOhVQIWL5T\u002BgdwM9tiz2P7Djj7/0b2w/zEyUP5Q1Ob8gdoy\u002BeqSEPlO\u002BOb8m/FBAc/tOvzzHpL/qvFA/MFffvcBw4j\u002BCJJM\u002B9A5ev5YSwr1Bwvm\u002BU1oSPppyYr81fZI/HlxgvzK0s7/eFVi/MvGyP7oPjj/Yxw7AnTSHP21ri79uCPq/bQabv4SW8sBef9E9jF6aP\u002BI2hz9M7v09UJfzPBK9AD83zjk/gjKuPvaNAL9AzmJAxryRv3Y91L5S4Ka\u002Bxhymv4C6Oj9ptQw/AXfnvplc17/AfRe/Xf6IvliE/T89dNu/ygDVvw6zcb/PgCU\u002Bbg\u002BXQDRkkb94CAtAMk\u002Bxv9/HIz/Gw7M/uqt6P37Ud8BslBRAAWIcP\u002BDzzj5KlvY\u002BBH8VQFlMzL5Q1xvAKF4wQMPpJr\u002BCwQvAlk\u002Bzv0gkhr8cAPm/nJr8v\u002BAUXb9fTgu/Um9hvxXHmr4m6pw9ntmJv9H5Kj9xrADAtBecv\u002BBKcT7dxbm\u002BvCAOvxLgcb\u002BEKwg\u002BDM1LvyLFg7\u002B8j4U\u002BzJmpvnPytL4ZrMe\u002BmE/2P1yLAr9sfYM/WokRQOSFF79aANE/T4YsP9E1D7/CDPM/O1t2P2iEvz8ZqYK/boUsP3IUiz9Enig\u002B6//Dvzi3GD8jvdw\u002BSdUxP2WB/b/VpxO/KFfMPljh5T6Q8J4/SnXTPU6UIb89PYhAojZTPt\u002Bd/sCm04G\u002BPh6DP7BwC8D4bRK/OAbEvww1oz\u002BNTqA/2OBTPx7dHj9QU\u002B6\u002BjbcHQMh\u002BKD9LJ4Y\u002B\u002BLvsP0YImz5noj1ANlu8v3Ix5z9Log3A52vev/iHaz/UAbFAT6UCv7D93D\u002BiaBdA/P\u002Bbv9b8J7/Jg/c/yKpuPoDtkT9g2F8\u002BHoolQDqF6r9QTdO/RzMIQFalHMCYAGe/IlnHvpYUvD4j46q\u002BQlkxv5/ZNcBAbVe/4AFyPzQUr79Mxby/ite\u002Bv/mlMD8/zpa/PI7KPqp\u002B9z9vD5q/4yNuv4LX8T8GeKc/hhpCvoaLB74BgAHAeA2Iv15WqL0UifW/ANDEv5hS17zh8IG\u002B"
},
{
"CategoryId": 30,
"Name": "Weatherproof Tech",
"NameEmbeddingBase64": "iNMEvxxS7T//UfM/egAzv3ldNkBzO6S/ATPVP2e\u002Bfz97Sba/4AWxvUv1pL8NlDC/DtjCP0hyrT8zIrw/CDNRP0iGJ0AtqqU/NALmPwXIIz/VLOg/knbKPknS4r752NC/ZEM9vo//sj49NT\u002B/5W8FP9Bp3rxFT0LAb5N6vyyDo79q\u002Br89FtbPP2hEwD5wPR0\u002BbMDyvCPIHsBWVuq/sr89P24Fy7/gLQG/5eZVwDIcvL\u002BBJjm/jycgwLU5uj9o6aG\u002BlyczPy8B\u002Br\u002BImAtAkgQQPpEmgr9C2Om\u002BPK3DPlFcYj\u002Bf2aG/UBfvP3YUWD/RRpe/R08oP/liOkAOzMfAh7ASQPgmF0B5PRZA4YQhwO10bT9Xppc/l3NmvxDEvL1DcClA22xDP8Z5yD\u002BpDqg/eGXlP79UvL8Ng32/\u002Bj30vzf2HsBEC1s/XGcgwAflF7\u002BQvbo8SOrSv3xvND\u002B1x0y/zSUCvstUqD/LGt49wh4pwOWRzL8YrM4\u002BkFSUvlE6H8CZrsA\u002BxeYfQECPv76GtaI9ljXoQCx7fMAVZza/kznwPkkY\u002BT\u002BGH8E\u002B/22Ov86sZj5gp0bAhJgEwHH47b54xqM\u002BJ92GPYwuZD0mJXg/RFsOP\u002BgFnT3Nfbm/WtQxP1T8Jj8dlYi\u002B3SL\u002Bvw4QQj/thB1A7dVLP4YAdz70k1m\u002B\u002B0zdPzEljkCGZYy\u002B1qp3QKRUZT8aez6/D40/PyDQTD8q0d4/9EJsP7ZID8AyrJ0\u002BdMyrv8CfSjyYyXm/iCINPsO/Z0B9N1DAmZI7P7IPOL\u002B2U/e/V8IZP9CnsL6w1jfABX1fvmjUPj\u002BpwwlADYuevxR0I0AgIa8/5AOZP4XKhb1U8qq/guQZP\u002Bnc9j\u002BQtZE\u002Bv\u002BCSv/vkIUCPMlu\u002B1I5KwHYUiD8hRfw/R74rP6D3f7\u002BplnQ/3td5PqISAT8Cmpc\u002BlyD9vmSzzb6TDe2/rLbNvj8gxr\u002Bbx0M/QOCgPmzjpr\u002B791c/Caj3Pu7AyD/danQ\u002BcsdEv8gT1b/43F0/q0inP9NEtL9TdZy/SmavPtgQRz84gEG/kfDhP8ei1L/4A2K9CGTkP5xCGsAsMQ1A\u002BvI8wM0gkb85/Wi\u002BLI/wPS8gEEBemQtAeJUTwF6kU78YVEq/Mwb\u002BP/WKAcDPH7I/0HQbwFcG8760hz0\u002Bf/1jP9jXjj/eogs\u002BgxBGv/LdfT/soPO9hpGkvyzjs8Ac70zAUXjsvmcvFj9BHNU/uCWXv3a4\u002Bz7Fb76/P9AJQIfUlL8M3YpAgNQYwHZqEz/UjYm/2XE5v/iKLL9ZBRE/AxOMPy7IAL/WM7a/LSt6vvSeIUAodPm/LxZswK76Xj8gxZa9lneKQLQ2Ib8y44U/M\u002BqUP55MRj7ZLX2/0syVvUtrjsD6TjY/TieAP0U0Dj7mtfg/d9Kgv8NWPb8L9MM/pnkgQBO5pj4T0\u002BO/uOIcP0qgKsBwzqy8WJJ3PznSHsBQLU3A9kCNvhl5pz9Ay2E9hglJv1Dg0z/EuOC/qrTtv5Exhz\u002BE1AU/7qujv44F8z9EJLq9M6d/P24AHr7akbA/VPLLv0AfCT8netG\u002BpkJtP8gdt7/RRQo/kmgwQDLUkb\u002BbTQdAT56\u002BPwgjqL\u002BNLRlArvFUP1s6xT\u002B2DlG\u002BsKMLQLAjHr98Xf0/3sRsP5tFmz\u002B0Jgw/odPePlxRor\u002Bf/to\u002BagnXv//qUj\u002Bls3q\u002BEilaPzXBPsBzMopASGeMv\u002B5M/sBm4Ce/dFWxvgzyEcAnej3AT54ZwPINMj5U1h5A9LCvv2/1tj/rxIzAGQaTP0pYBr403/G\u002BbEPbP\u002BO2lz8QIJE/R\u002BYGvUFXlL5N04s\u002B0Bedv1SHLj9OyKdAMIy5v2yz2D9k43NAwO6rvsx3Db5Nm/I/crNUPxue0j\u002BN6ai/Vv\u002B\u002BPsoClL/rjhy/xHW9P2rbQD/ObOg\u002BknSMvm4W8D2kxJO\u002BEMTrP4gJybzNsJm/1qPtvZSfob08WzW/jrUlvo7B5T68Vj8/oeAHv0TJjr39HH2/SFOUv91Xzb92Qzw/nLV6vi\u002B1CL9ME1\u002B/fHKbv\u002Bk01T6OXjXAb4WEvy4Osz\u002BQHss/"
},
{
"CategoryId": 31,
"Name": "Trekking Gear",
"NameEmbeddingBase64": "1kV/vxQOoz\u002BjiCxArGHJv4Rpnb9P3J2/djoGQEqQ0z\u002Bq1kXA5kgLv/6eGECtFjDAwn0QPrvWpD\u002Brq6g/VKf1v\u002BqANUB4x80/pnaTPwxpej\u002B/eY4/Gx0OwKaRm7/Uu9i/fjbNP31itD9U7zS/GM2svx6aD78rAlTACEq6Pjdbnj5onD2/XPCOv5R5cL/4CRo/xIcHv67ewL9II/y/JgStPwh0CEDzJ/A/p\u002BhRv4vHAj98vBq/L/vLv9xclD7YbL\u002B/vsglQAWZGz/L2aM\u002BuBDXvwE3sj/Vkiq/Kzn8vcgeUj/DYlk/ZuRgP4Jymz8MXoc\u002BlbFdPszLWz8Su5rA28cqQCSLC743oZw/FLTqPYUlMj8WG3A/BXeYP\u002B3uN7/P4b0//mwwP09n6D8YYic/W8UoPmxzAEBQwka/NKa7vkzQ576Sooi/9MSkvyhPrb4qs1I\u002BO2k/PpRyuL\u002BMxxO/W7b1v0F9Gj/eUY0/FPprv0oBX77FFn2\u002BR1xkP\u002BRhMcBcLte\u002B\u002BJi9P8COrr7Qj3U7rcX7QGIC07\u002BWZYI/npksQOwkvj8iXPM/j1EGwO7/\u002Bb4oPtq9ArM0vvxAYj9vfTI/q/GlPYzYoL89wIU\u002B5LddvwkPBEA6zvK/r54iQMmYkL8ggHm9ObMDwGQE7L4RYQNACKRWvywgw794via/8tcoQEKSH0DVgxA/II6DP1xJ0j8crB8/GoKKv8upwr6zaPy\u002BPABtv3G\u002BPz/lpmS/rEZiPsY0FEDdcS6/DraGPlYAK0AMRHHAAALwOXUQZb/u90C\u002BbGkyv/jVYL\u002BIaeU\u002BTAqfvzTtlz1OQBM/yKrUv5v9oz8ykIM/vqUmQELLsD\u002B4GT/AownTPxKQjr8QJMi\u002BdJ9SPhRhQECG9l8/S8eTwFsllD4Deo4/vM/IP0gm3r8i5Xq9SgzDP5RwnL4rC1s/FyEhQM2Y/L7DXCLAXBDNPypMAsAuW3o/4PkcQLzfQr/CvQ6/C38fP787Oz9\u002B4Ka/BGMvwNq7zj9qPCc/\u002BfKWP\u002BHuIECZ4Ze/2fHTPxV8Zr7\u002BZ\u002BI/2qHlPjIXpb9yy2y/aiX3v1J8xr8OatY/Pzn2vztJS76lNSY/yC9MvWqMuz/erSG/igpxv0zHpL/sw/M/2wpAPYQlC8BPhAZA8gedP5SBSb8IaBC/9KIQvpcs3D8T5gjAWrLivm\u002BcO77zVUI/DVO8vp4/5MBn3ku/k8O7P3WbD0Cs3ck/TQ75P8hzuj\u002By4Wo/i3izP3w33L9Dm1JATSQ/vyjPCz\u002BXM9e\u002BgsXCvcN6EECIHJU/Ap20v4OGiT7aZ3C/ItzJPZwGF0AfYifAEJ1fvzy9w74yr1\u002B/l\u002B2MQHwyoT/e5r8/7r1CwNvkDL\u002BTJKA/ZznVP5QnXcC4cZw/rciYv1Y12D9Q\u002BaY85lvhPnqfjD3Dlm\u002B/j8C5P8AKQ76APZq/Ral\u002BPjLasb\u002BYnzDAXkULP2BuJD8GihXAKO4OP/5iLD\u002BE8GM/J7mHv5xJRT4ReC7AKOoNv49ATsBA0JK/zylfv1ARu74K59O/RFkkvwJEpz7r48k/ivzBvv4\u002BAj\u002BGaZ09mneTPwfrI8AQ7Ie9\u002B9iFvqCoaDwYfx09dDKmvlRpyr9WiCW/3d9AP3ijLEDu5rM\u002B3qYwQA\u002BeeT4b7C6/3G5lv0pCmz4SoUu/tZsiPzUrnT91wL8\u002BtkjoPkjXPT6GiwW\u002BXM\u002Bcv7PKWb7JFHZATj8zPwkiBsGujxO\u002B7rC5vg4vNr\u002B4rLa/GlstPzpsWz92ogFADElpv9T07j4pxJM/f4kCQLymYz\u002B9rkG\u002BDUMtP8Sj5j9tl/Q/l1Rivy0lLz/NCPu/qMxrvWBG2D/twGBAWFiLPoXezT/u3t0\u002B08dDv9cnMD\u002By7Za/4tAAvjYOCD\u002BcYUu9LQKDPi1jlr7B8AG/poIXvlEsuD\u002BoiK2\u002BPtHtPjhZaD8wM8o\u002B5KTQv/j8pT2aUss/OJkyQBViJcBEI9K/BiELwPHkfj8EiyS/XGFpv89pjj4V\u002B6u/Ftiiv2lG478MMTY/sSZ4PtUW8752NAM/1ZPXvxkvgL9YWHfA8C1KwD05l79JzhvA"
},
{
"CategoryId": 32,
"Name": "High-tech Lighting",
"NameEmbeddingBase64": "wCehv0QZJEAty3w\u002B4GCEv\u002Bwj3j9iKpO/lp\u002BUP7gH/T9DgkI\u002BAlKLP/5ZKz/4CiK/GgXpv590OD/0pTw/UrAaPiVKIkA64r6/gEqNu8hwyb5vWUtAIiXEvv\u002BA6r\u002Bi4gnAhiYAQI5lD8DSbcs\u002BKICLvwFQ4b/BnafA\u002BPXpv52ltT4KJhxAt1BVP7pGX75GJeu/kRE9v7VgJcBWuRvA9\u002BtCvz5\u002Bsz/hY/i/gP4KwO5Yqr\u002B54Ta/2iQPwGqPir4ubgnAWn2Qv7uL4r/YcMY/8n6kv3EA4z7o0Ty/5\u002BSMP\u002BxWNUAUJbs/pMs3QAhsPkCV94K/\u002BdH5P\u002BhZsUB8W9nAFlUsQBT3FkDL3Ai/TLkKwOqtsr/6gI4/ScEuv8L5MD\u002BAARDAHhgLv8\u002BbsL8FMAq/QIHxvkqnwj/AWIDALtbiv4yWC8DflXdAp7lDwOLK9b\u002BCa5w/IGlWvGdmvj9nJn6/1P5tPzQaf786aPy9UHo9wIDr17/SKirAUj85wORQjL\u002Ba5zPA1PIPP\u002B47BcDPa40/EEfXQCEuDMA59\u002Bm/7Hx8QCQqbL9j3cs/sJs9v56eGEA\u002BepQ/5mQEwCu8FD9I1h88Q\u002Bdiv03uUL\u002BqtYA/5BYVQFIQzz/nVi0\u002Bfk9qP8D2CT50hN6/b5kBv0Cyi0BPA0NA2Byav3s31T4GQMi/7iHcPxL2jEB4HZM\u002Be44dQCxMprw0tEq\u002BnJ3uP2q2Gz9ueYQ/qzyqP65e7r6zZwbA/wC1PhtO8D\u002BBS4y\u002Bxcg5P7ZmJkD2Ix/A\u002BkMpPu37hT7c8Xu/DMmjQKH6j78cdti/qAzSvaDPir5Vw/E/DawSv3dH5z58T9w/xfGQP9ghAkBANAg/PAkdQEqMmD8PzwJAZA\u002B8v4EBbUBOq6i\u002BOoCCwLk8QT\u002BvfTm/ic9IvrBW4zyMl9O\u002BNMBWQAp4jT8SEtU\u002Blv83QGyWlL/m/B3ADudPvndhj7/qPaw/vK20P2GT0r8SP4m\u002BT2qiP84Ec0De3KS\u002BnP05P2Bspj2VIUe/aPdpQEqGDcAoyb0/QAmEvzhYqz\u002BwVvU/n7dfP/QehcDUJrm/OMMgQIDbAMB8xOU\u002B8T0\u002BwKYYEcBegTU/4Ib5P/osyj0ARMU\u002BKkRKP3PLqj\u002Btp3K\u002BcCUivqn5ur\u002Bpza5Alk46P44IUMC0M1y\u002BlDmLv0Whjz/dcEM91BOXP9b3lj\u002BE1Ew/hklCwAYiC8GpAwdANR4iv0SHsr814AJA0qsIvwBtXL2AEAC/4QTwvkK63j89P3RAruLqPu52RT/JihPA0rw2vWQJ/j\u002BMtuQ8pNhYPDi4a79mtHm/kh1EP/7NM0BIK7O\u002BrkaPwHRN7T7CAho/ZKDSQNIFEb\u002Bq4DQ/6BN0vyKbiD7EAOu/5eGMvkTTUcDgJNU/pP/iP7paJED2lyNA7asevv\u002BpfL\u002BYDD0/goYHP9GydsCAsE/AtHgNQCbAG8DJY\u002BA/aJKYvmkbdL88bBjAODqqPxuJ7L/4zam/CD2lPQcBuz4yJynAHouFwNU5BEBvTgK/s83tv8cK8r1YBYU/QhhOPlh8t78cYjhAMLK0O94avL69jDg/djrXP\u002BAj4L4JTM2\u002BN8poQGHZWb9S\u002Bz1A/WUSQG5mlz51tIFAPiugPefQVz8E0Go/5oXmPYWfeL7I6Yw\u002BY5xRPyHrib2mR0i\u002B/JQFwDdlVsBw4z0/kda5PgDFgb/OBSg//2i4P/TxM8C6iec\u002BbWTGPhZ1E8EkFBg\u002BGSepPiFgQcC19j3AvBwov9/pvT3LzdQ/v1n4P8x3gT//bqTAaHEgP\u002Bib575w\u002BLU/RJzdPmADmj5adBBAacAlwKf6J78Vwy4\u002Brfe6vmr5Ir/31LdAmlFfwMQiar8z3oI/WkelPsVk\u002BD4YQjY/IaNlvizlDj826Q5AjhcJQNpcbr9cBRNATEu2P9LKvT6ot2PAT99Gv6Cpnz\u002BsBmQ9BJ0PQAYISsBJFeu/h8QNQFAeCMBrLQTAz2X8Pg0JYD4KTDi/XX\u002BVvsDf9z69S5o\u002BbTVWPwZZCcC4z6\u002B8y1f6v3GXOT9zwBc/QzLYv\u002BKQFr\u002BoTiS/0DuRPXogCkCZ6TJA"
},
{
"CategoryId": 33,
"Name": "Camping Gadgets",
"NameEmbeddingBase64": "77CAvuq0/T\u002BhZu8/bI/JvywlCEBSY5s/1QYOQEa5u7/ztoq/IAAIv10J6r8x//G\u002Br9EbP06uF0DKEPw/HZGrvurQjT\u002BuFmq/2BzPvQs8eD9g2QxAgFlwv2wRfz7Sthi/QEf7u76Fg78klbG/vHgNPxTfP7\u002By6k3AoTSfP56DPL8y7HHAaynqPvYko7/YCtq9dG0FQAqxSb6zqcu/spqBPwj4DD9p\u002BOE\u002B38aDv/XdiL4oxPq9dpJUvycMC7\u002BqyjTAkbsUQMf4IMAkU8Q/ZE8FPQQl4z51vAzA8CaxvrB5VTzCuKm9hpOeP2zAaj\u002B8uxM/QyJVP9zr9z8brqvA/wXrP6ALSz8JjHY\u002BrXokwEHtrD/v/eg/pEVEvpgbSb\u002ByPTs/wAbjPqUKoj5loEY/kY/pPiySXL7e4ek\u002BatgvwEiAfD8yvSM/UbapvQLggz\u002BTJ5Y//Gt8PwTsGT6JUXA/ZOoQwKK1NT\u002Bbqa8\u002BC\u002Baxv1Qe67/p6Z2/xueCPwJsRcB2oi6/grEvv6Srgb/hIk/ANOAHQYbcFb961r0/jayfPxYaBD4wgYC/DuJewEhRe78mOHe\u002BJjzev0VWjD9P93w\u002BQKw0P45Vp7/zp9M/h0Bov6raBL\u002BwqQY/bp2zP3f/5D7f3BNA0Yg/wCYYQL922Mg/RfDAv6SvJUBcaPa/xPU8va62UUBYy8y\u002BlgfmPxsDYT8A33s/zAkVvmppSL8FEUK\u002B4M9tv\u002BDc9j53CTS/aTeQPwyKET\u002BW0nA/FNptvcvKbkDYgqLAuE77vPRtkT2okT8/X/FOP62UKMBQEMC/ovWLP4YDnD\u002B/C1RAP5cAwOYTqD9f6lNA7ouAv0Cg7T/wJ0q\u002BNGVrPwTCsb\u002BOHAG/bpCBP1ujsr8pGhY/z\u002BN5wKi4Dz86Q\u002Bw/Vj3bvlJMtL\u002B21w0\u002BBejNPy2jn77F3cy/PvRAQMhQU7/d48i/qAdRPnwuGMDC820/Mes7P3f1pb9keik/6bX4PkbtGr5Asx6/Clh5vtignr8GA7M/F2OHP7fsEcBmvC3AdMIjQCnPt79WpiA\u002BqcucPqLlCMCDjmm/bp1UQJotJcBbOq0/pOCCv3zUer8eLrI/fcMyQFhd/T/1IWu/gYcJwMD5dz9Vcew/IREOQHaXn790Jt4/lQuev46YAcBMWBU\u002BKxT9vRrGgj9q1w/AEEKevvsSBD44HGnAODINwPb90MAZzsm/AgcUP8MsHD\u002BqUey/7QeJvqmgUD\u002Bg7ARA5l8AwOAsHT4oxUhAc6udwLspnT4\u002Bki1ARxwlvxFSAED2/as9O8vgvwyMsj8M4Kk/bpBVvpwfSD17BRVA3KOmvRpUUb96rae/TXyqQIaS4D9XUj5AMbsTv1jXxj9cU9I/PnKIP3bWZcAvagxAl3hcP9xC5T5Kuy5ANj4uP4a0xL/m8oi\u002BUhepQF7pxr4yfDvAtAsJv3nR1L91P42/8L\u002BMwB0Kl79MJ3u/tqMMQCy2zr7Idi8/9YoUwDAmRkBnDOa/IJjVv/6tFEDuagTAJgkAQGgnr77LxI2/8EFrv7Jtx78EkDc/gHZgPrhy9L7w4J4\u002BQhqlP7ysur9fOpA\u002BvGp2QCkOCb6eIeU\u002BH7EkQD06X7\u002B5AyJAvzX7PZLssz89TMC/Iuqkv2rRJ0DeZI4/bn8\u002Bv5gXVj9gZxg/AW27v2bGSD8lyS\u002B/J0I5vy\u002Buib7arYg\u002BqvPSv\u002B0S678HN4JARiyAvrE38cDYPX8\u002BGg43v9s2kr\u002B8CMi/WH/lvY0y9j4uq01AIN6GPwz2\u002BT9otxG97QrAPxgeQj/avxU/heKZP4J5BkAKY60/FO1SwC6yez85\u002BivA7kRDPzk2DT/6W5ZA//Cvv0RWBD4kdL0/FemiP5B3Mz9G2Nc/SshzPwUhkT1x/Cm/WvT7P\u002B6sDL5oDhZAIHjMPhLxBj8RzQnAM9yFP90Mor90T8\u002B/oc0DPze/4r7IPtk\u002B9zToPl0q9r\u002BK7JM\u002BXh4/wA7L9j4Y6LK/R/KyvyIKh78/Q7W/\u002BD9kP0hJJj6b9ns\u002BjJUQv88na7/jT4w/xgL1PzAUBD9PIEbAdMLlPePaK8DXMV\u002B\u002B"
},
{
"CategoryId": 34,
"Name": "Travel Accessories",
"NameEmbeddingBase64": "owKUvhgOLr\u002BJ2g1Anrxqv76qDz/dmwu\u002BDANkQJyDpT90NzjA/Gnnvzh6T74KfX09t/lFPQ6WBEBgjBa\u002BehK/vzCyjD8w7IC93m83wJg2ob66G9I9tOKxv6HcCb8sEuI\u002BuDmuvVjNYT/o0We8IVvVv1h0YL7g517Aap4lv4Dior/7gTrAnF8ePu9rvr9gLEQ92PLAvHb8\u002Bb4\u002BKSm/XCBgPWagoD/9fBW/VOKQv1EOib/GhQQ\u002BaFnDvo7fTD82F5a\u002B2ATqPsZSQL5YbCFAUMWTvj4C/75cEPo9PCNXPlqB/T8AL\u002BK\u002BjMmmPgpAxD65Wn\u002B\u002B64A/P4GHoj6tImHANugNQFYhxb\u002BExTk/3e5ov2QOJEAYOcS\u002BqBnMvtNhcb63phw/Nuamv04ZNEDw8sE/\u002BwIBv2O9pD6YOXi\u002B0M7Av28XPT9snfg/4gqGvu2jzz4sEWI/DewLQDRxpr9AG5y\u002B\u002BBwFwANbbL/SfWe\u002B7VW6PmHZUMBvaA4/t1nbPhf\u002B2L84Wnk90ofrPurpwb/nHb\u002B/AJHZQJH\u002B2r\u002BYUbM/WHTGP3WUoz\u002BKy7q/Fgvpvwywsj4Ohcw8hUC1vxDfTz2x36k\u002BfXvqvjZ6Hr8\u002BZJo9QMZYv1Sqmj86GPq\u002B7rjtP3xbsb\u002BfdLi/bUmIvwU/kr/83h9AoUsWPxDL1L\u002BQFQG/luIbQEZmKkCNo/6\u002BNLLRP8grbD\u002BOQw1Ahp2gv8xkND8\u002Bzhe\u002BExplvwXKpz\u002BUSnq/\u002Bk3VPieDgT\u002BdhIS/VE/DPHidkD\u002ByjxzAar\u002BXveWbwj9GLsM\u002BBmKcv\u002BM0Jr/vvgm/cqaaPz4Z4z/sIZU\u002BX39Ev\u002BpY8r6w7fE/GPiEP9CXID9OxR2/x0EIQHTn/j7kDFO/by6qvl7SJkDJcUe//gKbwKuRqT/Ai4m\u002BMG9CPi6xpb4ZNq6/Blu4PmaWzr/Jbw0/yAwyQIgKTz6Xxo6/JTYAQNa5E8AhRr\u002B\u002B1/2lvWazYr/6xxLA6uqEPybOcD9yqwW\u002BelfMv2bzAb/0LT0/p3YqQPJIfz\u002BG4uW\u002BejPFP2GSBz8\u002B7IA\u002BWW0hv097\u002Bb\u002By5oa9\u002BiOoPvQfCMDeeJw/go1cv07Wc7439VO/\u002Bs68P1g8vD6r1Zc9lP0EwG1l379UGOG9kH98Po2FFL\u002Bf334/QvL3vv9EIL6wjAg/C5vMP2yty73ZoKA\u002Bkq7QPm93MD8OT/i/ykUHP2jpssAYL1I91cQRvzioqj/v95m/xjeTvZvbXD5RYL4\u002BTDMePgrT9L3n9Og/dwEDwP6YvT7qtYw/6uNUv07J0D\u002B4m1q99xqFP0yiM781LZW9rNejvihiLUA8T54/Vss7P43at78Smru9IGCRQMonbz6qohG/GL3wPDc29z2uFN8/krk2PsFRL780Hqk/WFJGP/WHr77kyBu/p6w3P14uLT7BLMW\u002B9CYtQDS54D38qS6/4y1SP14XrL6xPVG/vIvHv6C2fLyMfMQ/hvqOv76sA7/Aj5G7BgR7v9gvOT/k2lK/ilBfP45Qv74CMwnA3ATUP/gMur8yA1S/ZchGvwE9Tb5yp2W\u002B/tVTPjGALL\u002BPYli\u002BAPxROoRlF7/QfwXAAZ9NQDiZ6z4MJ0Y\u002BczenP8Ajsr9cc8E/LOwWQI6Kvj\u002BSO7S/3\u002BplP9JfOT31OU8/XEanPkG/HL4cUas/aj0IP1/Yl781LoG/CKaGv4IGcr88LgK/y08wP\u002BRxjb5uWhRA0lHevuxcssBK/hw/bpYaPgoCG751PbS/wE8KQLu3ND9oog8/rByLPg4Ahb/tTZ4/5XrHP2VYqD\u002BuQVA/9J6ePy5njD92Dpk/xmCcPq/e3z\u002BnlcS\u002BrlF6v5emkD9IxpFAtw4PPtLGTL7lc0U/YBWzu16/d7\u002B/7Ya\u002B5qRcP5Wxfr/wTta/qFKcPqUuqz40L\u002B4\u002B3ynrviaye7\u002BAkH68hDYTvrm53b5XiJy/w5YtP4HUhb4Q0UG80OedP7lJY7\u002B2UDC\u002BbpaovuQvTT5Mry4\u002BpBL9PiAzk79ee5i/jbTAvv0\u002BmT\u002BTKV6/2MIFwIdqOT4ePj8/fMKDP2gpFb9/jM\u002B/8UT0v2DE97\u002BFg/Q/"
},
{
"CategoryId": 35,
"Name": "Outdoor Safety",
"NameEmbeddingBase64": "go91vlJxGr8Ds6Y/Vhdgv85N8z\u002B0iH0/KLe8P5BCoD4DfJ\u002B/qFevPQPsPL\u002B2mfi\u002BHlb0PZgB0j92bQG\u002B\u002BBUuv9gg9j8Y9b0/pUCZvn0azj/0KJ\u002B\u002BHem2PqsUmD5QF66/Gw9kvx/cxT8uoue/Fnd8P15ehL//vv\u002B/3TyLvwa0CL9/xZq/gXkRP7NU5r\u002BiPTe\u002BJUOAPlwYyj5mdRS/ZlIUPxg4sr4ccYI/Ni2nvt8DE796pUO/Mcp\u002Bv2zQmz/7jeq/sIL8P5vYnr\u002BcMFU/3yySvitYOL9DG64\u002BgPc4upofir6wyHs\u002BZGWSPxs6Kr/Cvzs/RzyBPyLvEj8SgKHAAhlHPoAPsj8CBcA/6G2fv12TwT\u002B\u002BbJE/3e4Zv94h9r4kqM0/oDZNPxvClD64jTi9HNWaPwmTDcBgQ2i\u002BJ6GFvzQ6D79kdGQ\u002BRtGvvxIjWL9pqjM/fnhsvkoIHz5nb/0\u002BVnMGv5pRHED69TZA\u002BPm6vLW\u002Bj7/c8VM/yjGtvqJ5Sr9zwEO/zH1CPxQV7L\u002BSUVa/lyveQK4L679O5q8/qrg3v\u002BMKgj\u002BgDKU8tA99vx6k/L6EvPS/5MBNv8BQCb\u002BINjNAJ9oQvvisIb\u002BJwno/TLvTvxptOD9gdPe\u002BlL2nP\u002B7YSr8qpjY/rkR5v\u002BebNL\u002BLCso/kiOEvu2bmT9Oowi/sGS5Pw0yJ0APhtc/ztNPQPtJYT9YI9i/y\u002BWwPkQVVr/0OjU9sQ\u002BwvpqqXz83urI/ZFX\u002BvOoh4b7/va4\u002BNJ\u002BLvx4svz95aE7AavILQCG/Gb8eg2u/5I2Kv9zmdb9\u002B8Im/LgzkPQOpTL4UMqM/lIXCva5JrT9uC4A/vJSwvXreBr5hMVE/qQI0P8dMcj96WZE/1wtPPtENsD8Mqpa/c3k8wGD3U7wIEYK92h9BP1Rgqb9Qkms8gPLVO5DjIUByPbc/2qMeP9SGdj8p\u002ByXAxD3mvnam57\u002B6R7U\u002B\u002BiCCP\u002BG2HL9ojSq/6ASMP5SrWL\u002BT5XE/Zl72v2CCsr7EbBm\u002BTvYgQJrXC8DGnQHAY6VXvzQ/Rb9iv7S\u002BKPTNP3GE3L9CGKW/6sm/P5S/wD0/JAxAvnuev5zSXj5pNlW\u002BPD6oP4nOB75oYbc/i4QKwBRZ0r4386U/i1whP8TBnD58uco\u002BQjfwvzEQQD9YEzM9syKkvlaMsz/y/Ao\u002BxAvkvv8sHD8JOcC/M6KVv3v/q8CjDR7AKOzLP7bgTb32TlK\u002BOG0Uv43QSL\u002B3koa/2pN7vxA9K71Zc4BAWJoYwKgor74azb0\u002B2SGrPqOWFUDQ7kw99J7Qv2CCOb1djV4\u002B8MSNvl5gjT9VaJ\u002B/k56OvuI8pD7qT/O/PEd/QFbqCD5iCIk/kEmxv72Vgb\u002B8FJ\u002B/t2qtP5xqGMBEsTk/lUgDPyq5vr\u002Buh7c\u002BkoQSwFKQUr82678/pzNIQLjHOT1XK12\u002BquBOv2w\u002BMsB6goW\u002BKW\u002BlPiSFgT/O8v6/bhqiP5iEfr0i\u002BiZAB46WPRR55T92/u2/tgmiv8Cdpz9Um0W/ztKuv4yDir4KBUW\u002BOBJLPxA2rr8edes/9tkKP4TlQL/UA2C/fm6BP7CVuL56abK/QFzaP9Fcab76yIC//dMHP1pOpb5qFM8\u002BthwwP7zmQD0Eipq/f3L4P/ewy76Q4Go/G5\u002BLP\u002BTkb7xz6UO/WMmxvyHtKT8s/Du/yAhzv/D/xD7eXYq/P7Z4vl3ADcCC0UBAq640v2fP0sBPhBu/IgM0v4hRP7\u002BQ44q//BCpPtUM/z8oMDpAG3e9vmpc3z2SEw\u002B/VfqzP3cAUz\u002BiVNQ\u002Bx2wzP1g7Zj\u002BtEi2\u002BdVo0P0Ky3z44xhW8T9pVPyLyOkCxSnFAEGa8vS6dnj8wTRNA6spLvyDTc79SO4c\u002BdjGgvg4U1j\u002Bc3vm\u002BqXzmP2aE0r9b75U/qvWbvj\u002B0WD\u002BziAk/fEZCP8AtsL7Syie/YloLP4d9xj8HC3g\u002Bgg3BvhOVbr8gubO9Flx\u002BvxrUVD6SL5c/gp67vt1KxL9PscC/QZs8vyljsL/loWY\u002BCtOwPQ5Kl76kheu/ByMEv9OfXj874ce/2EdWvyEjjD7ykv4/"
},
{
"CategoryId": 36,
"Name": "Wilderness DJing",
"NameEmbeddingBase64": "kCS7vliZuD\u002BEDmg/Lo\u002B4v8DRqT\u002BEH/I/t5\u002BnPg4/5r8W\u002BkG/jD4eviIKxz11AKy\u002B/dkYQOH\u002BB0BcKeg/soDGP3uwfD9E\u002Bcg/XDdpP0hCkz8WOm6\u002BtLGlPTdkJb/4ORHAPGvrvwpJBz9ExuO/8yHCv7frmj4zLCHAw7glQB7Wfb9/nKy\u002BYAOhv86Xyz9pgc8\u002BuUhpvyR2Tb9SP4m/i1wpQC1ygj9UpwC9xrLrv1pMkL/G1fw9p3BEwMk9Yb\u002B1DRLAxsRPP2wjFL\u002BqISK/fOy6vwpZtL7h6JW/SB1fP1YqLL6vuwNAx4rMPyNUAr/deBa\u002B/g87P1kRpD/kap/AOwrvPyzcur1Kqlw/Ujz\u002Bv\u002BLrNj8gKmo/cJOOPpTbML1/BCRAzsVGPw/\u002Bir6Ywso/IRdvvyJA3j4AMKg/urEAwKxKR75So0Q/jXoAwMBcub16/w/AuV\u002BZvoHysr\u002BgfSc/aGDrv80RlT6etvC\u002BijEKwDSj7j\u002By56S/2qkavwWyPsAZYYu/wzKpPiDbQz7B0qa/nMzmQMUznb/uumg/7CxTP2uCcj\u002BuG1a/WJsAwNB89L\u002B6X1a/yCJ5v5ZllD3S4Tw/TV8KvvwlgT/wnhI\u002B01Hovuvt2T/gZce9llhzQBzQrb\u002B8QWI/UIvvvurRuL/TfNk/0iovvikq6j9/xOy\u002Bj8fXP7rJLUBXzdE/QXDDPyTz8r2YHuq9\u002BHZ\u002BP\u002ByCyz11vKu\u002B6pC6v06O5L1WbvQ\u002BWPMLQIdZrT\u002BKj2a/7ym8P3MjhD8jgGzA3sVNPUU347\u002BtXB2/O/\u002BUv5D6zb\u002Bq/4G/xa8tPpIYeb8wxMI/paKBPQ6p6D\u002BOXYS\u002BesYUQCQYyj4KwOy/BHJhPxxtDL6XZva/CAPRP92QoEBEQEk\u002BhxolwJqHF7\u002BA1WM/NRSLP6SIJb6uF4i/Lc\u002BnP\u002BPvkT8schA/nUClP4pDCr/WYALAWDcYPwQB47\u002ByUClAJ/InQECSI7/CYgs/tB03P5VqbL\u002B0a2K/AjAPv9aXZb8OnZW/Wh0YP/9MGD/u\u002BE3AUUkJQEb8/b3CtkG\u002B9kHIPiBohDwkLRo/77AHQHZStr\u002BHTC8/owa5P2aMd76YQFU/EzD1P1J4ST8mA8k\u002BpOikvpvmHL/JQH9A2C8ov1G2lz6qew5AjtB8vyOyDr/280A/xpvOPhzg5j8Dn3O/qGefPiPIpb9i7RTAhFzBvvpH6MAUyqI\u002BXFShPmIiOD\u002BRO10/xouVv\u002B25mz\u002BYzU4/mchvv2mLrT/ac\u002Bk/VlVZvxge9T\u002BN3fo/K\u002BOKv0MKTUDw8oy75aM6wFbweD9o8I\u002B9XDkyPjqnXD/ryBY/06yvvi5D3b7gbJe/QGmjQA0h6z\u002BMnZI/bDZqvhg/p758saO/VK8APaxyusBg\u002BEm/J7rmPmwiBkAW/WU/m6GBP7\u002Bg3r8oSYQ\u002BZTpAQGAuRb3mHDPAYOQdvzcuA78\u002BP5W/AE9HwKiaBz9mux7AohQ8QEiS5L4ooJC\u002BFt64v3awxj/zoLu/2aIOwK/MB7\u002B3NnO/eRHlviYVED9QfFHAeSyFv0SNWcBKxOk\u002BoCaHvuAZe7\u002BieQk\u002BopeBQA/3ZsDiDfS\u002BtBeTPf8pCT8OPUU/BrbKP8/BGr\u002Bvg46/4uKhv6IAkT9tVg6/waFNP71TFEDVSm4/eCZDvggIJr3JJAu/VF1KvT1tH0DwQcu/MZ\u002Bbv39okb/CXYs/doawv9do0b7nnxBAJOjBP6eo0MBPM86/GGa\u002BvwxiZL5HaQDA8mXUP9Y\u002BZz/OWTJA47ibv4BByL\u002BWOic/qeAdQNSSNj1IRr4/qGH3P/hSjz/yqwI/6dnDPxiCPD7/AEbAkWnTPoK6kD/s5IxAQKCCPorx7z944\u002B\u002B9iCXDvheKTb/u93s/ZwcUwE4uAb9KWda/LMwyQO3qcL9hdbE/Y/uLPvFfK0BCTZO/sqN0P9os5D4JDYW/HC8Vv8DzF0Bm1mg/K5invx76r78F/iq/84z2v6IvRL4O/Na\u002BMOn3PI0x3j6qBYe/asooP6ieub7w9hRALYnDv0AEmrrjb6I/xVi5vrbrkj8r2AvAkEIGwJl0GsDyxKC/"
},
{
"CategoryId": 37,
"Name": "Adventure Photography",
"NameEmbeddingBase64": "nusEv\u002B7CID53Eh0/ajRAv6qbyj6kk\u002BU/YkPuvfnJvr7wpeq/IMNlvWuCnj9DsPS9gNfDPrrJwj8sjdK9iTZrP6vsB0BRat6\u002BGFWevyyoFkD8NRk\u002BJL8wvz68kD\u002BFdWK/MH8vv93djT6ixzi/92Vlv8BjATzYreK/c/tBP3LcZT6iGu2\u002B/xL1v6Q46T5EdjJAwjMIwGKsNr/iBYi/y8l9Px\u002BPRj8Sme4/wr\u002BJvqPnHb9e4DU\u002BeOy4vzN/sr\u002B\u002B5hTA1jGpPnLpcb9ebQu/LmF1v\u002BpZEb\u002B0r6C/wp6Evuv5cz/3RJY/ZJsAvjrJ3z5YPSY/WlyCPzzMqT9YUl7AGD0lQHRSNr9hyBRAQoyTPQyorj8M2Qc9UzYXwPHqeL88WQ1AC3GRPiFLrj9D6XA97kGCv91ABz\u002BSnA2/Ku7fv9Dc178EKwA96OFOv2xvuD9q/zU/bCD9P94WL7/iuVQ/mPEFwO5RxD/YvSg/pNk0PWl8BsAa7rC/lYrkPuu/cL\u002BIpxM//vpBv6060b4AfAm\u002BpZ3FQLELiL/GpGo/xd0WQLlAnD\u002BeKlM\u002BSqr0v7TK9L7U3NE9NiEKv1s04z0ifUI/OLlePQbUrj/sVqi\u002BAysLwOKa\u002Bz7FRay/1kInPz1hg79g9qC9EWWUvznCHL\u002BWbF4/6KauPq83mL8EmJy\u002Bi/90QFKBH0A6Rbk/l92TPjpWlz0QbF4/NrUov6Dveb9Nrpi/jFdsPn\u002Bi3T66Z4e/9CZdPjD88D/n1ae/IoI\u002BvjO4tj9UqiDAuYOzPmHle76qd5c/daCNPgQvY794n1q/GO\u002BRvVF9Gj6qqqI/KQWYPoKdkj9lhS8\u002BSOtHP\u002BsWMj80DeW/6\u002Ba/Pj6Xk7\u002Bbh6i/ugXOvR5OC0BZHNy\u002BpstpwIEp\u002BD/MjyS/eDeMv5xahL6MihW/oPjNvbY4jT3c\u002BmY/ILcRQGam7z6N2YW/8pSRP0Ywwr9kygw/Bj6ePzBjer99WQM/39\u002B/PhJWEr\u002BEii2/O\u002BrjPtSpjD1N148\u002BlAaYP93TSj91wnC//CdEQNZqMr\u002BgibS\u002BNb3HPkx8/75\u002B1aO/VKyLv7Y/0L9lNLE/5jGcv3ICq72FWfQ/stoNQHT1ML\u002BO27k\u002BB0tPvoFg87\u002BlLqk/\u002BAw2PY7bHb\u002BonjU/DZwIPljvlL8SszO/HPacPxtotz\u002BLNQHAje6xP3FmpL\u002BBPBnAmcSoP30GtsDmT8\u002B\u002B5NOgviPBVz8rZCPAWjDPv3Avqz96bRA/GGUhPwqX775mYsk/\u002BG0iwBMX9D5JNzc/vSIpP3gMMz\u002Bf99A\u002BtwKavlGbkz67ZWe/ZqG2vvJqyz\u002BOJDu\u002BdnwXwPgFoj6fCCG\u002BX4CdQHpvLECEsiC/GS61vgVENr6e7JE/VgXiPlNjrb/2WAS\u002BipU9v5/\u002B\u002BT9\u002BplC\u002Baq95vrO7h79yAEo/0JodQPhkpT\u002BC2Ay/znJZv0RRZT2ssbi/6NrwvOdYqL4m7rq/OF6uP3RMUb9K\u002BYq\u002BjPDXv6w1TT8sOiW/g2wVwJ6Wsj1aWm\u002B/MSdnP28OkL\u002B85Q3AYbIBP4okYb8iW\u002BY/jowWP5Ja3L60LtC/\u002BvEIQF3bHMCC4jS/gPYKP/4qJT4OVy0\u002BbD7WP/dgjz967B9AbBiQvqZftD9g1U6/6wSBPiI7Yr8OtKk9rmfrP/pg\u002Bz57Jpm\u002BM8RKvwynOb84CL6/P9yjv2XmZ78DRs2\u002B8i3Mv6xNwb\u002BNoAhA262EP4QCqcA37Ua\u002BpzWDv6tjd7/wu0q/onxUP\u002B9Fqj/\u002Bq40/0g\u002BEP34\u002BlD/DZT6/obCdP9q2bz4//iU/CsIkvvBED0Ayxds\u002BxLsBPnT4D0D\u002BBzm/oBk/P\u002BO7wj8xvz5AA/ifvz\u002BaEcDweN4\u002BBFENPrSghj/dQa6/rRoUvrw2cD5hDVS/WknaP3wv4j7wotY85FG9P5Mc8z5Yeuu9Vbgyv8iabz0SkgC/SyqAP8AiO0BNEDA\u002B0LeLP0WFrr/roAg/nKx3P96ikb\u002Bla2E/XlQ0v6\u002BvMb80T9W/PA0uP6BUoD/pf8I/rBVsv3xS\u002Bj3J5yM/4BWOv2DN4j4Q7wXATk09vx3CFsDWZ/K/"
},
{
"CategoryId": 38,
"Name": "Extreme Sports Gear",
"NameEmbeddingBase64": "edfcvwQmIEC5I4o/ZJUZwGx0B0DOEgI/Ni77PuG80T8CeaM\u002B3t3UPqHBUD91gS/AyXCFPnYO3z7eNuU/M9QvvlaoGECp9Jg/Rdvgvny6AUCYZMQ/zKiZvrWGgj\u002BhBb\u002B/qYG1P/WNEb8DbXG/KEX/P2XXXL\u002Bc\u002BZzAG/ZVviNFRL7VRxVAMQ6UP2NWHb\u002BcaBDA0oVUvrQ727/RM82/\u002BeA7QPyrH7/i8gxAFrLivzSde79xTCs\u002BjKEvPwWz/j4DHY\u002B/LhWZQOgF/b/SNN4/7r9MPxJCwT9a4nu/Oy2PPyVDtD\u002BqDGc/74YRv\u002BRTnD7S0z8/DzYhP1nI8z\u002Bb86HAFYNaP2o6xz6psyZAbKitvzRQS0BX9ao/Rv\u002BzP\u002BDOmb0EIlg/eXHdPxFvzj\u002BoZNM/shq8P83ryj4cz\u002Bm/Nqy3v4JtMT6n9E2/HzWZwLmfjr8cUc6//8GQvzzEfb9WHgG/LI3jvzpz/D\u002BZpRJADhIrv29oxz/8SNw\u002BW2sPP\u002BNMRL/Udp29plm3vsN10L\u002BBlUi/QYsIQRswtL9\u002Bs7m\u002Bct3QP3bixz4aBLg/5MLCv\u002BbFcz3W0Qa\u002BR3oFwM2XaL9V/4s/RaImP53SYL9I/us/eXI5v5chsD\u002BPFy7A9CsHQGN/tr/A/x09iJHPv1JUDj/BapQ/70rOvi5QDcAzeZq\u002BpOCFvC9QDUATIHY/1njOP9HVyT6dF42\u002BSwD8v5KmD7\u002Bu1RA\u002BpOI1v6ggWD8I1Fw\u002BlEHyvS1Kk0CNvRO\u002BU\u002B\u002BYv8bQikCiwLDAcZ6mv0g1sj3nl8i/gp9hv/FqNL4sIDE\u002BElZPvn9JIr99Isa\u002BwOHbPqwoTr7WcSg\u002B2gQ6QLDDTbwV6/a/HiPAv2IA/r2PLeG\u002Bzh0hP9Tug0BLhIa97cVxwNgRFL2wQ5G/cW9Vvyp1X78wSBy/Ot5vv6O1MD8IyKQ/BApaQA7zcD1UW5e/3CElv5Lksb8IgfI/vtmZP6RlcL997\u002BW/SOL9PijDOT/8iO6/WNocwJHph79GFqs/Pp5\u002BvcbNEr8rz2W/BuB8vmRMKL96WJe\u002BWJ2eP\u002BZWYL5gyfI\u002B6ye8P9XIBsAIAYm\u002B5C25Pr16jD/wSzs8s0\u002BNPxNcYz\u002B9ZLu/4ov7vy4wGb8q/V0/okO\u002BvNXIMcDyj9o/ZYEFvzXCH74o\u002BOG/ZF1CvwwVEkDg/l\u002B/dLSYPhmQbT/uFUg/pu\u002B5PsJCw8BwGk88\u002B9Q\u002Bv/25oD84awxAUgwSQHpBsz93dqM\u002B5CoEQD7V0z2U1YtA3n5eP7992b/pY0S/oBo7vgRBCEA2DW6/F8Elv2z4zr/KdF8/9LJDPyC0tT/JdnzAexUJQPhlsrwhFf2/1v6RQFac4D/aXaI/AKkAwFcOq74XHf6\u002B\u002B6HRP1gXS8ANy5M/NvMSv9Z23T\u002Blhuq\u002BuhDKPoA58L\u002B\u002Bepu/QvqEP\u002B51hD98qfi/fVmEPwEZAcAcIY6/Tkl9P27CLcBTkj8\u002BnHnnPwTuEL3uix9Ag7Gev0DkQkAGBP2/5/uNv/JGi7\u002BcXZe\u002BlpJ/v9yy7778wg3AtFM5P20/JMBiVBk/CpAYP43PiD/WrI4\u002BOxJhv8fyHsCUC/e9WGlhPsmQe75CGCE/zdl4PwHzoD5Gf7M/nkEIv0z8Zz\u002BgPUs9T/28PysO9T6AlqI/zRdOP4x0WT/e/qG/vMg8P9bgqz5jfQa/\u002BrZWP0ZVRr/49P88IBcBv38Xir83Juw/fDEYwHR5/8DKKNi\u002BNKycP\u002BqOA8AacWm/gLSOv72ypj6eMkc/pPWNv5J/IUDKccC/dEwIP/Lakj\u002BOgYM/cDfHv74TnD5fwqa\u002BYNklvYpoFEAx0MM\u002Bc64oP8rvtj/HpIVAnFg8v3z8R0BrlzFAezrrv1C/p7w24Pa/pvi8v6vbKUDQPWG82A31PqTQhT8BSz6//IWkPtLGRT9YqxlAJYCBP4iOdz1wTmA\u002Bk6O1v5ZGGr5j5Ss/tZWdP4azzL9gF9e/pR7fvyi1Wb/Kea\u002B/n7UQwK5oXr9WrJ6/x8\u002Bxv3xEH71ST7i/WCipvlD9db6VT70/BFwewICCJT7anJ4\u002BjgRxwOuPiD9CS8K9"
},
{
"CategoryId": 39,
"Name": "Survival Essentials",
"NameEmbeddingBase64": "RJuOv8uyrD8QAhFAqOzOvlPgbUAWhiVA/Cr9P/EX3T8jS/c\u002BAi9rvx7VhT4awQbAPQuIP47evj\u002BiLgM/mHkiP5LYFj/GQEpAPozev60Wcj/hm1G/wZoXv9oL2b2ju\u002BO/JrGPP2KFaL4ezSW\u002BqcysP4B0\u002BztYEHrADpj8vpC/kr/pJDG\u002Bx16jPsO0nb8zkKo/iMiXP2IrgD/g\u002B5u\u002BkpesP0Fnmr/gIh5A9K1svqpWCz81cUg\u002BCpHEv3/EDL\u002BGIcu/rNEjQEpR/78gZGC7z\u002BapvjxEjL8Mdhq\u002BCmOyP1rM0r8H5hk/EFp7vFJXN75DQNk\u002B2xG8P3z\u002BGb\u002B6K6bAfmRXPpb7EkB6d1I/clYYwLSBOz97S/A/r7KTP3aVxr\u002BLT5w/p1MfQF1IMkBM47u9aMv0vqx9wT/Z/6C/DrlQP0mDpj\u002B0Z1c/0AMRvia3xb4K4m89dEIAv9IuF78U96Q\u002B6dgEwKKj6T6tMbs\u002Bpukrv0uskL820vQ\u002B\u002BOCZP5J4cb9dcp\u002B/au\u002BNP\u002BU1ML/Treq\u002Bmfz2QItBqj7G\u002Br4/37xvP1A6Vb/LR3w\u002BP13CvxR03T5g8Y\u002B/jLuOvmgqyj5zZqu\u002BjgKBvvVEgj6frd2/p0gBPyL7F75kubw9IJHWPitRMj6UyPc\u002BxJH6vjJ8\u002BL6Zv0FAaPUEwGGxuD866Mc\u002BQYG\u002BP\u002BplEEAgCAW9PpSoP2YCBz\u002BLInM/igT6vsSSiTzTiRDAM\u002B6CvvQy0r7pi2s/MiShvTegXz8IYbg/8DMEv2k\u002BkT/qUZvAKN7Dv6YGTz\u002BiLfM9DM6oPQp\u002B2b/U85w/dFckv6mx5z1aFqY/G/kAP91MTT\u002BbX\u002Bu\u002BFw63PjQODMDDghXANHgJvayVpr8w44q\u002BE9bFv0cLkEAI1rw\u002B/HgAwBR\u002Bxr/oE9w/wvs8PwOppj1KXew/qWHdvpgnwj\u002B8w2K\u002BgxXzP1YmUb8hV8K\u002B7mMwPgLoE8ByxyU/46tcv60xxb84Hre/jv\u002BnPwD9fr9knuq\u002BrJAXwJ4sjb9ZNQw/pdFpvlmqMz/pfU4\u002BXjAPQMgGjb9mpxO/6o2PP2Iw87\u002BR5Im/5hUFv1rCC8AajoM/ViHvvvDyBbww98y/\u002B/MDQGMWAEC6rMQ\u002Bf4ojvqv/8z9uerE/O4\u002Bjvv8J8r1EUKU/L2bqvobzvj7N3Ay\u002BFOBCP\u002BBcpT/Ikla\u002BgMSGP0mghT8YvYS/surcv6Qp\u002B8Ba0s89OA7WvkJGgb5Lcrc/BsuPPqwsIz9\u002B3Mg/ct87v1Kbbb8DNP0/jU4AwA4lEz/8z9g/YiSvv0Bojr4XSVa/GoM3wAYF8L161Kg/lCVGva4l8r\u002BlnPq\u002BPQ\u002Bov/C9Cb91Au6\u002BapiWQHeyEUBQcOQ\u002BmuTbvzRyB75QHS5A0usBP79FssDcH\u002Bw/FWWZPhFN1b92wI6/XpSKvy/tGL45fq0/rpFgQCBrHr5kW4u/sBxpv\u002BPEXcArdM6/48Q/QJerIL/Et8W/WUG1Pkyqrb2XK\u002BU/tOg5wOt5Uz\u002BiCAu/Rl/8v2DbEr85Gi3AMlhzP6woI79U0hC/xCibvpLxkL9AWuk/lB3MvzcMIb7q2gq/9CqIPxfHg8AwSgzAXfBSvsr7CMARX5a/U3ZnP\u002Bx0AT5M2EK9Tg7hvuj6yD8\u002B4J6/AC\u002B9Oy9Zhr\u002Bmhbm9\u002Bh84PxRGtj/ise0/WIpFv1BYAUC2p7k/RGdxP4W9bT/sQYk/PkG2v9Yotr\u002BgG/0/eimGvo0U/MDOY8E/OtSFvIBNMcDYi96/SFvsvrejiz1h2e4/cI6zvg9sFEClba8/\u002BEWKPwxLgz\u002BzVp8/d7GuPqdGpz\u002Bosdk\u002BSFjnPDzxUb8MFBDA3sQGPmJlDj9ATapA7TZgvoSscr\u002BpKtw/VMq1vnIPKUBtOls\u002BpCXDPY06zD/17KU\u002BTL8VQEwU6r7COTc/CMy8PzvrFL8EZPw/yiiZvYOMKD8SOOM\u002BA9AywIhRO0AVZgtAwIn6P4e9mcADu/Y9woNpwHJbt7\u002B0Ng\u002B/4kw7wFBDyb6gChA\u002BnM4FwIeuKkA2is8\u002BoVY2P5blgb/bf58/v8Sgv\u002BrSoD/alJ2\u002BT/G3vrG9XD4G/ys/"
},
{
"CategoryId": 4,
"Name": "Climbing Gear",
"NameEmbeddingBase64": "XFoxwLpmXz\u002Bojfg/RhKQPgKsDL8yPr4/ULnAPwh0FD/IAMC/ORajv3YnoD/P/Li/m8UpP61eyT9UefA/twk9P86Iuz8L7\u002Bc/fwPPPdDL0D6nKhQ/1sICv2ykiL4c1xa9xWfnP87SbD9ABby/eJJEPlofAj9UVzfA4IMWPzfEUz9tlAq/qC4WPlrNb7\u002BEMt8/UHfPv6JT/r523l2/e67cP9jw8z5Miqc/rHPuvoAo\u002Br08KJM\u002BQdRSPwBttjujZ3q/IpmsP6QdSL/MSeK9ltmQv8\u002B8KL62Nic9HxooPsrrGD/ODl0/3m3EvtrHWL78Mmw/7j/LPk7s0j4Ngl/ARczsP3ycTT8peTdAXH8AvzK3lD8Rokm\u002BysKYP9d6Fj9yj5U\u002BO1hdP\u002Br/4D3sR0w/dG7rPhhv1r7SjUe/PTzgv9uN5j2WHVy/026iv51FCj5RAwM/eu4VvwyaVD1j9p0/xY\u002B/vwSqoj8em/c/c\u002B9FP/RwR784aKS/0e\u002B1P7qczj5JCY\u002B\u002BDDtxvymkRL\u002BsLuq/eWnwQCheub/Y/x0/Gg6JPzl/2T8kW\u002Bk9PD3Fv\u002BjXjr78Zi0/1KGavu/s1z208fo/hQ4ZPzcT2b6pHI\u002B\u002B5xi9v7CMsT07wAfAaDOFP7o/p7/QR3Q/RnIIwLL4Gb\u002Bi9Lo/0KRmvyM7or/Oooi99jDHP7pkEkDOBkU/paLOP1WbsT\u002BXLQy/xOOSv7vYPL8yT7G/gwhDP0qCez9Qc7e/EJ8AvbaTDEDV7f\u002B\u002BBq4ePxcSSED5X2jAvnYFQFNKij6shP2/F1Qzv43bQL4OYpq/Erfmv\u002BLc5r1un1c/LzBHP5yi7j\u002Bads\u002B/vhxvPjxYLL4U0wfA6YIvv/C2Bb\u002B0SgK/jouDvyvbLkCyhaU/p6RiwJTYHz8kMzo\u002BhDthPUQs979GD9A/aG6VPi0u9b6Zyhk/WpBQQLIEzL5QLyXA/9twv2bSAsC89Jk8KhPHP0Di8L7YFFK9u2f8viF4RD8\u002BDhO\u002BmhXQPvxQx71Ee40/chDRP3L7p78EPzU/9qOAPx5YAb8AHKw\u002B/JbmPqvf0L9MpbK\u002BOkGev9A7Nj70cH4/QAjAPrj7BT9SdJA\u002BrEi8P6a9oD8P/4K\u002B6qBUvzSih7\u002BMDAE/\u002BlpSP7aKH8C7l7Y/umdYP4C4FjvWGW2/Jl5IPz6o6z3alSrAp1AXPzLlSL8GqeO\u002BRkEBvgyHscCFObe\u002BeeMKQGdt/j/u1L49A44VQAmKxj/BMWS/9lfJPk0yu7\u002BAJmBAFgPvvuURFr/wc7K\u002BF1jwvhefCUB\u002BPqw\u002BOiMQwJdWs77o1wW9EgLePo8xiz/IvSbA/uqDP98DM8AAzyW/UCNQQFJTHT80SAO\u002BaFB/PYoTZ7\u002ByDyE/4dBjP\u002Bzq/7\u002BCcbU/x2Uov3Xk8j\u002B2J6e\u002BfLbzvrrHb761WhS/b5FYQCj4/j8WbPS/yPrlvBwHvr8a9ou/fsYHQFLunD4/skfAehXuPmznhb6YAhpAkv1nv/uy7z6UWeG/tqvTv1W\u002BAL81RL\u002B/DQ9Sv0YZlb/XBbO/2uYLv0tO5r7T7PM\u002BkM7vP7Tyx75Yp88/wc7LPgkuIsCzNLO/K1y2viBGwzwck6c/m/Nvv/tOqj7duqM\u002BFu\u002Bpv8TCCUAy4dK94pV\u002Bvw4A9D4u268\u002BFlKCPzSOTz2YEk2/YNELv6g/pT/lm2y/MBmivLiTdL\u002Bwhxa/4famv8c\u002BrL/nJl9AKFk6v9CVwsDmsk6/7LEmP6z/1L/QBv2/XFKevoCYez/DwdU/c5OtvkZZ/j7a656\u002BC4gJP041MD85E3K/Pgj5vgKEhD9OGTg/6jW/vQW58D\u002BNH9c\u002BkOHKvCZSLkBaumBAv5GhvWiTsz\u002BJC/0\u002B5KcUvmwzab0xDqa/A3KuPrqYTz94dt48ZZe\u002BPhmUgD9atQE/IMA8P3L7vb1rxGg/oiR8Py5bhr8yw5C/4mDvvthuDL9DWwJAv58JQDpTW8CkI0a9FuoIwKGq0z4AZlA7VqsrwAqiTj\u002B2mXA9knY8vkawaL86Ace\u002BSMX5PT5AGr9Y\u002B/6\u002BSPgKwJIonz4vYUW/ZcHsv2i35L8xNMA\u002B"
},
{
"CategoryId": 40,
"Name": "Secret Communication",
"NameEmbeddingBase64": "HMWYPgAm1joC9U6\u002B1NW0v2DMzry1LpI\u002BhwYfQM7RxT5izjW/KmpaPgkxNL\u002B/XEg\u002B1NxaP1CuET/nqwFAo/66PyfejT8bb7q\u002B1pB4vl7l4z6A2NE/YuSWv2DcOL6Lxhc/erWzPsDSfT3lbK\u002B/6Gvqv/JroL\u002B57x7AYunJPgqv\u002BL2m2s8/JS9KP\u002Bg4hT8mxa0\u002B\u002Bhl3v\u002Bwrnb\u002B6aOi/XsiuPyOwl72DqnC\u002BLNh5PqoQ/73uTV0/GobJv\u002Bz9\u002BL5mj1y\u002BtoR7vhz4KcAIIe4\u002BZ5H/P\u002BQqdr86ZZQ/jSeAPzJN9T4gr/Q/lEcDP5aJO7/EA4Y/6nqDP8FYpT\u002BuroDA3I\u002BjP9RNzD4bXaM//NTzv4BHKzuMeN4/Wls0v1\u002BIPz\u002BzxBY\u002BvOEFP/7rFL0sJ40/GN6KPzeOob87XO2\u002BV04Av5KFDj5I0lk/fveSvyqyCT/96g2\u002BUf8LwAOHAcAXqAJA2DQ7v1R5ML9MhgW\u002Ba2T8v2yvrD2CGqu/jJZTvrihsr8UeZu/GiKKv8xpmL/JK6W/9\u002BzIQK8xiL\u002B4YQU9kS2EP4H\u002Bf7/CICu\u002Bki62v9omkT2o7Pq/CmpPv5WaPkB4DZ4\u002BjqJyv5CCEbzKric/kLgvPDfjE0DsnLg/Fo/HPzZa3r4Iib89Ya6QP94m\u002Bj6sIxE/vJFnP/AIpz\u002Bdd12/\u002B5CIPyXnCUCUgZG99L/5P4g9Yj8pCQJAPlABP\u002BJGYj/eWHo/1vvfPtXxhL8679o/oBdaP/Tk\u002BT5iPwE/YMKLvLCuj75yj52/jtEIP\u002BYYTEDTLo0/DZ\u002B0PUp0pb/32wI/cnykP0ufSL9t1eg/JU7AvuFJij/c4BHA\u002BFKkPrq0tz\u002BnRO6/LlZ9PxAcmT9RxQG/ZWugPvbmNEAwfrs\u002BByFxwKjeOj8Uw12/UWy9P5J4N8ASfiC\u002Br3BmP3wegz\u002BQDeK\u002BXorJvg3SkL45EwK/cMBnvQdBi7/jlYU/edTmv0A/A7\u002BOgnm\u002Btq/BPx/HZr9Wj\u002B6/3LmSP/\u002BoQz//3Dk/Oe4UQHrcsr/O9Z4/rrxAv68uqL6Yod2/\u002BJc/vxgM6b5sclq/IJZcwErx/T2mOqi/YEE0v9wGt79ADQk/mYy0PuVXA78jtZI/N2\u002Brv8WWhj/MRZU/9PZrvxg2kD5EnV0/8YMKv8YyrL5Yqjq\u002BwVbFvnK\u002BnT9HgUW/FBdvv9Rswb1Z9T2/52kpvmw7v8D0x4u/VfPGPgorU78NlUk/6KVTvVIrnz/\u002Bs0O\u002BG\u002BMFP/H4AkCPektAAG\u002BYP8JL9b/07uQ/PhvLPu9DhT\u002BMBAy/gBjyvCLRMr6tOqI\u002B/DohvxAaTT\u002B2G3o/yI8UwHrd178Hy02/BmgkQEgwsD41qjU\u002BAu7VP985Cj\u002BHzLA/pHJwPkkCDcD2x9Q9MN17vvrrRz4iCTlA\u002BC6LPxTo877KHZY\u002BmAhzv2Zf3D2aQ7m/njdevtkytr\u002BhD8K/Wj\u002B6v9CStb9b2I\u002B/l87xP0iYDUD6Ey5AlH4wP9ABM7\u002ByTiC/Wu5vPzDES8B\u002BsHO/Ynm9Pyufyr8mVU4/xZWevjwvIb8EXis\u002BI9TrPqBOq7xNNI\u002B\u002BB\u002BiYP0bQMD9ocUo/1NE0QKr3\u002Br4AFAS/EGG0Pe\u002BInz8X1\u002BA/jDNLwDRbEcB2b5K\u002BCFkZQCcODL9o0gc/XuEhPwMEK76Nrqg\u002BVDNeP2CUjj9qAI2\u002BkpRjPvIhRr/Es6q\u002BqVEZP5SmLMByq6M\u002BS1ujv1F6u8Cwn6O/amY3vzjurb8W9hPAnoLMPQYOkT8mJXc/CqRNwFnFtT\u002BO29K\u002BV5cjv5IHdD6BxQa/988tP0c2DECy2nQ/dT4BwB0svL8WsGm98Ew6PpKeWT5qbl9AhV0HP1eqFD/06cI9DLE3P/gC/D94SM88V7Svv8bPuj9Ou8m\u002B6sFvv09Kjb7ewkq/IyUwv4cJqT4qeps9yLahvyBx3jxbVpo/bEfkvn53xz59\u002BJO\u002BmvDtPx5\u002BJz6G81\u002B/FJuPPQylXT\u002Bcwbi/CgTqv1isTTzhsEY/4Ue3PtAxdj9YjJw/ooQPv04Bv7/\u002BcAM\u002B0kaRPh49yL54udS/gGOIu\u002BeeDb8W2KY9"
},
{
"CategoryId": 41,
"Name": "Adventure Nutrition",
"NameEmbeddingBase64": "0QrNv1FvFz8ybwg/Ar2mvu0CbL8KLbE/fNXdPqv/lj9rady/7t6Ev0N\u002BsD\u002BS/Pi/\u002BNxUP7x8AT9UZNY/SO9Dv0vJFEDKXCc\u002BuhjTvzxHFkA5eQRAaUkBv3raYT/yAaC\u002BbA\u002BCPwT5oj/M/wzAeqn1vkIyDT8s1Q3AVoLtPtTYgr70aN8\u002BZKrTv0f\u002B5L7s4jlATvZZv2qu175GWRO/Z1ACQBcnqT9TUBZAjnFmP2h/oj2OTbs\u002BAmXGv5cVEr/lkoC/MNu9Pzaxgr6zIXO/7gZ7Ps78tL9Wtds\u002BZz93vjY0fT\u002B\u002BuYM/iFuUv6esBj\u002BJE\u002BI/LVtDPj4aDz4uo1DAWFg4QFowCz/sGCVACo6LvyywBkB0DTy8jO0wwPfumb\u002Bqo88/Jk\u002B\u002BPxf5Gz4k7u0\u002BVApTPXK1kj2\u002B/AA9KdIovzQwB77w1ALAta5lv/RujD6aP8g/dYgcP/v\u002BTL\u002BZ\u002Bxs/Z2rgvfwCDECi4E4/YPsGPzhUtL\u002Byppe/mWqDPzTIpr60PBC\u002Bxj9sv/Q8nb/W1sK/RpSvQHSTJT4I1Ew/4dBPPo/4lT8MF6o/B/8/wDz8H7/\u002BnBo/cxmwP/poDj9Mp70\u002BEkd3PwxfTb5ewQ2/hFcAwDo0wT80xg2\u002BYECJPtBhyL14nnY/JXDpv6DyITzi5QlAqFQDP7ol/D4kU4I\u002B8mQqQHiF2D8JyFq\u002BlkWqvZvJCD\u002B4ZQk/ik6yv\u002BRAIL/Mm4\u002B/5XjlPpX20D\u002BemPW/agBXv9J4RUB0RUy/NHZcP1BRI7wSeJjAbpVYPYYYmj\u002BOb0VAI6S2PoVKMb\u002B03io9Puf1vlh3Hb2FRKQ/fAKjvqT4IT92RJY/TP5oPy8oc79qjBbAVGYQPq4D\u002Bb/elGS/\u002BIWwvYqulj/zOGg/3YhOwJiauD7iKW69/BAtv0B0o7\u002BHi5M/pF\u002BYvpvujL\u002BYJgg/4MBbQFh8Ob/QiY2\u002BF1pwP8u6gr8RLzA/o1lBQJLacL9ChlQ\u002BRLyQPpyahL7gtQC/qsvAvhdP5T7YQr\u002B\u002BjTkEPw6iUT8EiPO/OxU/QOZNeL8aFam\u002BRUfJvufesb9YXrk8bNq6vg6DkL863E8/epB4v1aZeT\u002BzsxQ/MEXOPwvE\u002Br4WMCy/bYbSvx6P3D30NPg/bGZOPoYNlD6LkHC/CeK\u002BPxiI4r/sNJQ/uvr8PxO3oD/bu0S/Ln3uPsLMbD6Su4\u002B9/pcYPheetMAt9Kq/y1KUP5EfIj/tZT\u002B/oJSZPPF84z43N0g\u002B5Eatv/L9xL7m\u002BbQ/HItZvuCc370rure9mlVZP7pyAz4s9f4/qZYgv5JMgT8jEtK\u002BqpEeP5Ckuz109IM\u002BXQudvl720j9Yt0K\u002BdT94QOSMJkAqkwm/yFT/vw4HhL3QLtE/91g/P6w\u002BJr/WbyY/2hG3vxF8nT5Y3TG/lCblvhbf\u002Br\u002B3k5W\u002Bl8dDQF6BWL0QSH\u002B/rhC2vw6kCsBy/yS/Xl5Pv8hwqL55yIw\u002BJOGkP/ullz/ArRY/HNirvXa5Oj9iKKy/0WrTv4LRbb/82K6/QvpIv6ZCMMBp4bS/2f/hvp2slz5mdSM/jKkCvrJgOz9VLnm\u002BnMyPP4edCsD\u002BtkG/NsTkvhq9\u002BT7MV4M/znFYPiGfvj/owkw/QuGxvr8/VD\u002BgstK\u002BxON3vsqh8Dwn0Qw\u002BsHgDP2IJJz4k0wu/3sCkv/Nytr\u002BxZsK/1uYEvxKE1j7\u002Bld6\u002BcuUMwCBrE8Dc1jJAvVumPwK9w8DvOXI/pfUlv5TpHcAd3Ka/sovUPszlmz523GI\u002BoIsxv1cXyz9wx8k/5NfJvaDedT\u002Bf\u002BlS/LAQzvVMdkj\u002BcIpw/AgRDvq1imD/3vkvA3B\u002BaP3eQAkA8HXJAZAtVvKifm78ZOZ8/pCX0vblLbj\u002B8/Au/VNO\u002BPlRwAT9JsCU\u002BiF8QQAgGfT8KL4y\u002BTiavP3q9CD8BOfu/ErQ7P1zfoj8b29Q/FSE2v/9c4D6h6sS\u002BIR8eP2A1z7\u002BkdwK94wjavyGeDr\u002BqcqA\u002BzbHMvzbjcr/3hjm/XPMVvYGg0D3LEke/uyJvv\u002BlY8T3Ex/2\u002Bl4Q3wPRQpz6BZQPAw88dwHICbL1UPjXA"
},
{
"CategoryId": 42,
"Name": "Tactical Gear",
"NameEmbeddingBase64": "ZRgKwGbRPEBj6f0/JMCHvxrMxj7rW6Q/mwUWQGWHdz9Cu3\u002B/jiiyv8GQgD\u002BGs8C/hUrDPyxa2z\u002B4exBAtmk2v7fWoT\u002Bhq7A95zFpP9A92z4Ksbm\u002Brmozv\u002BwpkL6y\u002BZW9prJCP48\u002BLj941sW\u002BLecdv8qPkL\u002Bp5oDAR4uqPkD5kD/IfoI/hHppvo3\u002BMb7TnHc/o7HUv3hc8j5NC4G\u002BZ\u002BwoQKp9pL4OoN4/17sIv4oFCb9HQKY/4mSlv79VOz\u002BaGTM961MZQDsAlr/HeIY/Wschvxb\u002BI7/KBdm\u002BHgZPvrSCor\u002B4\u002B3k/1cpJvkT/mj9Qzkc/8EDkPU4YCz8KQprAAMCTP9\u002BC376Oyd8/\u002Bpa8vmvy7L5Em7U/tSlvP7LAHr9QT2A/v0C3PyRTnj4PQ9A/Kj63vQ9tnz/tuWi/lFx3P2pOaL8jUpu/JDzBvaDXGz\u002BRKyG/hkrxvfj0gL\u002BG4ApA5pJLvwrgYj/rpuQ/QJzJvrEotj8Gcia/fDrhvNLMyL4kv1C/1bUSvwxVbL\u002B\u002BPP6/gD33QAk9375Ert6/SCEvPYY5lj8Cy4E/J/kzvxoF0T55MgE/SWvAv176/j2Og0q/gOTGPBsbjr\u002BG1BC/cAIjPgg5VT3qYZS\u002BfY9dPxozHD8Ws8w\u002BM2M0v4Nkxr8yX7g/FHuwv4kMoj5uZpC/1dnIvj3raUABUsy\u002BrBtiPq2zAz9AVsI\u002BVlWPvzhvir\u002BhohK/kL1lPBSJIb1sV00/1yELv\u002BRx1T\u002BwbK6/2PWdPzUcIkCmqpPAX/01PzPh3T\u002BdG6O/Tlcovlreob3EE0\u002B\u002BtXIIwK7liz8vvQBA01bEvtIhiT9/4P8\u002Bjr8tP2aviL81a8C/rPCmvswrdjwm8FW/0wQWPlVnKkDgkWy/t2RHwAZQiD5gXq4\u002B4VCmP1rIwr/\u002B15\u002B/YBo8vRBt8LzTPBI/cf7VP3PKbz00psO/Lmiwv7GwIL/y3oQ\u002B732gPwJ/wb2fETm/FZYoPuxxOz9G4oO\u002Ba5YYvsqUsL\u002BXdPo\u002B0LOGP5QJvD1ZEgM\u002BDMhPQIgDZb98D\u002Bo\u002BsHHyPkXWFcDGbdW\u002BnH7PPXeUyL/nmJg/yLKBv4xeO73oHoM83gCcP8q6YT\u002BgTYU/gEf\u002Bv73qo78Ks0w/tsaePVozTb1wvtc/NGdBPkQi1r47bvO/1oMvvzqkLUCkfgnAi208P4o/gb8NiVI/07cAQPMOwcDixk0/ihQsP4R9Hj\u002BiH8O\u002BPx9Xv/adiT\u002B69LE/uu28vswPWb8/1INAkqsBP87CgL9Me5\u002B/Tnjqvz7SAEDUm0O\u002B724CwIBW47\u002BM1JS\u002BFJOgPkN1zz\u002BFPFfANhyyPorAHr64Ide/NQF1QITwzT7yQp8/GKucvyqlUz8mjMw/F9\u002BzPyQ7m7/CMhZAhM4sP2m1Uj9GILG\u002BOw7ZP62WKz7US2a/dxd3P61NiT\u002BmWeO/N4QiPyg6JcA1NTnAKS7ZPwY8vr/g0dm/ehGuveDiP775U3g/vfkgv0SYCz8k2xa/OqwFwGcGtr\u002BE8jK/vIp1Ps6Upr6ZqFU\u002B/Fy3PUpF6b8Ua/I/dO1DP67V5D4ENoW/VvbnPwswv7\u002BKmgq\u002B38rsP5n4LL8Ag287VRyjPwZmuL5qGQo\u002BiM4wPlpOyT7857C/26XoPyV\u002BFEAgdka\u002Btzyiv6xNjT91aoW/MfnNPYwVUz\u002BNxuo/QpUGP3Iogb\u002Bk\u002BA4\u002B1LdHv4zbhb\u002BQVz9A6Kz0v5A508D3uAi/Pa\u002B0P8zcVz\u002B3sky/r77hv92xy76GQFG/UpQiwAP1\u002Bb69VP\u002B\u002Bo/O\u002BP6678b2u7uU/4sGZPaKKOT\u002BCRvs\u002BDU4QwCkyqT/8OHO/F0zCP\u002Ba/oj/MYV5ArlGZvVhzXz8q\u002BVs/lWUiP\u002BcRvb5Dtmq\u002BSxGJP\u002B5xAkBcsNG\u002BoIHWPxjrWT\u002B3I\u002BW\u002BCOYFP5bgLD8MLl8/Z8omP1tjoD60WW\u002B/KAMgvyudTD9nF7E/Xkz/P08jEsBOkqO/tmfxv766G7\u002BGb06/RM5EwBg9tD8wdcq\u002BW\u002B2yv5ZyRj/KtEG/\u002BEAiv5pnir95VxM/NJ3/vTDq2z6YxAvACDqZv9DkGb/NNOq/"
},
{
"CategoryId": 43,
gitextract_9atq3bqx/
├── .config/
│ └── dotnet-tools.json
├── .editorconfig
├── .gitignore
├── CODE_OF_CONDUCT.md
├── Directory.Build.props
├── Directory.Packages.props
├── LICENSE
├── README.md
├── SECURITY.md
├── docs/
│ └── Architecture.pptx
├── eShopSupport.sln
├── nuget.config
├── seeddata/
│ ├── DataGenerator/
│ │ ├── .gitignore
│ │ ├── ChatCompletionServiceExtensions.cs
│ │ ├── DataGenerator.csproj
│ │ ├── Generators/
│ │ │ ├── CategoryGenerator.cs
│ │ │ ├── EvalQuestionGenerator.cs
│ │ │ ├── GeneratorBase.cs
│ │ │ ├── LocalTextEmbeddingGenerator.cs
│ │ │ ├── ManualGenerator.cs
│ │ │ ├── ManualPdfConverter.cs
│ │ │ ├── ManualTocGenerator.cs
│ │ │ ├── ProductGenerator.cs
│ │ │ ├── TicketGenerator.cs
│ │ │ ├── TicketSummaryGenerator.cs
│ │ │ └── TicketThreadGenerator.cs
│ │ ├── Model/
│ │ │ ├── Category.cs
│ │ │ ├── EvalQuestion.cs
│ │ │ ├── Manual.cs
│ │ │ ├── ManualPdf.cs
│ │ │ ├── ManualToc.cs
│ │ │ ├── Product.cs
│ │ │ ├── Role.cs
│ │ │ ├── Ticket.cs
│ │ │ ├── TicketThread.cs
│ │ │ └── TicketThreadMessage.cs
│ │ ├── Program.cs
│ │ └── appsettings.json
│ ├── dev/
│ │ ├── categories.json
│ │ ├── customers.json
│ │ ├── evalquestions.json
│ │ ├── manual-chunks.json
│ │ ├── products.json
│ │ └── tickets.json
│ └── test/
│ ├── categories.json
│ ├── customers.json
│ ├── evalquestions.json
│ ├── manual-chunks.json
│ ├── products.json
│ └── tickets.json
├── src/
│ ├── AppHost/
│ │ ├── .gitignore
│ │ ├── AppHost.csproj
│ │ ├── Ollama/
│ │ │ ├── OllamaResource.cs
│ │ │ └── OllamaResourceExtensions.cs
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── Python/
│ │ │ └── PythonUvicornAppResourceBuilderExtensions.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
│ ├── Backend/
│ │ ├── Api/
│ │ │ ├── AssistantApi.cs
│ │ │ ├── CatalogApi.cs
│ │ │ ├── TicketApi.cs
│ │ │ └── TicketMessagingApi.cs
│ │ ├── Backend.csproj
│ │ ├── Data/
│ │ │ ├── AppDbContext.cs
│ │ │ ├── AsyncEnumerableExtensions.cs
│ │ │ ├── Customer.cs
│ │ │ ├── ManualChunk.cs
│ │ │ ├── Message.cs
│ │ │ ├── Product.cs
│ │ │ ├── ProductCategory.cs
│ │ │ └── Ticket.cs
│ │ ├── HttpContextUserIdentityExtensions.cs
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── Services/
│ │ │ ├── ProductManualSemanticSearch.cs
│ │ │ ├── ProductSemanticSearch.cs
│ │ │ └── TicketSummarizer.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
│ ├── CustomerWebUI/
│ │ ├── Components/
│ │ │ ├── App.razor
│ │ │ ├── Layout/
│ │ │ │ ├── FooterBar.razor
│ │ │ │ ├── FooterBar.razor.css
│ │ │ │ ├── HeaderBar.razor
│ │ │ │ ├── HeaderBar.razor.css
│ │ │ │ ├── MainLayout.razor
│ │ │ │ ├── MainLayout.razor.css
│ │ │ │ ├── UserMenu.razor
│ │ │ │ └── UserMenu.razor.css
│ │ │ ├── Pages/
│ │ │ │ ├── Error.razor
│ │ │ │ ├── Home.razor
│ │ │ │ └── Support/
│ │ │ │ ├── Ticket.razor
│ │ │ │ ├── Ticket.razor.css
│ │ │ │ ├── TicketCreate.razor
│ │ │ │ ├── TicketCreate.razor.css
│ │ │ │ ├── TicketList.razor
│ │ │ │ └── TicketList.razor.css
│ │ │ ├── Routes.razor
│ │ │ └── _Imports.razor
│ │ ├── CustomerWebUI.csproj
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ └── wwwroot/
│ │ └── css/
│ │ ├── app.css
│ │ └── normalize.css
│ ├── DataIngestor/
│ │ ├── DataIngestor.csproj
│ │ ├── EvalQuestionIngestor.cs
│ │ ├── ManualIngestor.cs
│ │ ├── ManualZipIngestor.cs
│ │ ├── PathUtils.cs
│ │ ├── ProductCategoryIngestor.cs
│ │ ├── ProductIngestor.cs
│ │ ├── Program.cs
│ │ └── TicketIngestor.cs
│ ├── Evaluator/
│ │ ├── .gitignore
│ │ ├── EvalQuestion.cs
│ │ ├── Evaluator.csproj
│ │ ├── Program.cs
│ │ └── appsettings.json
│ ├── IdentityServer/
│ │ ├── .gitignore
│ │ ├── Config.cs
│ │ ├── HostingExtensions.cs
│ │ ├── IdentityServer.csproj
│ │ ├── Pages/
│ │ │ ├── Account/
│ │ │ │ ├── AccessDenied.cshtml
│ │ │ │ ├── AccessDenied.cshtml.cs
│ │ │ │ ├── Create/
│ │ │ │ │ ├── Index.cshtml
│ │ │ │ │ ├── Index.cshtml.cs
│ │ │ │ │ └── InputModel.cs
│ │ │ │ ├── Login/
│ │ │ │ │ ├── Index.cshtml
│ │ │ │ │ ├── Index.cshtml.cs
│ │ │ │ │ ├── InputModel.cs
│ │ │ │ │ ├── LoginOptions.cs
│ │ │ │ │ └── ViewModel.cs
│ │ │ │ └── Logout/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── LoggedOut.cshtml
│ │ │ │ ├── LoggedOut.cshtml.cs
│ │ │ │ ├── LoggedOutViewModel.cs
│ │ │ │ └── LogoutOptions.cs
│ │ │ ├── Ciba/
│ │ │ │ ├── All.cshtml
│ │ │ │ ├── All.cshtml.cs
│ │ │ │ ├── Consent.cshtml
│ │ │ │ ├── Consent.cshtml.cs
│ │ │ │ ├── ConsentOptions.cs
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── InputModel.cs
│ │ │ │ ├── ViewModel.cs
│ │ │ │ └── _ScopeListItem.cshtml
│ │ │ ├── Consent/
│ │ │ │ ├── ConsentOptions.cs
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── InputModel.cs
│ │ │ │ ├── ViewModel.cs
│ │ │ │ └── _ScopeListItem.cshtml
│ │ │ ├── Device/
│ │ │ │ ├── DeviceOptions.cs
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ ├── InputModel.cs
│ │ │ │ ├── Success.cshtml
│ │ │ │ ├── Success.cshtml.cs
│ │ │ │ ├── ViewModel.cs
│ │ │ │ └── _ScopeListItem.cshtml
│ │ │ ├── Diagnostics/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ └── ViewModel.cs
│ │ │ ├── Extensions.cs
│ │ │ ├── ExternalLogin/
│ │ │ │ ├── Callback.cshtml
│ │ │ │ ├── Callback.cshtml.cs
│ │ │ │ ├── Challenge.cshtml
│ │ │ │ └── Challenge.cshtml.cs
│ │ │ ├── Grants/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ └── ViewModel.cs
│ │ │ ├── Home/
│ │ │ │ └── Error/
│ │ │ │ ├── Index.cshtml
│ │ │ │ ├── Index.cshtml.cs
│ │ │ │ └── ViewModel.cs
│ │ │ ├── IdentityServerSuppressions.cs
│ │ │ ├── Index.cshtml
│ │ │ ├── Index.cshtml.cs
│ │ │ ├── Log.cs
│ │ │ ├── Redirect/
│ │ │ │ ├── Index.cshtml
│ │ │ │ └── Index.cshtml.cs
│ │ │ ├── SecurityHeadersAttribute.cs
│ │ │ ├── ServerSideSessions/
│ │ │ │ ├── Index.cshtml
│ │ │ │ └── Index.cshtml.cs
│ │ │ ├── Shared/
│ │ │ │ ├── _Layout.cshtml
│ │ │ │ ├── _Nav.cshtml
│ │ │ │ └── _ValidationSummary.cshtml
│ │ │ ├── Telemetry.cs
│ │ │ ├── TestUsers.cs
│ │ │ ├── _ViewImports.cshtml
│ │ │ └── _ViewStart.cshtml
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── appsettings.json
│ │ └── wwwroot/
│ │ ├── css/
│ │ │ ├── site.css
│ │ │ └── site.scss
│ │ ├── js/
│ │ │ ├── signin-redirect.js
│ │ │ └── signout-redirect.js
│ │ └── lib/
│ │ ├── bootstrap/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ └── dist/
│ │ │ ├── css/
│ │ │ │ ├── bootstrap-grid.css
│ │ │ │ ├── bootstrap-reboot.css
│ │ │ │ └── bootstrap.css
│ │ │ └── js/
│ │ │ ├── bootstrap.bundle.js
│ │ │ └── bootstrap.js
│ │ ├── bootstrap4-glyphicons/
│ │ │ ├── LICENSE
│ │ │ ├── css/
│ │ │ │ └── bootstrap-glyphicons.css
│ │ │ └── maps/
│ │ │ ├── glyphicons-fontawesome.css
│ │ │ └── glyphicons-fontawesome.less
│ │ └── jquery/
│ │ ├── LICENSE.txt
│ │ ├── README.md
│ │ └── dist/
│ │ ├── jquery.js
│ │ └── jquery.slim.js
│ ├── PythonInference/
│ │ ├── PythonInference.pyproj
│ │ ├── main.py
│ │ ├── requirements.txt
│ │ └── routers/
│ │ ├── classifier.py
│ │ └── embedder.py
│ ├── ServiceDefaults/
│ │ ├── Clients/
│ │ │ ├── Backend/
│ │ │ │ ├── CustomerBackendClient.cs
│ │ │ │ ├── DevToolBackendClient.cs
│ │ │ │ └── StaffBackendClient.cs
│ │ │ ├── ChatCompletion/
│ │ │ │ ├── ChatCompletionServiceExtensions.cs
│ │ │ │ ├── PreventStreamingWithFunctions.cs
│ │ │ │ ├── ServiceCollectionChatClientExtensions.cs
│ │ │ │ └── TestCachingChatClientBuilderExtensions.cs
│ │ │ ├── HttpClientExtensions.cs
│ │ │ ├── PythonInference/
│ │ │ │ └── PythonInferenceClient.cs
│ │ │ └── QdrantHttpClientExtensions.cs
│ │ ├── Extensions.cs
│ │ └── ServiceDefaults.csproj
│ └── StaffWebUI/
│ ├── Components/
│ │ ├── App.razor
│ │ ├── Layout/
│ │ │ ├── LoginDisplay.razor
│ │ │ ├── LoginDisplay.razor.css
│ │ │ ├── MainLayout.razor
│ │ │ ├── MainLayout.razor.css
│ │ │ ├── ThemePicker.razor
│ │ │ ├── ThemePicker.razor.css
│ │ │ └── Title.razor
│ │ ├── Pages/
│ │ │ ├── Account/
│ │ │ │ └── AccessDenied.razor
│ │ │ ├── Error.razor
│ │ │ ├── RedisSubscribingComponent.cs
│ │ │ ├── Ticket/
│ │ │ │ ├── Ticket.razor
│ │ │ │ ├── Ticket.razor.css
│ │ │ │ ├── TicketAssistant.razor
│ │ │ │ ├── TicketAssistant.razor.css
│ │ │ │ ├── TicketAssistant.razor.js
│ │ │ │ ├── TicketAssistantMessage.razor
│ │ │ │ ├── TicketAssistantMessage.razor.css
│ │ │ │ ├── TicketAssistantMessage.razor.js
│ │ │ │ ├── TicketDetails.razor
│ │ │ │ ├── TicketDetails.razor.css
│ │ │ │ ├── TicketMessages.razor
│ │ │ │ └── TicketMessages.razor.css
│ │ │ └── Tickets/
│ │ │ ├── Columns/
│ │ │ │ ├── LinkPropertyColumn.cs
│ │ │ │ └── LinkTemplateColumn.cs
│ │ │ ├── SatisfactionIndicator.razor
│ │ │ ├── SatisfactionIndicator.razor.css
│ │ │ ├── Tickets.razor
│ │ │ ├── Tickets.razor.css
│ │ │ ├── TicketsFilter.razor
│ │ │ └── TicketsFilter.razor.css
│ │ ├── Routes.razor
│ │ └── _Imports.razor
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── StaffWebUI.csproj
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── wwwroot/
│ ├── app.css
│ ├── manual.html
│ ├── pdfjs-4.2.67-dist/
│ │ ├── LICENSE
│ │ ├── build/
│ │ │ ├── pdf.mjs
│ │ │ ├── pdf.sandbox.mjs
│ │ │ └── pdf.worker.mjs
│ │ └── web/
│ │ ├── viewer.css
│ │ ├── viewer.html
│ │ └── viewer.mjs
│ └── theme-info.js
└── test/
├── E2ETest/
│ ├── ChatCompletionCache/
│ │ ├── 5AF0103EF2560BEC4FE94D21D18E3A1945C5202F7B452834A8FFC891322F321A.json
│ │ ├── 6981B02D1211D89EAD2B18D2A00BC2CC55A0CAA06E294C0318ADBB35112EB9D7.json
│ │ ├── 973247AA1FE93490986EF3435E4C6D88928EC469857A873D0899EB4389672BB0.json
│ │ ├── C70A33FF52171DCD96D2BF8F41BC45DE1FA308FAF38030F5EFE5764FDA6F787A.json
│ │ ├── E55E8743B91B9650A9C60E7DF7627B0B5C39C8CD35093DF9D6F6EE4CF476FE87.json
│ │ └── F7F43C2AD0BFAB1D1CEECA1454D8C1DD286336B9E097A32FA1A8FFEEA785937E.json
│ ├── E2ETest.csproj
│ ├── GlobalUsings.cs
│ ├── Infrastructure/
│ │ ├── AppHostFixture.cs
│ │ ├── AppTestCollection.cs
│ │ ├── LoginExtensions.cs
│ │ └── PlaywrightTestBase.cs
│ ├── TicketAssistantTest.cs
│ └── TicketsListTest.cs
└── EvaluationTests/
├── AnswerScoringEvaluator.cs
├── EvalQuestion.cs
├── EvaluationTests.cs
├── EvaluationTests.csproj
├── README.md
├── Settings.cs
└── appsettings.json
Showing preview only (435K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6134 symbols across 131 files)
FILE: seeddata/DataGenerator/ChatCompletionServiceExtensions.cs
class ChatCompletionServiceExtensions (line 12) | public static class ChatCompletionServiceExtensions
method AddOpenAIChatCompletion (line 14) | public static void AddOpenAIChatCompletion(this HostApplicationBuilder...
FILE: seeddata/DataGenerator/Generators/CategoryGenerator.cs
class CategoryGenerator (line 6) | public class CategoryGenerator(IServiceProvider services) : GeneratorBas...
method GetId (line 10) | protected override object GetId(Category item) => item.CategoryId;
method GenerateCoreAsync (line 12) | protected override async IAsyncEnumerable<Category> GenerateCoreAsync()
method ImproveBrandName (line 55) | private static string ImproveBrandName(string name)
class Response (line 67) | private class Response
FILE: seeddata/DataGenerator/Generators/EvalQuestionGenerator.cs
class EvalQuestionGenerator (line 7) | public class EvalQuestionGenerator(IReadOnlyList<Product> products, IRea...
method GetId (line 12) | protected override object GetId(EvalQuestion item)
method GenerateCoreAsync (line 15) | protected override async IAsyncEnumerable<EvalQuestion> GenerateCoreAs...
method CompleteOutputAfterTask (line 43) | private static void CompleteOutputAfterTask<T>(ChannelWriter<T> writer...
method GenerateSingle (line 59) | private async Task<EvalQuestion> GenerateSingle()
FILE: seeddata/DataGenerator/Generators/GeneratorBase.cs
class GeneratorBase (line 10) | public abstract class GeneratorBase<T>
method GetId (line 14) | protected abstract object GetId(T item);
method GeneratorBase (line 25) | public GeneratorBase(IServiceProvider services)
method GenerateAsync (line 30) | public async Task<IReadOnlyList<T>> GenerateAsync()
method GetItemOutputPath (line 51) | protected string GetItemOutputPath(string id)
method GenerateCoreAsync (line 54) | protected abstract IAsyncEnumerable<T> GenerateCoreAsync();
method GetCompletion (line 58) | protected async Task<string> GetCompletion(string prompt)
method GetAndParseJsonChatCompletion (line 68) | protected async Task<TResponse> GetAndParseJsonChatCompletion<TRespons...
method RunWithRetries (line 88) | private static async Task<TResult> RunWithRetries<TResult>(Func<Task<T...
method ReadAndDeserializeSingleValue (line 107) | private static TResponse? ReadAndDeserializeSingleValue<TResponse>(str...
method WriteAsync (line 115) | protected virtual Task WriteAsync(string path, T item)
method Read (line 121) | protected virtual T Read(string path)
method MapParallel (line 135) | protected IAsyncEnumerable<V> MapParallel<U, V>(IEnumerable<U> source,...
FILE: seeddata/DataGenerator/Generators/LocalTextEmbeddingGenerator.cs
class LocalTextEmbeddingGenerator (line 6) | public class LocalTextEmbeddingGenerator : IEmbeddingGenerator<string, E...
method Dispose (line 12) | public void Dispose() => _embedder.Dispose();
method GenerateAsync (line 14) | public Task<GeneratedEmbeddings<Embedding<float>>> GenerateAsync(IEnum...
method GetService (line 20) | public object? GetService(Type serviceType, object? key = null)
FILE: seeddata/DataGenerator/Generators/ManualGenerator.cs
class ManualGenerator (line 6) | public class ManualGenerator(IReadOnlyList<Category> categories, IReadOn...
method GetId (line 11) | protected override object GetId(Manual item) => item.ProductId;
method GenerateCoreAsync (line 13) | protected override IAsyncEnumerable<Manual> GenerateCoreAsync()
method GenerateManualAsync (line 20) | private async Task<Manual> GenerateManualAsync(ManualToc toc)
method FormatTocForPrompt (line 74) | private static string FormatTocForPrompt(ManualTocSection section)
method CountSubtreeLength (line 96) | private static int CountSubtreeLength(ManualTocSection tocSection)
method WriteAsync (line 103) | protected override Task WriteAsync(string path, Manual item)
method Read (line 108) | protected override Manual Read(string path)
method ExtractFromManual (line 115) | public static string ExtractFromManual(Manual manual)
FILE: seeddata/DataGenerator/Generators/ManualPdfConverter.cs
class ManualPdfConverter (line 8) | public class ManualPdfConverter(IReadOnlyList<Product> products, IReadOn...
method CreateConverter (line 10) | Markdown2PdfConverter CreateConverter(Product product) => new(new()
method ConvertAsync (line 38) | public async Task<IReadOnlyList<ManualPdf>> ConvertAsync()
class TempFile (line 81) | private class TempFile : IDisposable
method TempFile (line 85) | public TempFile(string contents)
method Dispose (line 91) | public void Dispose()
FILE: seeddata/DataGenerator/Generators/ManualTocGenerator.cs
class ManualTocGenerator (line 5) | public class ManualTocGenerator(IReadOnlyList<Category> categories, IRea...
method GetId (line 9) | protected override object GetId(ManualToc item) => item.ProductId;
method GenerateCoreAsync (line 11) | protected override IAsyncEnumerable<ManualToc> GenerateCoreAsync()
method GenerateTocForProductAsync (line 18) | private async Task<ManualToc> GenerateTocForProductAsync(Product product)
method PopulateSiblingIndexes (line 73) | void PopulateSiblingIndexes(List<ManualTocSection> sections)
FILE: seeddata/DataGenerator/Generators/ProductGenerator.cs
class ProductGenerator (line 5) | public class ProductGenerator(IReadOnlyList<Category> categories, IServi...
method GetId (line 9) | protected override object GetId(Product item) => item.ProductId;
method GenerateCoreAsync (line 11) | protected override async IAsyncEnumerable<Product> GenerateCoreAsync()
class Response (line 63) | class Response
FILE: seeddata/DataGenerator/Generators/TicketGenerator.cs
class TicketGenerator (line 5) | public class TicketGenerator(IReadOnlyList<Product> products, IReadOnlyL...
method GetId (line 9) | protected override object GetId(Ticket item) => item.TicketId;
method GenerateCoreAsync (line 11) | protected override async IAsyncEnumerable<Ticket> GenerateCoreAsync()
FILE: seeddata/DataGenerator/Generators/TicketSummaryGenerator.cs
class TicketSummaryGenerator (line 7) | public class TicketSummaryGenerator(IReadOnlyList<Product> products, IRe...
method GetId (line 9) | protected override object GetId(TicketThread item) => item.TicketId;
method GenerateCoreAsync (line 13) | protected override IAsyncEnumerable<TicketThread> GenerateCoreAsync()
method GenerateSummaryAsync (line 28) | private async Task GenerateSummaryAsync(TicketThread thread)
class Response (line 96) | private class Response
class JsonStringEnumConverterWithFallback (line 109) | private class JsonStringEnumConverterWithFallback : JsonConverterFactory
method CanConvert (line 111) | public override bool CanConvert(Type typeToConvert)
method CreateConverter (line 114) | public override JsonConverter? CreateConverter(Type typeToConvert, J...
class ErrorHandlingEnumConverter (line 120) | private class ErrorHandlingEnumConverter<T> : JsonConverter<T> where...
method CanConvert (line 122) | public override bool CanConvert(Type typeToConvert)
method Read (line 125) | public override T Read(ref Utf8JsonReader reader, Type typeToConve...
method Write (line 138) | public override void Write(Utf8JsonWriter writer, T value, JsonSer...
FILE: seeddata/DataGenerator/Generators/TicketThreadGenerator.cs
class TicketThreadGenerator (line 9) | public class TicketThreadGenerator(IReadOnlyList<Ticket> tickets, IReadO...
method GetId (line 13) | protected override object GetId(TicketThread item) => item.TicketId;
method GenerateCoreAsync (line 17) | protected override IAsyncEnumerable<TicketThread> GenerateCoreAsync()
method GenerateThreadAsync (line 24) | private async Task<TicketThread> GenerateThreadAsync(Ticket ticket)
method GenerateCustomerMessageAsync (line 70) | private async Task<Response> GenerateCustomerMessageAsync(Product prod...
method GenerateAssistantMessageAsync (line 99) | private async Task<Response> GenerateAssistantMessageAsync(Product pro...
method FormatMessagesForPrompt (line 144) | public static string FormatMessagesForPrompt(IReadOnlyList<TicketThrea...
class Response (line 154) | private class Response
class AssistantTools (line 160) | private class AssistantTools(IEmbeddingGenerator<string, Embedding<flo...
method SearchUserManualAsync (line 162) | [Description("Searches for information in the product's user manual.")]
method SplitIntoChunks (line 189) | private IEnumerable<string> SplitIntoChunks(string markdownText, int...
type SeparatorMode (line 261) | private enum SeparatorMode { Paragraph, Sentence, Word }
FILE: seeddata/DataGenerator/Model/Category.cs
class Category (line 3) | public class Category
FILE: seeddata/DataGenerator/Model/EvalQuestion.cs
class EvalQuestion (line 3) | public class EvalQuestion
FILE: seeddata/DataGenerator/Model/Manual.cs
class Manual (line 3) | public class Manual
FILE: seeddata/DataGenerator/Model/ManualPdf.cs
class ManualPdf (line 3) | public class ManualPdf
FILE: seeddata/DataGenerator/Model/ManualToc.cs
class ManualToc (line 3) | public class ManualToc
class ManualTocSection (line 12) | public class ManualTocSection
FILE: seeddata/DataGenerator/Model/Product.cs
class Product (line 3) | public class Product
FILE: seeddata/DataGenerator/Model/Role.cs
type Role (line 3) | public enum Role { Customer, Assistant };
FILE: seeddata/DataGenerator/Model/Ticket.cs
class Ticket (line 3) | public class Ticket
FILE: seeddata/DataGenerator/Model/TicketThread.cs
class TicketThread (line 5) | public class TicketThread
type TicketStatus (line 28) | public enum TicketStatus
type TicketType (line 34) | public enum TicketType
FILE: seeddata/DataGenerator/Model/TicketThreadMessage.cs
class TicketThreadMessage (line 3) | public class TicketThreadMessage
FILE: src/AppHost/Ollama/OllamaResource.cs
class OllamaResource (line 3) | internal class OllamaResource(string name, string[] models, string defau...
FILE: src/AppHost/Ollama/OllamaResourceExtensions.cs
class OllamaResourceExtensions (line 8) | internal static class OllamaResourceExtensions
method AddOllama (line 10) | public static IResourceBuilder<OllamaResource> AddOllama(this IDistrib...
method WithDataVolume (line 49) | public static IResourceBuilder<OllamaResource> WithDataVolume(this IRe...
method WithReference (line 54) | public static IResourceBuilder<TDestination> WithReference<TDestinatio...
method CreateVolumeName (line 63) | private static string CreateVolumeName<T>(IResourceBuilder<T> builder,...
class OllamaEnsureModelAvailableHook (line 73) | private sealed class OllamaEnsureModelAvailableHook(
method AfterEndpointsAllocatedAsync (line 78) | public Task AfterEndpointsAllocatedAsync(DistributedApplicationModel...
method DownloadModelAsync (line 137) | private static async Task DownloadModelAsync(ILogger logger, Endpoin...
type OllamaGetTagsResponse (line 155) | record OllamaGetTagsResponse(OllamaGetTagsResponseModel[]? Models);
type OllamaGetTagsResponseModel (line 156) | record OllamaGetTagsResponseModel(string Name);
class OllamaModelDownloaderResource (line 159) | private class OllamaModelDownloaderResource(string name, OllamaResourc...
FILE: src/AppHost/Python/PythonUvicornAppResourceBuilderExtensions.cs
class PythonUvicornAppResourceBuilderExtensions (line 3) | public static class PythonUvicornAppResourceBuilderExtensions
method AddPythonUvicornApp (line 5) | public static IResourceBuilder<PythonUvicornAppResource> AddPythonUvic...
class PythonUvicornAppResource (line 13) | public class PythonUvicornAppResource(string name, string command, strin...
FILE: src/Backend/Api/AssistantApi.cs
class AssistantApi (line 13) | public static class AssistantApi
method MapAssistantApiEndpoints (line 15) | public static void MapAssistantApiEndpoints(this WebApplication app)
method GetStreamingChatResponseAsync (line 20) | private static async Task GetStreamingChatResponseAsync(AssistantChatR...
class MessageClassification (line 85) | private class MessageClassification
class SearchManualContext (line 90) | private class SearchManualContext(HttpContext httpContext)
method SearchManual (line 95) | public async Task<object> SearchManual(
method GetProductId (line 135) | private static int? GetProductId(MemoryQueryResult result)
method GetPageNumber (line 141) | private static int? GetPageNumber(MemoryQueryResult result)
FILE: src/Backend/Api/CatalogApi.cs
class CatalogApi (line 12) | public static class CatalogApi
method MapCatalogApiEndpoints (line 14) | public static void MapCatalogApiEndpoints(this WebApplication app)
method SearchCategoriesAsync (line 26) | private static async Task<IEnumerable<FindCategoriesResult>> SearchCat...
method SearchProductsAsync (line 67) | private static Task<IEnumerable<FindProductsResult>> SearchProductsAsy...
method GetManualPdfAsync (line 70) | private static async Task<IResult> GetManualPdfAsync(string file, Blob...
FILE: src/Backend/Api/TicketApi.cs
class TicketApi (line 12) | public static class TicketApi
method MapTicketApiEndpoints (line 14) | public static void MapTicketApiEndpoints(this WebApplication app)
method ListTicketsAsync (line 40) | private static async Task<IResult> ListTicketsAsync(AppDbContext dbCon...
method GetTicketAsync (line 112) | private static async Task<IResult> GetTicketAsync(AppDbContext dbConte...
method UpdateTicketAsync (line 137) | private static async Task<IResult> UpdateTicketAsync(AppDbContext dbCo...
method CloseTicketAsync (line 156) | private static async Task<IResult> CloseTicketAsync(AppDbContext dbCon...
method CreateTicketAsync (line 172) | private static async Task CreateTicketAsync(HttpContext httpContext, A...
FILE: src/Backend/Api/TicketMessagingApi.cs
class TicketMessagingApi (line 8) | public static class TicketMessagingApi
method MapTicketMessagingApiEndpoints (line 10) | public static void MapTicketMessagingApiEndpoints(this WebApplication ...
method PostMessageAsync (line 32) | private static async Task PostMessageAsync(int ticketId, AppDbContext ...
FILE: src/Backend/Data/AppDbContext.cs
class AppDbContext (line 8) | public class AppDbContext : DbContext
method AppDbContext (line 10) | public AppDbContext(DbContextOptions<AppDbContext> options) : base(opt...
method OnModelCreating (line 24) | protected override void OnModelCreating(ModelBuilder modelBuilder)
method EnsureDbCreatedAsync (line 31) | public static async Task EnsureDbCreatedAsync(IServiceProvider service...
method ImportInitialData (line 47) | private static async Task ImportInitialData(AppDbContext dbContext, st...
FILE: src/Backend/Data/AsyncEnumerableExtensions.cs
class AsyncEnumerableExtensions (line 3) | internal static class AsyncEnumerableExtensions
method ToListAsync (line 5) | public static async Task<List<T>> ToListAsync<T>(this IAsyncEnumerable...
FILE: src/Backend/Data/Customer.cs
class Customer (line 3) | public class Customer
FILE: src/Backend/Data/ManualChunk.cs
class ManualChunk (line 3) | public class ManualChunk
FILE: src/Backend/Data/Message.cs
class Message (line 3) | public class Message
FILE: src/Backend/Data/Product.cs
class Product (line 8) | public class Product
class EmbeddingJsonConverter (line 21) | class EmbeddingJsonConverter : JsonConverter<ReadOnlyMemory<float>>
method Read (line 23) | public override ReadOnlyMemory<float> Read(ref Utf8JsonReader reader, ...
method Write (line 40) | public override void Write(Utf8JsonWriter writer, ReadOnlyMemory<float...
FILE: src/Backend/Data/ProductCategory.cs
class ProductCategory (line 5) | public class ProductCategory
FILE: src/Backend/Data/Ticket.cs
class Ticket (line 6) | public class Ticket
FILE: src/Backend/HttpContextUserIdentityExtensions.cs
class HttpContextUserIdentityExtensions (line 5) | public static class HttpContextUserIdentityExtensions
method GetRequiredCustomerId (line 7) | public static int GetRequiredCustomerId(this HttpContext httpContext)
FILE: src/Backend/Services/ProductManualSemanticSearch.cs
class ProductManualSemanticSearch (line 11) | public class ProductManualSemanticSearch(ITextEmbeddingGenerationService...
method SearchAsync (line 15) | public async Task<IReadOnlyList<MemoryQueryResult>> SearchAsync(int? p...
method EnsureSeedDataImportedAsync (line 46) | public static async Task EnsureSeedDataImportedAsync(IServiceProvider ...
method ImportManualFilesSeedDataAsync (line 56) | private static async Task ImportManualFilesSeedDataAsync(string import...
method ImportManualChunkSeedDataAsync (line 76) | private static async Task ImportManualChunkSeedDataAsync(string import...
method HasAnyAsync (line 102) | private static async Task<bool> HasAnyAsync<T>(IAsyncEnumerable<T> asy...
method ReadChunkedAsync (line 112) | private static async IAsyncEnumerable<IEnumerable<T>> ReadChunkedAsync...
class QdrantResult (line 132) | class QdrantResult
class QdrantResultEntry (line 137) | class QdrantResultEntry
class QdrantResultEntryPayload (line 143) | class QdrantResultEntryPayload
FILE: src/Backend/Services/ProductSemanticSearch.cs
class ProductSemanticSearch (line 8) | public class ProductSemanticSearch(ISemanticTextMemory semanticTextMemory)
method FindProductsAsync (line 12) | public async Task<IEnumerable<FindProductsResult>> FindProductsAsync(s...
method EnsureSeedDataImportedAsync (line 24) | public static async Task EnsureSeedDataImportedAsync(IServiceProvider ...
method ImportProductSeedDataAsync (line 33) | private static async Task ImportProductSeedDataAsync(string importData...
FILE: src/Backend/Services/TicketSummarizer.cs
class TicketSummarizer (line 10) | public class TicketSummarizer(IServiceScopeFactory scopeFactory)
method UpdateSummary (line 27) | public void UpdateSummary(int ticketId, bool enforceRateLimit)
method UpdateSummaryAsync (line 43) | private async Task UpdateSummaryAsync(int ticketId)
method FormatMessagesForPrompt (line 130) | private static string FormatMessagesForPrompt(IReadOnlyList<Message> m...
class Response (line 140) | private class Response
FILE: src/DataIngestor/EvalQuestionIngestor.cs
class EvalQuestionIngestor (line 4) | public class EvalQuestionIngestor
method RunAsync (line 6) | public async Task RunAsync(string generatedDataPath, string outputDir)
FILE: src/DataIngestor/ManualIngestor.cs
class ManualIngestor (line 11) | public class ManualIngestor
method RunAsync (line 13) | public async Task RunAsync(string sourceDir, string outputDir)
method GetPageText (line 59) | private static string GetPageText(Page pdfPage)
FILE: src/DataIngestor/ManualZipIngestor.cs
class ManualZipIngestor (line 3) | public class ManualZipIngestor
method RunAsync (line 5) | public Task RunAsync(string generatedDataPath, string outputDir)
FILE: src/DataIngestor/PathUtils.cs
class PathUtils (line 1) | public static class PathUtils
method FindAncestorDirectoryContaining (line 3) | public static string FindAncestorDirectoryContaining(string pattern)
FILE: src/DataIngestor/ProductCategoryIngestor.cs
class ProductCategoryIngestor (line 7) | class ProductCategoryIngestor
method RunAsync (line 9) | public async Task RunAsync(string generatedDataPath, string outputDir)
method ToBase64 (line 33) | private static string ToBase64(ReadOnlyMemory<float> embedding)
type GeneratedCategory (line 36) | internal record GeneratedCategory(int CategoryId, string Name);
FILE: src/DataIngestor/ProductIngestor.cs
class ProductIngestor (line 6) | class ProductIngestor
method RunAsync (line 8) | public async Task RunAsync(string generatedDataPath, string outputDir)
type GeneratedProduct (line 36) | internal record GeneratedProduct(int ProductId, int CategoryId, string...
FILE: src/DataIngestor/TicketIngestor.cs
class TicketIngestor (line 6) | class TicketIngestor
method RunAsync (line 8) | public async Task RunAsync(string generatedDataPath, string outputDir)
type GeneratedTicket (line 52) | internal record GeneratedTicket(int TicketId, int ProductId, string Ti...
type GeneratedMessage (line 53) | internal record GeneratedMessage(int MessageId, int AuthorRole, string...
FILE: src/Evaluator/EvalQuestion.cs
class EvalQuestion (line 3) | public class EvalQuestion
FILE: src/Evaluator/Program.cs
type ScoringResponse (line 208) | record ScoringResponse(AnswerScore[] Scores);
type AnswerScore (line 209) | record AnswerScore(int Index, string ScoreLabel, string DescriptionOfQua...
FILE: src/IdentityServer/Config.cs
class Config (line 6) | public static class Config
method GetClients (line 20) | public static IEnumerable<Client> GetClients(IConfiguration configurat...
FILE: src/IdentityServer/HostingExtensions.cs
class HostingExtensions (line 5) | internal static class HostingExtensions
method ConfigureServices (line 7) | public static WebApplication ConfigureServices(this WebApplicationBuil...
method ConfigurePipeline (line 28) | public static WebApplication ConfigurePipeline(this WebApplication app)
FILE: src/IdentityServer/Pages/Account/AccessDenied.cshtml.cs
class AccessDeniedModel (line 8) | public class AccessDeniedModel : PageModel
method OnGet (line 10) | public void OnGet()
FILE: src/IdentityServer/Pages/Account/Create/Index.cshtml.cs
class Index (line 15) | [SecurityHeaders]
method Index (line 25) | public Index(
method OnGet (line 35) | public IActionResult OnGet(string? returnUrl)
method OnPost (line 41) | public async Task<IActionResult> OnPost()
FILE: src/IdentityServer/Pages/Account/Create/InputModel.cs
class InputModel (line 8) | public class InputModel
FILE: src/IdentityServer/Pages/Account/Login/Index.cshtml.cs
class Index (line 17) | [SecurityHeaders]
method Index (line 32) | public Index(
method OnGet (line 48) | public async Task<IActionResult> OnGet(string? returnUrl)
method OnPost (line 61) | public async Task<IActionResult> OnPost()
method BuildModelAsync (line 165) | private async Task BuildModelAsync(string? returnUrl)
FILE: src/IdentityServer/Pages/Account/Login/InputModel.cs
class InputModel (line 8) | public class InputModel
FILE: src/IdentityServer/Pages/Account/Login/LoginOptions.cs
class LoginOptions (line 6) | public static class LoginOptions
FILE: src/IdentityServer/Pages/Account/Login/ViewModel.cs
class ViewModel (line 6) | public class ViewModel
class ExternalProvider (line 17) | public class ExternalProvider
method ExternalProvider (line 19) | public ExternalProvider(string authenticationScheme, string? display...
FILE: src/IdentityServer/Pages/Account/Logout/Index.cshtml.cs
class Index (line 15) | [SecurityHeaders]
method Index (line 25) | public Index(IIdentityServerInteractionService interaction, IEventServ...
method OnGet (line 31) | public async Task<IActionResult> OnGet(string? logoutId)
method OnPost (line 62) | public async Task<IActionResult> OnPost()
FILE: src/IdentityServer/Pages/Account/Logout/LoggedOut.cshtml.cs
class LoggedOut (line 10) | [SecurityHeaders]
method LoggedOut (line 18) | public LoggedOut(IIdentityServerInteractionService interactionService)
method OnGet (line 23) | public async Task OnGet(string? logoutId)
FILE: src/IdentityServer/Pages/Account/Logout/LoggedOutViewModel.cs
class LoggedOutViewModel (line 9) | public class LoggedOutViewModel
FILE: src/IdentityServer/Pages/Account/Logout/LogoutOptions.cs
class LogoutOptions (line 7) | public static class LogoutOptions
FILE: src/IdentityServer/Pages/Ciba/All.cshtml.cs
class AllModel (line 11) | [SecurityHeaders]
method AllModel (line 19) | public AllModel(IBackchannelAuthenticationInteractionService backchann...
method OnGet (line 24) | public async Task OnGet()
FILE: src/IdentityServer/Pages/Ciba/Consent.cshtml.cs
class Consent (line 15) | [Authorize]
method Consent (line 23) | public Consent(
method OnGet (line 38) | public async Task<IActionResult> OnGet(string? id)
method OnPost (line 53) | public async Task<IActionResult> OnPost()
method SetViewModelAsync (line 124) | private async Task<bool> SetViewModelAsync(string? id)
method CreateConsentViewModel (line 141) | private ViewModel CreateConsentViewModel(BackchannelUserLoginRequest r...
method CreateScopeViewModel (line 183) | private static ScopeViewModel CreateScopeViewModel(IdentityResource id...
method CreateScopeViewModel (line 197) | private static ScopeViewModel CreateScopeViewModel(ParsedScopeValue pa...
method GetOfflineAccessScope (line 217) | private static ScopeViewModel GetOfflineAccessScope(bool check)
FILE: src/IdentityServer/Pages/Ciba/ConsentOptions.cs
class ConsentOptions (line 6) | public static class ConsentOptions
FILE: src/IdentityServer/Pages/Ciba/Index.cshtml.cs
class IndexModel (line 12) | [AllowAnonymous]
method IndexModel (line 21) | public IndexModel(IBackchannelAuthenticationInteractionService backcha...
method OnGet (line 27) | public async Task<IActionResult> OnGet(string id)
FILE: src/IdentityServer/Pages/Ciba/InputModel.cs
class InputModel (line 6) | public class InputModel
FILE: src/IdentityServer/Pages/Ciba/ViewModel.cs
class ViewModel (line 6) | public class ViewModel
class ScopeViewModel (line 18) | public class ScopeViewModel
class ResourceViewModel (line 30) | public class ResourceViewModel
FILE: src/IdentityServer/Pages/Consent/ConsentOptions.cs
class ConsentOptions (line 6) | public static class ConsentOptions
FILE: src/IdentityServer/Pages/Consent/Index.cshtml.cs
class Index (line 16) | [Authorize]
method Index (line 24) | public Index(
method OnGet (line 39) | public async Task<IActionResult> OnGet(string? returnUrl)
method OnPost (line 54) | public async Task<IActionResult> OnPost()
method SetViewModelAsync (line 132) | private async Task<bool> SetViewModelAsync(string? returnUrl)
method CreateConsentViewModel (line 149) | private ViewModel CreateConsentViewModel(AuthorizationRequest request)
method CreateScopeViewModel (line 191) | private static ScopeViewModel CreateScopeViewModel(IdentityResource id...
method CreateScopeViewModel (line 205) | private static ScopeViewModel CreateScopeViewModel(ParsedScopeValue pa...
method CreateOfflineAccessScope (line 225) | private static ScopeViewModel CreateOfflineAccessScope(bool check)
FILE: src/IdentityServer/Pages/Consent/InputModel.cs
class InputModel (line 6) | public class InputModel
FILE: src/IdentityServer/Pages/Consent/ViewModel.cs
class ViewModel (line 6) | public class ViewModel
class ScopeViewModel (line 17) | public class ScopeViewModel
class ResourceViewModel (line 29) | public class ResourceViewModel
FILE: src/IdentityServer/Pages/Device/DeviceOptions.cs
class DeviceOptions (line 6) | public static class DeviceOptions
FILE: src/IdentityServer/Pages/Device/Index.cshtml.cs
class Index (line 18) | [SecurityHeaders]
method Index (line 27) | public Index(
method OnGet (line 44) | public async Task<IActionResult> OnGet(string? userCode)
method OnPost (line 64) | public async Task<IActionResult> OnPost()
method SetViewModelAsync (line 136) | private async Task<bool> SetViewModelAsync(string userCode)
method CreateConsentViewModel (line 151) | private ViewModel CreateConsentViewModel(DeviceFlowAuthorizationReques...
method CreateScopeViewModel (line 182) | private static ScopeViewModel CreateScopeViewModel(IdentityResource id...
method CreateScopeViewModel (line 195) | private static ScopeViewModel CreateScopeViewModel(ParsedScopeValue pa...
method GetOfflineAccessScope (line 209) | private static ScopeViewModel GetOfflineAccessScope(bool check)
FILE: src/IdentityServer/Pages/Device/InputModel.cs
class InputModel (line 6) | public class InputModel
FILE: src/IdentityServer/Pages/Device/Success.cshtml.cs
class SuccessModel (line 9) | [SecurityHeaders]
method OnGet (line 13) | public void OnGet()
FILE: src/IdentityServer/Pages/Device/ViewModel.cs
class ViewModel (line 6) | public class ViewModel
class ScopeViewModel (line 17) | public class ScopeViewModel
FILE: src/IdentityServer/Pages/Diagnostics/Index.cshtml.cs
class Index (line 11) | [SecurityHeaders]
method OnGet (line 17) | public async Task<IActionResult> OnGet()
FILE: src/IdentityServer/Pages/Diagnostics/ViewModel.cs
class ViewModel (line 11) | public class ViewModel
method ViewModel (line 13) | public ViewModel(AuthenticateResult result)
FILE: src/IdentityServer/Pages/Extensions.cs
class Extensions (line 11) | public static class Extensions
method GetSchemeSupportsSignOutAsync (line 16) | internal static async Task<bool> GetSchemeSupportsSignOutAsync(this Ht...
method IsNativeClient (line 26) | internal static bool IsNativeClient(this AuthorizationRequest context)
method LoadingPage (line 35) | internal static IActionResult LoadingPage(this PageModel page, string?...
FILE: src/IdentityServer/Pages/ExternalLogin/Callback.cshtml.cs
class Callback (line 17) | [AllowAnonymous]
method Callback (line 26) | public Callback(
method OnGet (line 40) | public async Task<IActionResult> OnGet()
method CaptureExternalLoginContext (line 126) | private static void CaptureExternalLoginContext(AuthenticateResult ext...
FILE: src/IdentityServer/Pages/ExternalLogin/Challenge.cshtml.cs
class Challenge (line 12) | [AllowAnonymous]
method Challenge (line 18) | public Challenge(IIdentityServerInteractionService interactionService)
method OnGet (line 23) | public IActionResult OnGet(string scheme, string? returnUrl)
FILE: src/IdentityServer/Pages/Grants/Index.cshtml.cs
class Index (line 14) | [SecurityHeaders]
method Index (line 23) | public Index(IIdentityServerInteractionService interaction,
method OnGet (line 36) | public async Task OnGet()
method OnPost (line 74) | public async Task<IActionResult> OnPost()
FILE: src/IdentityServer/Pages/Grants/ViewModel.cs
class ViewModel (line 6) | public class ViewModel
class GrantViewModel (line 11) | public class GrantViewModel
FILE: src/IdentityServer/Pages/Home/Error/Index.cshtml.cs
class Index (line 10) | [AllowAnonymous]
method Index (line 19) | public Index(IIdentityServerInteractionService interaction, IWebHostEn...
method OnGet (line 25) | public async Task OnGet(string? errorId)
FILE: src/IdentityServer/Pages/Home/Error/ViewModel.cs
class ViewModel (line 8) | public class ViewModel
method ViewModel (line 10) | public ViewModel()
method ViewModel (line 14) | public ViewModel(string error)
FILE: src/IdentityServer/Pages/Index.cshtml.cs
class Index (line 11) | [AllowAnonymous]
method Index (line 14) | public Index(IdentityServerLicense? license = null)
FILE: src/IdentityServer/Pages/Log.cs
class Log (line 6) | internal static class Log
method InvalidId (line 13) | public static void InvalidId(this ILogger logger, string? id)
method InvalidBackchannelLoginId (line 23) | public static void InvalidBackchannelLoginId(this ILogger logger, stri...
method ExternalClaims (line 33) | public static void ExternalClaims(this ILogger logger, IEnumerable<str...
method NoMatchingBackchannelLoginRequest (line 43) | public static void NoMatchingBackchannelLoginRequest(this ILogger logg...
method NoConsentMatchingRequest (line 53) | public static void NoConsentMatchingRequest(this ILogger logger, strin...
class EventIds (line 61) | internal static class EventIds
FILE: src/IdentityServer/Pages/Redirect/Index.cshtml.cs
class IndexModel (line 10) | [AllowAnonymous]
method OnGet (line 15) | public IActionResult OnGet(string? redirectUri)
FILE: src/IdentityServer/Pages/SecurityHeadersAttribute.cs
class SecurityHeadersAttribute (line 9) | public sealed class SecurityHeadersAttribute : ActionFilterAttribute
method OnResultExecuting (line 11) | public override void OnResultExecuting(ResultExecutingContext context)
FILE: src/IdentityServer/Pages/ServerSideSessions/Index.cshtml.cs
class IndexModel (line 12) | public class IndexModel : PageModel
method IndexModel (line 16) | public IndexModel(ISessionManagementService? sessionManagementService ...
method OnGet (line 38) | public async Task OnGet()
method OnPost (line 56) | public async Task<IActionResult> OnPost()
FILE: src/IdentityServer/Pages/Telemetry.cs
class Telemetry (line 14) | public static class Telemetry
class Metrics (line 26) | public static class Metrics
class Counters (line 33) | public static class Counters
class Tags (line 44) | public static class Tags
class TagValues (line 57) | public static class TagValues
method ConsentGranted (line 78) | public static void ConsentGranted(string clientId, IEnumerable<strin...
method ConsentDenied (line 98) | public static void ConsentDenied(string clientId, IEnumerable<string...
method GrantsRevoked (line 113) | public static void GrantsRevoked(string? clientId)
method UserLogin (line 122) | public static void UserLogin(string? clientId, string idp)
method UserLoginFailure (line 130) | public static void UserLoginFailure(string? clientId, string idp, st...
method UserLogout (line 139) | public static void UserLogout(string? idp)
FILE: src/IdentityServer/Pages/TestUsers.cs
class TestUsers (line 12) | public static class TestUsers
FILE: src/IdentityServer/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
function _interopDefaultLegacy (line 12) | function _interopDefaultLegacy (e) { return e && typeof e === 'object' &...
function _defineProperties (line 16) | function _defineProperties(target, props) {
function _createClass (line 26) | function _createClass(Constructor, protoProps, staticProps) {
function _extends (line 32) | function _extends() {
function _inheritsLoose (line 50) | function _inheritsLoose(subClass, superClass) {
function toType (line 72) | function toType(obj) {
function getSpecialTransitionEndEvent (line 80) | function getSpecialTransitionEndEvent() {
function transitionEndEmulator (line 94) | function transitionEndEmulator(duration) {
function setTransitionEndSupport (line 109) | function setTransitionEndSupport() {
function Alert (line 256) | function Alert(element) {
function Button (line 418) | function Button(element) {
function Carousel (line 664) | function Carousel(element, config) {
function Collapse (line 1213) | function Collapse(element, config) {
function microtaskDebounce (line 1558) | function microtaskDebounce(fn) {
function taskDebounce (line 1572) | function taskDebounce(fn) {
function isFunction (line 1605) | function isFunction(functionToCheck) {
function getStyleComputedProperty (line 1617) | function getStyleComputedProperty(element, property) {
function getParentNode (line 1634) | function getParentNode(element) {
function getScrollParent (line 1648) | function getScrollParent(element) {
function getReferenceNode (line 1683) | function getReferenceNode(reference) {
function isIE (line 1697) | function isIE(version) {
function getOffsetParent (line 1714) | function getOffsetParent(element) {
function isOffsetContainer (line 1743) | function isOffsetContainer(element) {
function getRoot (line 1759) | function getRoot(node) {
function findCommonOffsetParent (line 1775) | function findCommonOffsetParent(element1, element2) {
function getScroll (line 1819) | function getScroll(element) {
function includeScroll (line 1843) | function includeScroll(rect, element) {
function getBordersSize (line 1866) | function getBordersSize(styles, axis) {
function getSize (line 1873) | function getSize(axis, body, html, computedStyle) {
function getWindowSizes (line 1877) | function getWindowSizes(document) {
function defineProperties (line 1895) | function defineProperties(target, props) {
function getClientRect (line 1952) | function getClientRect(offsets) {
function getBoundingClientRect (line 1966) | function getBoundingClientRect(element) {
function getOffsetRectRelativeToArbitraryNode (line 2015) | function getOffsetRectRelativeToArbitraryNode(children, parent) {
function getViewportOffsetRectRelativeToArtbitraryNode (line 2067) | function getViewportOffsetRectRelativeToArtbitraryNode(element) {
function isFixed (line 2096) | function isFixed(element) {
function getFixedPositionOffsetParent (line 2119) | function getFixedPositionOffsetParent(element) {
function getBoundaries (line 2142) | function getBoundaries(popper, reference, padding, boundariesElement) {
function getArea (line 2196) | function getArea(_ref) {
function computeAutoPlacement (line 2212) | function computeAutoPlacement(placement, refRect, popper, reference, bou...
function getReferenceOffsets (line 2273) | function getReferenceOffsets(state, popper, reference) {
function getOuterSizes (line 2287) | function getOuterSizes(element) {
function getOppositePlacement (line 2306) | function getOppositePlacement(placement) {
function getPopperOffsets (line 2323) | function getPopperOffsets(popper, referenceOffsets, placement) {
function find (line 2361) | function find(arr, check) {
function findIndex (line 2380) | function findIndex(arr, prop, value) {
function runModifiers (line 2405) | function runModifiers(modifiers, data, ends) {
function update (line 2435) | function update() {
function isModifierEnabled (line 2487) | function isModifierEnabled(modifiers, modifierName) {
function getSupportedPropertyName (line 2502) | function getSupportedPropertyName(property) {
function destroy (line 2521) | function destroy() {
function getWindow (line 2551) | function getWindow(element) {
function attachToScrollParents (line 2556) | function attachToScrollParents(scrollParent, event, callback, scrollPare...
function setupEventListeners (line 2573) | function setupEventListeners(reference, options, state, updateBound) {
function enableEventListeners (line 2593) | function enableEventListeners() {
function removeEventListeners (line 2605) | function removeEventListeners(reference, state) {
function disableEventListeners (line 2629) | function disableEventListeners() {
function isNumeric (line 2643) | function isNumeric(n) {
function setStyles (line 2655) | function setStyles(element, styles) {
function setAttributes (line 2674) | function setAttributes(element, attributes) {
function applyStyle (line 2694) | function applyStyle(data) {
function applyStyleOnLoad (line 2723) | function applyStyleOnLoad(reference, popper, options, modifierOptions, s...
function getRoundedOffsets (line 2760) | function getRoundedOffsets(data, shouldRound) {
function computeStyle (line 2799) | function computeStyle(data, options) {
function isModifierRequired (line 2900) | function isModifierRequired(modifiers, requestingName, requestedName) {
function arrow (line 2925) | function arrow(data, options) {
function getOppositeVariation (line 3007) | function getOppositeVariation(variation) {
function clockwise (line 3062) | function clockwise(placement) {
function flip (line 3083) | function flip(data, options) {
function keepTogether (line 3180) | function keepTogether(data) {
function toValue (line 3214) | function toValue(str, measurement, popperOffsets, referenceOffsets) {
function parseOffset (line 3266) | function parseOffset(offset, popperOffsets, referenceOffsets, basePlacem...
function offset (line 3342) | function offset(data, _ref) {
function preventOverflow (line 3383) | function preventOverflow(data, options) {
function shift (line 3454) | function shift(data) {
function hide (line 3487) | function hide(data) {
function inner (line 3525) | function inner(data) {
function Popper (line 3992) | function Popper(reference, popper) {
function Dropdown (line 4210) | function Dropdown(element, config) {
function Modal (line 4708) | function Modal(element, config) {
function allowedAttribute (line 5321) | function allowedAttribute(attr, allowedAttributeList) {
function sanitizeHtml (line 5345) | function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
function Tooltip (line 5472) | function Tooltip(element, config) {
function Popover (line 6149) | function Popover() {
function ScrollSpy (line 6323) | function ScrollSpy(element, config) {
function Tab (line 6607) | function Tab(element) {
function Toast (line 6835) | function Toast(element, config) {
FILE: src/IdentityServer/wwwroot/lib/bootstrap/dist/js/bootstrap.js
function _interopDefaultLegacy (line 12) | function _interopDefaultLegacy (e) { return e && typeof e === 'object' &...
function _defineProperties (line 17) | function _defineProperties(target, props) {
function _createClass (line 27) | function _createClass(Constructor, protoProps, staticProps) {
function _extends (line 33) | function _extends() {
function _inheritsLoose (line 51) | function _inheritsLoose(subClass, superClass) {
function toType (line 73) | function toType(obj) {
function getSpecialTransitionEndEvent (line 81) | function getSpecialTransitionEndEvent() {
function transitionEndEmulator (line 95) | function transitionEndEmulator(duration) {
function setTransitionEndSupport (line 110) | function setTransitionEndSupport() {
function Alert (line 257) | function Alert(element) {
function Button (line 419) | function Button(element) {
function Carousel (line 665) | function Carousel(element, config) {
function Collapse (line 1214) | function Collapse(element, config) {
function Dropdown (line 1597) | function Dropdown(element, config) {
function Modal (line 2095) | function Modal(element, config) {
function allowedAttribute (line 2708) | function allowedAttribute(attr, allowedAttributeList) {
function sanitizeHtml (line 2732) | function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
function Tooltip (line 2859) | function Tooltip(element, config) {
function Popover (line 3536) | function Popover() {
function ScrollSpy (line 3710) | function ScrollSpy(element, config) {
function Tab (line 3994) | function Tab(element) {
function Toast (line 4222) | function Toast(element, config) {
FILE: src/IdentityServer/wwwroot/lib/jquery/dist/jquery.js
function DOMEval (line 103) | function DOMEval( code, node, doc ) {
function toType (line 133) | function toType( obj ) {
function isArrayLike (line 503) | function isArrayLike( obj ) {
function Sizzle (line 755) | function Sizzle( selector, context, results, seed ) {
function createCache (line 903) | function createCache() {
function markFunction (line 923) | function markFunction( fn ) {
function assert (line 932) | function assert( fn ) {
function addHandle (line 956) | function addHandle( attrs, handler ) {
function siblingCheck (line 971) | function siblingCheck( a, b ) {
function createInputPseudo (line 997) | function createInputPseudo( type ) {
function createButtonPseudo (line 1008) | function createButtonPseudo( type ) {
function createDisabledPseudo (line 1019) | function createDisabledPseudo( disabled ) {
function createPositionalPseudo (line 1075) | function createPositionalPseudo( fn ) {
function testContext (line 1098) | function testContext( context ) {
function setFilters (line 2309) | function setFilters() {}
function toSelector (line 2383) | function toSelector( tokens ) {
function addCombinator (line 2393) | function addCombinator( matcher, combinator, base ) {
function elementMatcher (line 2460) | function elementMatcher( matchers ) {
function multipleContexts (line 2474) | function multipleContexts( selector, contexts, results ) {
function condense (line 2483) | function condense( unmatched, map, filter, context, xml ) {
function setMatcher (line 2504) | function setMatcher( preFilter, selector, matcher, postFilter, postFinde...
function matcherFromTokens (line 2604) | function matcherFromTokens( tokens ) {
function matcherFromGroupMatchers (line 2667) | function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
function nodeName (line 3025) | function nodeName( elem, name ) {
function winnow (line 3035) | function winnow( elements, qualifier, not ) {
function sibling (line 3330) | function sibling( cur, dir ) {
function createOptions (line 3423) | function createOptions( options ) {
function Identity (line 3648) | function Identity( v ) {
function Thrower (line 3651) | function Thrower( ex ) {
function adoptValue (line 3655) | function adoptValue( value, resolve, reject, noValue ) {
function resolve (line 3748) | function resolve( depth, deferred, handler, special ) {
function completed (line 4113) | function completed() {
function fcamelCase (line 4208) | function fcamelCase( _all, letter ) {
function camelCase (line 4215) | function camelCase( string ) {
function Data (line 4232) | function Data() {
function getData (line 4401) | function getData( data ) {
function dataAttr (line 4426) | function dataAttr( elem, key, data ) {
function adjustCSS (line 4738) | function adjustCSS( elem, prop, valueParts, tween ) {
function getDefaultDisplay (line 4806) | function getDefaultDisplay( elem ) {
function showHide (line 4829) | function showHide( elements, show ) {
function getAll (line 4961) | function getAll( context, tag ) {
function setGlobalEval (line 4986) | function setGlobalEval( elems, refElements ) {
function buildFragment (line 5002) | function buildFragment( elems, context, scripts, selection, ignored ) {
function returnTrue (line 5097) | function returnTrue() {
function returnFalse (line 5101) | function returnFalse() {
function expectSync (line 5111) | function expectSync( elem, type ) {
function safeActiveElement (line 5118) | function safeActiveElement() {
function on (line 5124) | function on( elem, types, selector, data, fn, one ) {
function leverageNative (line 5612) | function leverageNative( el, type, expectSync ) {
function manipulationTarget (line 5976) | function manipulationTarget( elem, content ) {
function disableScript (line 5987) | function disableScript( elem ) {
function restoreScript (line 5991) | function restoreScript( elem ) {
function cloneCopyEvent (line 6001) | function cloneCopyEvent( src, dest ) {
function fixInput (line 6034) | function fixInput( src, dest ) {
function domManip (line 6047) | function domManip( collection, args, callback, ignored ) {
function remove (line 6139) | function remove( elem, selector, keepData ) {
function computeStyleTests (line 6453) | function computeStyleTests() {
function roundPixelMeasures (line 6497) | function roundPixelMeasures( measure ) {
function curCSS (line 6571) | function curCSS( elem, name, computed ) {
function addGetHookIf (line 6624) | function addGetHookIf( conditionFn, hookFn ) {
function vendorPropName (line 6649) | function vendorPropName( name ) {
function finalPropName (line 6664) | function finalPropName( name ) {
function setPositiveNumber (line 6690) | function setPositiveNumber( _elem, value, subtract ) {
function boxModelAdjustment (line 6702) | function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, ...
function getWidthOrHeight (line 6770) | function getWidthOrHeight( elem, dimension, extra ) {
function Tween (line 7146) | function Tween( elem, options, prop, end, easing ) {
function schedule (line 7269) | function schedule() {
function createFxNow (line 7282) | function createFxNow() {
function genFx (line 7290) | function genFx( type, includeWidth ) {
function createTween (line 7310) | function createTween( value, prop, animation ) {
function defaultPrefilter (line 7324) | function defaultPrefilter( elem, props, opts ) {
function propFilter (line 7496) | function propFilter( props, specialEasing ) {
function Animation (line 7533) | function Animation( elem, properties, options ) {
function stripAndCollapse (line 8248) | function stripAndCollapse( value ) {
function getClass (line 8254) | function getClass( elem ) {
function classesToArray (line 8258) | function classesToArray( value ) {
function buildParams (line 8885) | function buildParams( prefix, obj, traditional, add ) {
function addToPrefiltersOrTransports (line 9039) | function addToPrefiltersOrTransports( structure ) {
function inspectPrefiltersOrTransports (line 9073) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
function ajaxExtend (line 9102) | function ajaxExtend( target, src ) {
function ajaxHandleResponses (line 9122) | function ajaxHandleResponses( s, jqXHR, responses ) {
function ajaxConvert (line 9180) | function ajaxConvert( s, response, jqXHR, isSuccess ) {
function done (line 9696) | function done( status, nativeStatusText, responses, headers ) {
FILE: src/IdentityServer/wwwroot/lib/jquery/dist/jquery.slim.js
function DOMEval (line 103) | function DOMEval( code, node, doc ) {
function toType (line 133) | function toType( obj ) {
function isArrayLike (line 503) | function isArrayLike( obj ) {
function Sizzle (line 755) | function Sizzle( selector, context, results, seed ) {
function createCache (line 903) | function createCache() {
function markFunction (line 923) | function markFunction( fn ) {
function assert (line 932) | function assert( fn ) {
function addHandle (line 956) | function addHandle( attrs, handler ) {
function siblingCheck (line 971) | function siblingCheck( a, b ) {
function createInputPseudo (line 997) | function createInputPseudo( type ) {
function createButtonPseudo (line 1008) | function createButtonPseudo( type ) {
function createDisabledPseudo (line 1019) | function createDisabledPseudo( disabled ) {
function createPositionalPseudo (line 1075) | function createPositionalPseudo( fn ) {
function testContext (line 1098) | function testContext( context ) {
function setFilters (line 2309) | function setFilters() {}
function toSelector (line 2383) | function toSelector( tokens ) {
function addCombinator (line 2393) | function addCombinator( matcher, combinator, base ) {
function elementMatcher (line 2460) | function elementMatcher( matchers ) {
function multipleContexts (line 2474) | function multipleContexts( selector, contexts, results ) {
function condense (line 2483) | function condense( unmatched, map, filter, context, xml ) {
function setMatcher (line 2504) | function setMatcher( preFilter, selector, matcher, postFilter, postFinde...
function matcherFromTokens (line 2604) | function matcherFromTokens( tokens ) {
function matcherFromGroupMatchers (line 2667) | function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
function nodeName (line 3025) | function nodeName( elem, name ) {
function winnow (line 3035) | function winnow( elements, qualifier, not ) {
function sibling (line 3330) | function sibling( cur, dir ) {
function createOptions (line 3423) | function createOptions( options ) {
function Identity (line 3648) | function Identity( v ) {
function Thrower (line 3651) | function Thrower( ex ) {
function adoptValue (line 3655) | function adoptValue( value, resolve, reject, noValue ) {
function resolve (line 3748) | function resolve( depth, deferred, handler, special ) {
function completed (line 4113) | function completed() {
function fcamelCase (line 4208) | function fcamelCase( _all, letter ) {
function camelCase (line 4215) | function camelCase( string ) {
function Data (line 4232) | function Data() {
function getData (line 4401) | function getData( data ) {
function dataAttr (line 4426) | function dataAttr( elem, key, data ) {
function adjustCSS (line 4738) | function adjustCSS( elem, prop, valueParts, tween ) {
function getDefaultDisplay (line 4806) | function getDefaultDisplay( elem ) {
function showHide (line 4829) | function showHide( elements, show ) {
function getAll (line 4961) | function getAll( context, tag ) {
function setGlobalEval (line 4986) | function setGlobalEval( elems, refElements ) {
function buildFragment (line 5002) | function buildFragment( elems, context, scripts, selection, ignored ) {
function returnTrue (line 5097) | function returnTrue() {
function returnFalse (line 5101) | function returnFalse() {
function expectSync (line 5111) | function expectSync( elem, type ) {
function safeActiveElement (line 5118) | function safeActiveElement() {
function on (line 5124) | function on( elem, types, selector, data, fn, one ) {
function leverageNative (line 5612) | function leverageNative( el, type, expectSync ) {
function manipulationTarget (line 5976) | function manipulationTarget( elem, content ) {
function disableScript (line 5987) | function disableScript( elem ) {
function restoreScript (line 5991) | function restoreScript( elem ) {
function cloneCopyEvent (line 6001) | function cloneCopyEvent( src, dest ) {
function fixInput (line 6034) | function fixInput( src, dest ) {
function domManip (line 6047) | function domManip( collection, args, callback, ignored ) {
function remove (line 6139) | function remove( elem, selector, keepData ) {
function computeStyleTests (line 6453) | function computeStyleTests() {
function roundPixelMeasures (line 6497) | function roundPixelMeasures( measure ) {
function curCSS (line 6571) | function curCSS( elem, name, computed ) {
function addGetHookIf (line 6624) | function addGetHookIf( conditionFn, hookFn ) {
function vendorPropName (line 6649) | function vendorPropName( name ) {
function finalPropName (line 6664) | function finalPropName( name ) {
function setPositiveNumber (line 6690) | function setPositiveNumber( _elem, value, subtract ) {
function boxModelAdjustment (line 6702) | function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, ...
function getWidthOrHeight (line 6770) | function getWidthOrHeight( elem, dimension, extra ) {
function stripAndCollapse (line 7455) | function stripAndCollapse( value ) {
function getClass (line 7461) | function getClass( elem ) {
function classesToArray (line 7465) | function classesToArray( value ) {
function buildParams (line 8086) | function buildParams( prefix, obj, traditional, add ) {
FILE: src/PythonInference/routers/classifier.py
class ClassifyRequest (line 9) | class ClassifyRequest(BaseModel):
function classify_text (line 14) | def classify_text(item: ClassifyRequest) -> str:
FILE: src/PythonInference/routers/embedder.py
class EmbedRequest (line 8) | class EmbedRequest(BaseModel):
function embed_sentences (line 12) | def embed_sentences(req: EmbedRequest) -> list[list[float]]:
FILE: src/ServiceDefaults/Clients/Backend/CustomerBackendClient.cs
class CustomerBackendClient (line 6) | public class CustomerBackendClient(HttpClient http)
method CreateTicketAsync (line 8) | public Task CreateTicketAsync(CreateTicketRequest request)
method ListTicketsAsync (line 11) | public Task<ListTicketsResult> ListTicketsAsync()
method GetTicketDetailsAsync (line 14) | public Task<TicketDetailsResult> GetTicketDetailsAsync(int ticketId)
method SendTicketMessageAsync (line 17) | public Task SendTicketMessageAsync(int ticketId, SendTicketMessageRequ...
method CloseTicketAsync (line 20) | public Task CloseTicketAsync(int ticketId)
method FindProductsAsync (line 23) | public Task<FindProductsResult[]> FindProductsAsync(string searchText)
FILE: src/ServiceDefaults/Clients/Backend/DevToolBackendClient.cs
class DevToolBackendClient (line 5) | public static class DevToolBackendClient
method GetDevToolStaffBackendClientAsync (line 11) | public static async Task<StaffBackendClient> GetDevToolStaffBackendCli...
FILE: src/ServiceDefaults/Clients/Backend/StaffBackendClient.cs
class StaffBackendClient (line 8) | public class StaffBackendClient(HttpClient http)
method ListTicketsAsync (line 10) | public async Task<ListTicketsResult> ListTicketsAsync(ListTicketsReque...
method GetTicketDetailsAsync (line 16) | public Task<TicketDetailsResult> GetTicketDetailsAsync(int ticketId)
method AssistantChatAsync (line 19) | public async IAsyncEnumerable<AssistantChatReplyItem> AssistantChatAsy...
method ReadManualAsync (line 36) | public async Task<Stream?> ReadManualAsync(string file, CancellationTo...
method SendTicketMessageAsync (line 43) | public async Task SendTicketMessageAsync(int ticketId, SendTicketMessa...
method UpdateTicketDetailsAsync (line 48) | public async Task UpdateTicketDetailsAsync(int ticketId, int? productI...
method FindCategoriesAsync (line 53) | public Task<FindCategoriesResult[]> FindCategoriesAsync(string searchT...
method FindCategoriesAsync (line 58) | public Task<FindCategoriesResult[]> FindCategoriesAsync(IEnumerable<in...
method FindProductsAsync (line 63) | public Task<FindProductsResult[]> FindProductsAsync(string searchText)
type ListTicketsRequest (line 69) | public record ListTicketsRequest(TicketStatus? FilterByStatus, List<int>...
type ListTicketsResult (line 71) | public record ListTicketsResult(ICollection<ListTicketsResultItem> Items...
type ListTicketsResultItem (line 73) | public record ListTicketsResultItem(
type TicketDetailsResult (line 76) | public record TicketDetailsResult(
type TicketDetailsResultMessage (line 82) | public record TicketDetailsResultMessage(int MessageId, DateTime Created...
type UpdateTicketDetailsRequest (line 84) | public record UpdateTicketDetailsRequest(int? ProductId, TicketType Tick...
type AssistantChatRequest (line 86) | public record AssistantChatRequest(
class AssistantChatRequestMessage (line 93) | public class AssistantChatRequestMessage
type AssistantChatReplyItem (line 99) | public record AssistantChatReplyItem(AssistantChatReplyItemType Type, st...
type AssistantChatReplyItemType (line 101) | public enum AssistantChatReplyItemType { AnswerChunk, Search, SearchResu...
type SendTicketMessageRequest (line 103) | public record SendTicketMessageRequest(string Text);
type FindCategoriesResult (line 105) | public record FindCategoriesResult(int CategoryId)
type FindProductsResult (line 110) | public record FindProductsResult(int ProductId, string Brand, string Mod...
type TicketStatus (line 112) | public enum TicketStatus
type TicketType (line 118) | public enum TicketType
type CreateTicketRequest (line 126) | public record CreateTicketRequest(
FILE: src/ServiceDefaults/Clients/ChatCompletion/ChatCompletionServiceExtensions.cs
class ChatCompletionServiceExtensions (line 5) | public static class ChatCompletionServiceExtensions
method AddChatCompletionService (line 7) | public static void AddChatCompletionService(this IHostApplicationBuild...
FILE: src/ServiceDefaults/Clients/ChatCompletion/PreventStreamingWithFunctions.cs
class PreventStreamingWithFunctionsExtensions (line 10) | public static class PreventStreamingWithFunctionsExtensions
method UsePreventStreamingWithFunctions (line 12) | public static ChatClientBuilder UsePreventStreamingWithFunctions(this ...
class PreventStreamingWithFunctions (line 17) | private class PreventStreamingWithFunctions(IChatClient innerClient) :...
method GetResponseAsync (line 19) | public override Task<ChatResponse> GetResponseAsync(IEnumerable<Chat...
method GetStreamingResponseAsync (line 36) | public override IAsyncEnumerable<ChatResponseUpdate> GetStreamingRes...
method TreatNonstreamingAsStreaming (line 43) | private async IAsyncEnumerable<ChatResponseUpdate> TreatNonstreaming...
FILE: src/ServiceDefaults/Clients/ChatCompletion/ServiceCollectionChatClientExtensions.cs
class ServiceCollectionChatClientExtensions (line 11) | public static class ServiceCollectionChatClientExtensions
method AddOllamaChatClient (line 13) | public static ChatClientBuilder AddOllamaChatClient(
method AddOllamaChatClient (line 33) | public static ChatClientBuilder AddOllamaChatClient(
method AddOpenAIChatClient (line 51) | public static ChatClientBuilder AddOpenAIChatClient(
method AddOpenAIChatClient (line 80) | public static ChatClientBuilder AddOpenAIChatClient(
FILE: src/ServiceDefaults/Clients/ChatCompletion/TestCachingChatClientBuilderExtensions.cs
class TestCachingChatClientBuilderExtensions (line 30) | public static class TestCachingChatClientBuilderExtensions
method UseCachingForTest (line 32) | public static ChatClientBuilder UseCachingForTest(this ChatClientBuild...
class DiskCache (line 47) | private class DiskCache(string cacheDir) : IDistributedCache
method Get (line 49) | public byte[]? Get(string key)
method GetAsync (line 55) | public async Task<byte[]?> GetAsync(string key, CancellationToken to...
method Refresh (line 61) | public void Refresh(string key)
method RefreshAsync (line 65) | public Task RefreshAsync(string key, CancellationToken token = default)
method Remove (line 68) | public void Remove(string key)
method RemoveAsync (line 71) | public Task RemoveAsync(string key, CancellationToken token = default)
method Set (line 77) | public void Set(string key, byte[] value, DistributedCacheEntryOptio...
method SetAsync (line 84) | public async Task SetAsync(string key, byte[] value, DistributedCach...
method FilePath (line 91) | private string FilePath(string key)
FILE: src/ServiceDefaults/Clients/HttpClientExtensions.cs
class HttpClientExtensions (line 9) | public static class HttpClientExtensions
method AddAuthToken (line 11) | public static IHttpClientBuilder AddAuthToken(this IHttpClientBuilder ...
class HttpClientAuthorizationDelegatingHandler (line 22) | private class HttpClientAuthorizationDelegatingHandler : DelegatingHan...
method HttpClientAuthorizationDelegatingHandler (line 26) | public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor...
method HttpClientAuthorizationDelegatingHandler (line 31) | public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor...
method SendAsync (line 36) | protected override async Task<HttpResponseMessage> SendAsync(HttpReq...
FILE: src/ServiceDefaults/Clients/PythonInference/PythonInferenceClient.cs
class PythonInferenceClient (line 5) | public class PythonInferenceClient(HttpClient http)
method ClassifyTextAsync (line 7) | public async Task<string?> ClassifyTextAsync(string text, IEnumerable<...
FILE: src/ServiceDefaults/Clients/QdrantHttpClientExtensions.cs
class QdrantHttpClientExtensions (line 8) | public static class QdrantHttpClientExtensions
method AddQdrantHttpClient (line 16) | public static void AddQdrantHttpClient(this WebApplicationBuilder buil...
method GetQdrantHttpClient (line 32) | public static HttpClient GetQdrantHttpClient(this IServiceProvider ser...
method GetServiceKey (line 35) | private static string GetServiceKey(string connectionName) => $"{conne...
FILE: src/ServiceDefaults/Extensions.cs
class Extensions (line 12) | public static class Extensions
method AddServiceDefaults (line 14) | public static IHostApplicationBuilder AddServiceDefaults(this IHostApp...
method ConfigureOpenTelemetry (line 34) | public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHos...
method AddOpenTelemetryExporters (line 64) | private static IHostApplicationBuilder AddOpenTelemetryExporters(this ...
method AddDefaultHealthChecks (line 87) | public static IHostApplicationBuilder AddDefaultHealthChecks(this IHos...
method MapDefaultEndpoints (line 96) | public static WebApplication MapDefaultEndpoints(this WebApplication app)
FILE: src/StaffWebUI/Components/Pages/RedisSubscribingComponent.cs
class RedisSubscribingComponent (line 10) | public abstract class RedisSubscribingComponent : ComponentBase, IDispos...
method HandleMessage (line 49) | void HandleMessage(RedisChannel channel, RedisValue value)
method HandleMessageAsync (line 52) | async Task HandleMessageAsync(RedisChannel channel, RedisValue value)
method Dispose (line 77) | protected virtual void Dispose(bool disposing)
method Dispose (line 91) | public void Dispose()
method OnRedisNotificationAsync (line 97) | protected virtual Task OnRedisNotificationAsync(RedisValue value)
FILE: src/StaffWebUI/Components/Pages/Ticket/TicketAssistant.razor.js
function submitOnEnter (line 1) | function submitOnEnter(formElem) {
FILE: src/StaffWebUI/Components/Pages/Ticket/TicketAssistantMessage.razor.js
function addAnswerChunk (line 1) | function addAnswerChunk(elem, chunkText) {
FILE: src/StaffWebUI/Components/Pages/Tickets/Columns/LinkPropertyColumn.cs
class LinkPropertyColumn (line 7) | public class LinkPropertyColumn<TGridItem, TProp> : PropertyColumn<TGrid...
method CellContent (line 12) | protected override void CellContent(RenderTreeBuilder builder, TGridIt...
FILE: src/StaffWebUI/Components/Pages/Tickets/Columns/LinkTemplateColumn.cs
class LinkTemplateColumn (line 7) | public class LinkTemplateColumn<TGridItem> : TemplateColumn<TGridItem>
method CellContent (line 12) | protected override void CellContent(RenderTreeBuilder builder, TGridIt...
FILE: src/StaffWebUI/wwwroot/pdfjs-4.2.67-dist/build/pdf.mjs
function makeColorComp (line 44) | function makeColorComp(n) {
function scaleAndClamp (line 47) | function scaleAndClamp(x) {
class ColorConverters (line 50) | class ColorConverters {
method CMYK_G (line 51) | static CMYK_G([c, y, m, k]) {
method G_CMYK (line 54) | static G_CMYK([g]) {
method G_RGB (line 57) | static G_RGB([g]) {
method G_rgb (line 60) | static G_rgb([g]) {
method G_HTML (line 64) | static G_HTML([g]) {
method RGB_G (line 68) | static RGB_G([r, g, b]) {
method RGB_rgb (line 71) | static RGB_rgb(color) {
method RGB_HTML (line 74) | static RGB_HTML(color) {
method T_HTML (line 77) | static T_HTML() {
method T_rgb (line 80) | static T_rgb() {
method CMYK_RGB (line 83) | static CMYK_RGB([c, y, m, k]) {
method CMYK_rgb (line 86) | static CMYK_rgb([c, y, m, k]) {
method CMYK_HTML (line 89) | static CMYK_HTML(components) {
method RGB_CMYK (line 93) | static RGB_CMYK([r, g, b]) {
function getRectDims (line 113) | function getRectDims(rect) {
class AnnotationElementFactory (line 119) | class AnnotationElementFactory {
method create (line 120) | static create(parameters) {
class AnnotationElement (line 180) | class AnnotationElement {
method constructor (line 183) | constructor(parameters, {
method _hasPopupData (line 208) | static _hasPopupData({
method hasPopupData (line 215) | get hasPopupData() {
method updateEdited (line 218) | updateEdited(params) {
method resetEdited (line 232) | resetEdited() {
method #setRectEdited (line 239) | #setRectEdited(rect) {
method _createContainer (line 273) | _createContainer(ignoreBorder) {
method setRotation (line 370) | setRotation(angle, container = this.container) {
method _commonActions (line 394) | get _commonActions() {
method _dispatchEventFromSandbox (line 472) | _dispatchEventFromSandbox(actions, jsEvent) {
method _setDefaultPropertiesFromJS (line 479) | _setDefaultPropertiesFromJS(element) {
method _createQuadrilaterals (line 502) | _createQuadrilaterals() {
method _createPopup (line 580) | _createPopup() {
method render (line 603) | render() {
method _getElementsByName (line 606) | _getElementsByName(name, skipId = null) {
method show (line 656) | show() {
method hide (line 662) | hide() {
method getElementsToTriggerPopup (line 668) | getElementsToTriggerPopup() {
method addHighlightArea (line 671) | addHighlightArea() {
method _isEditable (line 681) | get _isEditable() {
method _editOnDoubleClick (line 684) | _editOnDoubleClick() {
class LinkAnnotationElement (line 703) | class LinkAnnotationElement extends AnnotationElement {
method constructor (line 704) | constructor(parameters, options = null) {
method render (line 712) | render() {
method #setInternalLink (line 754) | #setInternalLink() {
method _bindLink (line 757) | _bindLink(link, destination) {
method _bindNamedAction (line 769) | _bindNamedAction(link, action) {
method #bindAttachment (line 777) | #bindAttachment(link, attachment, dest = null) {
method #bindSetOCGState (line 785) | #bindSetOCGState(link, action) {
method _bindJSAction (line 793) | _bindJSAction(link, data) {
method _bindResetFormAction (line 817) | _bindResetFormAction(link, resetForm) {
class TextAnnotationElement (line 920) | class TextAnnotationElement extends AnnotationElement {
method constructor (line 921) | constructor(parameters) {
method render (line 926) | render() {
class WidgetAnnotationElement (line 941) | class WidgetAnnotationElement extends AnnotationElement {
method render (line 942) | render() {
method showElementAndHideCanvas (line 945) | showElementAndHideCanvas(element) {
method _getKeyModifier (line 953) | _getKeyModifier(event) {
method _setEventListener (line 956) | _setEventListener(element, elementData, baseName, eventName, valueGett...
method _setEventListeners (line 997) | _setEventListeners(element, elementData, names, getter) {
method _setBackgroundColor (line 1014) | _setBackgroundColor(element) {
method _setTextStyle (line 1018) | _setTextStyle(element) {
method _setRequired (line 1043) | _setRequired(element, isRequired) {
class TextWidgetAnnotationElement (line 1052) | class TextWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 1053) | constructor(parameters) {
method setPropertyOnSiblings (line 1059) | setPropertyOnSiblings(base, key, value, keyInStorage) {
method render (line 1070) | render() {
class SignatureWidgetAnnotationElement (line 1370) | class SignatureWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 1371) | constructor(parameters) {
class CheckboxWidgetAnnotationElement (line 1377) | class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 1378) | constructor(parameters) {
method render (line 1383) | render() {
class RadioButtonWidgetAnnotationElement (line 1451) | class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 1452) | constructor(parameters) {
method render (line 1457) | render() {
class PushButtonWidgetAnnotationElement (line 1534) | class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
method constructor (line 1535) | constructor(parameters) {
method render (line 1540) | render() {
class ChoiceWidgetAnnotationElement (line 1553) | class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 1554) | constructor(parameters) {
method render (line 1559) | render() {
class PopupAnnotationElement (line 1775) | class PopupAnnotationElement extends AnnotationElement {
method constructor (line 1776) | constructor(parameters) {
method render (line 1786) | render() {
class PopupElement (line 1811) | class PopupElement {
method constructor (line 1829) | constructor({
method render (line 1867) | render() {
method _formatContents (line 1948) | _formatContents({
method #keyDown (line 1965) | #keyDown(event) {
method #toggle (line 1973) | #toggle() {
method #show (line 1985) | #show() {
method #hide (line 1996) | #hide() {
method forceHide (line 2004) | forceHide() {
method maybeShow (line 2011) | maybeShow() {
method isVisible (line 2018) | get isVisible() {
class FreeTextAnnotationElement (line 2022) | class FreeTextAnnotationElement extends AnnotationElement {
method constructor (line 2023) | constructor(parameters) {
method render (line 2032) | render() {
method _isEditable (line 2051) | get _isEditable() {
class LineAnnotationElement (line 2055) | class LineAnnotationElement extends AnnotationElement {
method constructor (line 2057) | constructor(parameters) {
method render (line 2063) | render() {
method getElementsToTriggerPopup (line 2086) | getElementsToTriggerPopup() {
method addHighlightArea (line 2089) | addHighlightArea() {
class SquareAnnotationElement (line 2093) | class SquareAnnotationElement extends AnnotationElement {
method constructor (line 2095) | constructor(parameters) {
method render (line 2101) | render() {
method getElementsToTriggerPopup (line 2125) | getElementsToTriggerPopup() {
method addHighlightArea (line 2128) | addHighlightArea() {
class CircleAnnotationElement (line 2132) | class CircleAnnotationElement extends AnnotationElement {
method constructor (line 2134) | constructor(parameters) {
method render (line 2140) | render() {
method getElementsToTriggerPopup (line 2164) | getElementsToTriggerPopup() {
method addHighlightArea (line 2167) | addHighlightArea() {
class PolylineAnnotationElement (line 2171) | class PolylineAnnotationElement extends AnnotationElement {
method constructor (line 2173) | constructor(parameters) {
method render (line 2181) | render() {
method getElementsToTriggerPopup (line 2208) | getElementsToTriggerPopup() {
method addHighlightArea (line 2211) | addHighlightArea() {
class PolygonAnnotationElement (line 2215) | class PolygonAnnotationElement extends PolylineAnnotationElement {
method constructor (line 2216) | constructor(parameters) {
class CaretAnnotationElement (line 2222) | class CaretAnnotationElement extends AnnotationElement {
method constructor (line 2223) | constructor(parameters) {
method render (line 2229) | render() {
class InkAnnotationElement (line 2237) | class InkAnnotationElement extends AnnotationElement {
method constructor (line 2239) | constructor(parameters) {
method render (line 2248) | render() {
method getElementsToTriggerPopup (line 2278) | getElementsToTriggerPopup() {
method addHighlightArea (line 2281) | addHighlightArea() {
class HighlightAnnotationElement (line 2285) | class HighlightAnnotationElement extends AnnotationElement {
method constructor (line 2286) | constructor(parameters) {
method render (line 2293) | render() {
class UnderlineAnnotationElement (line 2301) | class UnderlineAnnotationElement extends AnnotationElement {
method constructor (line 2302) | constructor(parameters) {
method render (line 2309) | render() {
class SquigglyAnnotationElement (line 2317) | class SquigglyAnnotationElement extends AnnotationElement {
method constructor (line 2318) | constructor(parameters) {
method render (line 2325) | render() {
class StrikeOutAnnotationElement (line 2333) | class StrikeOutAnnotationElement extends AnnotationElement {
method constructor (line 2334) | constructor(parameters) {
method render (line 2341) | render() {
class StampAnnotationElement (line 2349) | class StampAnnotationElement extends AnnotationElement {
method constructor (line 2350) | constructor(parameters) {
method render (line 2356) | render() {
class FileAttachmentAnnotationElement (line 2364) | class FileAttachmentAnnotationElement extends AnnotationElement {
method constructor (line 2366) | constructor(parameters) {
method render (line 2382) | render() {
method getElementsToTriggerPopup (line 2416) | getElementsToTriggerPopup() {
method addHighlightArea (line 2419) | addHighlightArea() {
method #download (line 2422) | #download() {
class AnnotationLayer (line 2426) | class AnnotationLayer {
method constructor (line 2430) | constructor({
method #appendElement (line 2446) | #appendElement(element, id) {
method render (line 2452) | async render(params) {
method update (line 2519) | update({
method #setAnnotationCanvasMap (line 2530) | #setAnnotationCanvasMap() {
method getEditableAnnotations (line 2556) | getEditableAnnotations() {
method getEditableAnnotation (line 2559) | getEditableAnnotation(id) {
class AnnotationStorage (line 2586) | class AnnotationStorage {
method constructor (line 2589) | constructor() {
method getValue (line 2594) | getValue(key, defaultValue) {
method getRawValue (line 2601) | getRawValue(key) {
method remove (line 2604) | remove(key) {
method setValue (line 2618) | setValue(key, value) {
method has (line 2639) | has(key) {
method getAll (line 2642) | getAll() {
method setAll (line 2645) | setAll(obj) {
method size (line 2650) | get size() {
method #setModified (line 2653) | #setModified() {
method resetModified (line 2661) | resetModified() {
method print (line 2669) | get print() {
method serializable (line 2672) | get serializable() {
method editorStats (line 2702) | get editorStats() {
class PrintAnnotationStorage (line 2740) | class PrintAnnotationStorage extends AnnotationStorage {
method constructor (line 2742) | constructor(parent) {
method print (line 2758) | get print() {
method serializable (line 2761) | get serializable() {
function getDocument (line 2822) | function getDocument(src) {
function _fetchDocument (line 2982) | async function _fetchDocument(worker, source) {
function getUrlProp (line 2992) | function getUrlProp(val) {
function getDataProp (line 3005) | function getDataProp(val) {
function isRefProxy (line 3020) | function isRefProxy(ref) {
class PDFDocumentLoadingTask (line 3023) | class PDFDocumentLoadingTask {
method constructor (line 3025) | constructor() {
method promise (line 3034) | get promise() {
method destroy (line 3037) | async destroy() {
class PDFDataRangeTransport (line 3057) | class PDFDataRangeTransport {
method constructor (line 3058) | constructor(length, initialData, progressiveDone = false, contentDispo...
method addRangeListener (line 3069) | addRangeListener(listener) {
method addProgressListener (line 3072) | addProgressListener(listener) {
method addProgressiveReadListener (line 3075) | addProgressiveReadListener(listener) {
method addProgressiveDoneListener (line 3078) | addProgressiveDoneListener(listener) {
method onDataRange (line 3081) | onDataRange(begin, chunk) {
method onDataProgress (line 3086) | onDataProgress(loaded, total) {
method onDataProgressiveRead (line 3093) | onDataProgressiveRead(chunk) {
method onDataProgressiveDone (line 3100) | onDataProgressiveDone() {
method transportReady (line 3107) | transportReady() {
method requestDataRange (line 3110) | requestDataRange(begin, end) {
method abort (line 3113) | abort() {}
class PDFDocumentProxy (line 3115) | class PDFDocumentProxy {
method constructor (line 3116) | constructor(pdfInfo, transport) {
method annotationStorage (line 3120) | get annotationStorage() {
method filterFactory (line 3123) | get filterFactory() {
method numPages (line 3126) | get numPages() {
method fingerprints (line 3129) | get fingerprints() {
method isPureXfa (line 3132) | get isPureXfa() {
method allXfaHtml (line 3135) | get allXfaHtml() {
method getPage (line 3138) | getPage(pageNumber) {
method getPageIndex (line 3141) | getPageIndex(ref) {
method getDestinations (line 3144) | getDestinations() {
method getDestination (line 3147) | getDestination(id) {
method getPageLabels (line 3150) | getPageLabels() {
method getPageLayout (line 3153) | getPageLayout() {
method getPageMode (line 3156) | getPageMode() {
method getViewerPreferences (line 3159) | getViewerPreferences() {
method getOpenAction (line 3162) | getOpenAction() {
method getAttachments (line 3165) | getAttachments() {
method getJSActions (line 3168) | getJSActions() {
method getOutline (line 3171) | getOutline() {
method getOptionalContentConfig (line 3174) | getOptionalContentConfig({
method getPermissions (line 3182) | getPermissions() {
method getMetadata (line 3185) | getMetadata() {
method getMarkInfo (line 3188) | getMarkInfo() {
method getData (line 3191) | getData() {
method saveDocument (line 3194) | saveDocument() {
method getDownloadInfo (line 3197) | getDownloadInfo() {
method cleanup (line 3200) | cleanup(keepLoadedFonts = false) {
method destroy (line 3203) | destroy() {
method cachedPageNumber (line 3206) | cachedPageNumber(ref) {
method loadingParams (line 3209) | get loadingParams() {
method loadingTask (line 3212) | get loadingTask() {
method getFieldObjects (line 3215) | getFieldObjects() {
method hasJSActions (line 3218) | hasJSActions() {
method getCalculationOrderIds (line 3221) | getCalculationOrderIds() {
class PDFPageProxy (line 3225) | class PDFPageProxy {
method constructor (line 3228) | constructor(pageIndex, pageInfo, transport, pdfBug = false) {
method pageNumber (line 3240) | get pageNumber() {
method rotate (line 3243) | get rotate() {
method ref (line 3246) | get ref() {
method userUnit (line 3249) | get userUnit() {
method view (line 3252) | get view() {
method getViewport (line 3255) | getViewport({
method getAnnotations (line 3271) | getAnnotations({
method getJSActions (line 3279) | getJSActions() {
method filterFactory (line 3282) | get filterFactory() {
method isPureXfa (line 3285) | get isPureXfa() {
method getXfa (line 3288) | async getXfa() {
method render (line 3291) | render({
method getOperatorList (line 3389) | getOperatorList({
method streamTextContent (line 3423) | streamTextContent({
method getTextContent (line 3439) | getTextContent(params = {}) {
method getStructTree (line 3467) | getStructTree() {
method _destroy (line 3470) | _destroy() {
method cleanup (line 3492) | cleanup(resetStats = false) {
method #tryCleanup (line 3500) | #tryCleanup(delayed = false) {
method #abortDelayedCleanup (line 3525) | #abortDelayedCleanup() {
method _startRenderPage (line 3531) | _startRenderPage(transparency, cacheKey) {
method _renderPageChunk (line 3539) | _renderPageChunk(operatorListChunk, intentState) {
method _pumpOperatorList (line 3553) | _pumpOperatorList({
method _abortOperatorList (line 3608) | _abortOperatorList({
method stats (line 3653) | get stats() {
class LoopbackPort (line 3657) | class LoopbackPort {
method postMessage (line 3660) | postMessage(obj, transfer) {
method addEventListener (line 3672) | addEventListener(name, listener) {
method removeEventListener (line 3675) | removeEventListener(name, listener) {
method terminate (line 3678) | terminate() {
class PDFWorker (line 3711) | class PDFWorker {
method constructor (line 3713) | constructor({
method promise (line 3735) | get promise() {
method port (line 3738) | get port() {
method messageHandler (line 3741) | get messageHandler() {
method _initializeFromPort (line 3744) | _initializeFromPort(port) {
method _initialize (line 3753) | _initialize() {
method _setupFakeWorker (line 3826) | _setupFakeWorker() {
method destroy (line 3851) | destroy() {
method fromPort (line 3864) | static fromPort(params) {
method workerSrc (line 3877) | static get workerSrc() {
method #mainThreadWorkerMessageHandler (line 3883) | static get #mainThreadWorkerMessageHandler() {
method _setupFakeWorkerGlobal (line 3890) | static get _setupFakeWorkerGlobal() {
class WorkerTransport (line 3901) | class WorkerTransport {
method constructor (line 3907) | constructor(messageHandler, loadingTask, networkStream, params, factor...
method #cacheSimpleMethod (line 3928) | #cacheSimpleMethod(name, data = null) {
method annotationStorage (line 3937) | get annotationStorage() {
method getRenderingIntent (line 3940) | getRenderingIntent(intent, annotationMode = _shared_util_js__WEBPACK_I...
method destroy (line 3981) | destroy() {
method setupMessageHandler (line 4015) | setupMessageHandler() {
method getData (line 4289) | getData() {
method saveDocument (line 4292) | saveDocument() {
method getPage (line 4309) | getPage(pageNumber) {
method getPageIndex (line 4334) | getPageIndex(ref) {
method getAnnotations (line 4343) | getAnnotations(pageIndex, intent) {
method getFieldObjects (line 4349) | getFieldObjects() {
method hasJSActions (line 4352) | hasJSActions() {
method getCalculationOrderIds (line 4355) | getCalculationOrderIds() {
method getDestinations (line 4358) | getDestinations() {
method getDestination (line 4361) | getDestination(id) {
method getPageLabels (line 4369) | getPageLabels() {
method getPageLayout (line 4372) | getPageLayout() {
method getPageMode (line 4375) | getPageMode() {
method getViewerPreferences (line 4378) | getViewerPreferences() {
method getOpenAction (line 4381) | getOpenAction() {
method getAttachments (line 4384) | getAttachments() {
method getDocJSActions (line 4387) | getDocJSActions() {
method getPageJSActions (line 4390) | getPageJSActions(pageIndex) {
method getStructTree (line 4395) | getStructTree(pageIndex) {
method getOutline (line 4400) | getOutline() {
method getOptionalContentConfig (line 4403) | getOptionalContentConfig(renderingIntent) {
method getPermissions (line 4406) | getPermissions() {
method getMetadata (line 4409) | getMetadata() {
method getMarkInfo (line 4424) | getMarkInfo() {
method startCleanup (line 4427) | async startCleanup(keepLoadedFonts = false) {
method cachedPageNumber (line 4446) | cachedPageNumber(ref) {
method loadingParams (line 4453) | get loadingParams() {
class PDFObjects (line 4465) | class PDFObjects {
method #ensureObj (line 4467) | #ensureObj(objId) {
method get (line 4473) | get(objId, callback = null) {
method has (line 4485) | has(objId) {
method resolve (line 4489) | resolve(objId, data = null) {
method clear (line 4494) | clear() {
method [Symbol.iterator] (line 4503) | *[Symbol.iterator]() {
class RenderTask (line 4515) | class RenderTask {
method constructor (line 4517) | constructor(internalRenderTask) {
method promise (line 4521) | get promise() {
method cancel (line 4524) | cancel(extraDelay = 0) {
method separateAnnots (line 4527) | get separateAnnots() {
class InternalRenderTask (line 4540) | class InternalRenderTask {
method constructor (line 4542) | constructor({
method completed (line 4581) | get completed() {
method initializeGraphics (line 4584) | initializeGraphics({
method cancel (line 4621) | cancel(error = null, extraDelay = 0) {
method operatorListChanged (line 4628) | operatorListChanged() {
method _continue (line 4639) | _continue() {
method _scheduleNext (line 4650) | _scheduleNext() {
method _next (line 4659) | async _next() {
class BaseFilterFactory (line 4694) | class BaseFilterFactory {
method constructor (line 4695) | constructor() {
method addFilter (line 4700) | addFilter(maps) {
method addHCMFilter (line 4703) | addHCMFilter(fgColor, bgColor) {
method addHighlightHCMFilter (line 4706) | addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgC...
method destroy (line 4709) | destroy(keepHCM = false) {}
class BaseCanvasFactory (line 4711) | class BaseCanvasFactory {
method constructor (line 4712) | constructor() {
method create (line 4717) | create(width, height) {
method reset (line 4727) | reset(canvasAndContext, width, height) {
method destroy (line 4737) | destroy(canvasAndContext) {
method _createCanvas (line 4746) | _createCanvas(width, height) {
class BaseCMapReaderFactory (line 4750) | class BaseCMapReaderFactory {
method constructor (line 4751) | constructor({
method fetch (line 4761) | async fetch({
method _fetchData (line 4776) | _fetchData(url, compressionType) {
class BaseStandardFontDataFactory (line 4780) | class BaseStandardFontDataFactory {
method constructor (line 4781) | constructor({
method fetch (line 4789) | async fetch({
method _fetchData (line 4803) | _fetchData(url) {
class BaseSVGFactory (line 4807) | class BaseSVGFactory {
method constructor (line 4808) | constructor() {
method create (line 4813) | create(width, height, skipDimensions = false) {
method createElement (line 4827) | createElement(type) {
method _createSVG (line 4833) | _createSVG(type) {
function applyBoundingBox (line 4862) | function applyBoundingBox(ctx, bbox) {
class BaseShadingPattern (line 4872) | class BaseShadingPattern {
method constructor (line 4873) | constructor() {
method getPattern (line 4878) | getPattern() {
class RadialAxialShadingPattern (line 4882) | class RadialAxialShadingPattern extends BaseShadingPattern {
method constructor (line 4883) | constructor(IR) {
method _createGradient (line 4894) | _createGradient(ctx) {
method getPattern (line 4906) | getPattern(ctx, owner, inverse, pathType) {
function drawTriangle (line 4936) | function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {
function drawFigure (line 5038) | function drawFigure(data, figure, context) {
class MeshShadingPattern (line 5064) | class MeshShadingPattern extends BaseShadingPattern {
method constructor (line 5065) | constructor(IR) {
method _createMeshCanvas (line 5075) | _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) {
method getPattern (line 5122) | getPattern(ctx, owner, inverse, pathType) {
class DummyShadingPattern (line 5146) | class DummyShadingPattern extends BaseShadingPattern {
method getPattern (line 5147) | getPattern() {
function getShadingPattern (line 5151) | function getShadingPattern(IR) {
class TilingPattern (line 5166) | class TilingPattern {
method constructor (line 5168) | constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) {
method createPatternCanvas (line 5181) | createPatternCanvas(owner) {
method getSizeAndScale (line 5232) | getSizeAndScale(step, realOutputSize, scale) {
method clipBbox (line 5246) | clipBbox(graphics, x0, y0, x1, y1) {
method setFillAndStrokeStyleToContext (line 5254) | setFillAndStrokeStyleToContext(graphics, paintType, color) {
method getPattern (line 5276) | getPattern(ctx, owner, inverse, pathType) {
function convertToRGBA (line 5296) | function convertToRGBA(params) {
function convertBlackAndWhiteToRGBA (line 5305) | function convertBlackAndWhiteToRGBA({
function convertRGBToRGBA (line 5346) | function convertRGBToRGBA({
function grayToRGBA (line 5389) | function grayToRGBA(src, dest) {
function mirrorContextOperations (line 5413) | function mirrorContextOperations(ctx, destCtx) {
class CachedCanvases (line 5511) | class CachedCanvases {
method constructor (line 5512) | constructor(canvasFactory) {
method getCanvas (line 5516) | getCanvas(id, width, height) {
method delete (line 5527) | delete(id) {
method clear (line 5530) | clear() {
function drawImageAtIntegerCoords (line 5538) | function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, d...
function compileType3Glyph (line 5573) | function compileType3Glyph(imgData) {
class CanvasExtraState (line 5703) | class CanvasExtraState {
method constructor (line 5704) | constructor(width, height) {
method clone (line 5731) | clone() {
method setCurrentPoint (line 5736) | setCurrentPoint(x, y) {
method updatePathMinMax (line 5740) | updatePathMinMax(transform, x, y) {
method updateRectMinMax (line 5747) | updateRectMinMax(transform, rect) {
method updateScalingPathMinMax (line 5757) | updateScalingPathMinMax(transform, minMax) {
method updateCurvePathMinMax (line 5764) | updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMa...
method getPathBoundingBox (line 5771) | getPathBoundingBox(pathType = PathType.FILL, transform = null) {
method updateClipFromPath (line 5787) | updateClipFromPath() {
method isEmptyClip (line 5791) | isEmptyClip() {
method startNewPathAndClipBox (line 5794) | startNewPathAndClipBox(box) {
method getClippedPathBoundingBox (line 5801) | getClippedPathBoundingBox(pathType = PathType.FILL, transform = null) {
function putBinaryImageData (line 5805) | function putBinaryImageData(ctx, imgData) {
function putBinaryImageMask (line 5898) | function putBinaryImageMask(ctx, imgData) {
function copyCtxState (line 5927) | function copyCtxState(sourceCtx, destCtx) {
function resetCtxToDefault (line 5939) | function resetCtxToDefault(ctx) {
function composeSMaskBackdrop (line 5962) | function composeSMaskBackdrop(bytes, r0, g0, b0) {
function composeSMaskAlpha (line 5978) | function composeSMaskAlpha(maskData, layerData, transferMap) {
function composeSMaskLuminosity (line 5986) | function composeSMaskLuminosity(maskData, layerData, transferMap) {
function genericComposeSMask (line 5993) | function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, ...
function composeSMask (line 6012) | function composeSMask(ctx, smask, layerCtx, layerBox) {
function getImageSmoothingEnabled (line 6028) | function getImageSmoothingEnabled(transform, interpolate) {
class CanvasGraphics (line 6042) | class CanvasGraphics {
method constructor (line 6043) | constructor(canvasCtx, commonObjs, objs, canvasFactory, filterFactory, {
method getObject (line 6081) | getObject(data, fallback = null) {
method beginDrawing (line 6087) | beginDrawing({
method executeOperatorList (line 6118) | executeOperatorList(operatorList, executionStartIdx, continueCallback,...
method #restoreInitialState (line 6162) | #restoreInitialState() {
method endDrawing (line 6176) | endDrawing() {
method #drawFilter (line 6191) | #drawFilter() {
method _scaleImage (line 6202) | _scaleImage(img, inverseTransform) {
method _createMaskCanvas (line 6237) | _createMaskCanvas(img) {
method setLineWidth (line 6305) | setLineWidth(width) {
method setLineCap (line 6312) | setLineCap(style) {
method setLineJoin (line 6315) | setLineJoin(style) {
method setMiterLimit (line 6318) | setMiterLimit(limit) {
method setDash (line 6321) | setDash(dashArray, dashPhase) {
method setRenderingIntent (line 6328) | setRenderingIntent(intent) {}
method setFlatness (line 6329) | setFlatness(flatness) {}
method setGState (line 6330) | setGState(states) {
method inSMaskMode (line 6378) | get inSMaskMode() {
method checkSMaskState (line 6381) | checkSMaskState() {
method beginSMaskMode (line 6389) | beginSMaskMode() {
method endSMaskMode (line 6405) | endSMaskMode() {
method compose (line 6414) | compose(dirtyBox) {
method save (line 6434) | save() {
method restore (line 6445) | restore() {
method transform (line 6463) | transform(a, b, c, d, e, f) {
method constructPath (line 6468) | constructPath(ops, args, minMax) {
method closePath (line 6552) | closePath() {
method stroke (line 6555) | stroke(consumePath = true) {
method closeStroke (line 6574) | closeStroke() {
method fill (line 6578) | fill(consumePath = true) {
method eoFill (line 6604) | eoFill() {
method fillStroke (line 6608) | fillStroke() {
method eoFillStroke (line 6613) | eoFillStroke() {
method closeFillStroke (line 6617) | closeFillStroke() {
method closeEOFillStroke (line 6621) | closeEOFillStroke() {
method endPath (line 6626) | endPath() {
method clip (line 6629) | clip() {
method eoClip (line 6632) | eoClip() {
method beginText (line 6635) | beginText() {
method endText (line 6641) | endText() {
method setCharSpacing (line 6660) | setCharSpacing(spacing) {
method setWordSpacing (line 6663) | setWordSpacing(spacing) {
method setHScale (line 6666) | setHScale(scale) {
method setLeading (line 6669) | setLeading(leading) {
method setFont (line 6672) | setFont(fontRefName, size) {
method setTextRenderingMode (line 6711) | setTextRenderingMode(mode) {
method setTextRise (line 6714) | setTextRise(rise) {
method moveText (line 6717) | moveText(x, y) {
method setLeadingMoveText (line 6721) | setLeadingMoveText(x, y) {
method setTextMatrix (line 6725) | setTextMatrix(a, b, c, d, e, f) {
method nextLine (line 6731) | nextLine() {
method paintChar (line 6734) | paintChar(character, x, y, patternTransform) {
method isFontSubpixelAAEnabled (line 6781) | get isFontSubpixelAAEnabled() {
method showText (line 6797) | showText(glyphs) {
method showType3Text (line 6927) | showType3Text(glyphs) {
method setCharWidth (line 6980) | setCharWidth(xWidth, yWidth) {}
method setCharWidthAndBounds (line 6981) | setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) {
method getColorN_Pattern (line 6986) | getColorN_Pattern(IR) {
method setStrokeColorN (line 7003) | setStrokeColorN() {
method setFillColorN (line 7006) | setFillColorN() {
method setStrokeRGBColor (line 7010) | setStrokeRGBColor(r, g, b) {
method setFillRGBColor (line 7015) | setFillRGBColor(r, g, b) {
method _getPattern (line 7021) | _getPattern(objId, matrix = null) {
method shadingFill (line 7034) | shadingFill(objId) {
method beginInlineImage (line 7056) | beginInlineImage() {
method beginImageData (line 7059) | beginImageData() {
method paintFormXObjectBegin (line 7062) | paintFormXObjectBegin(matrix, bbox) {
method paintFormXObjectEnd (line 7081) | paintFormXObjectEnd() {
method beginGroup (line 7088) | beginGroup(group) {
method endGroup (line 7163) | endGroup(group) {
method beginAnnotation (line 7187) | beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) {
method endAnnotation (line 7234) | endAnnotation() {
method paintImageMaskXObject (line 7243) | paintImageMaskXObject(img) {
method paintImageMaskXObjectRepeat (line 7269) | paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY,...
method paintImageMaskXObjectGroup (line 7288) | paintImageMaskXObjectGroup(images) {
method paintImageXObject (line 7319) | paintImageXObject(objId) {
method paintImageXObjectRepeat (line 7330) | paintImageXObjectRepeat(objId, scaleX, scaleY, positions) {
method applyTransferMapsToCanvas (line 7353) | applyTransferMapsToCanvas(ctx) {
method applyTransferMapsToBitmap (line 7361) | applyTransferMapsToBitmap(imgData) {
method paintInlineImageXObject (line 7377) | paintInlineImageXObject(imgData) {
method paintInlineImageXObjectGroup (line 7411) | paintInlineImageXObjectGroup(imgData, map) {
method paintSolidColorImageMask (line 7436) | paintSolidColorImageMask() {
method markPoint (line 7443) | markPoint(tag) {}
method markPointProps (line 7444) | markPointProps(tag, properties) {}
method beginMarkedContent (line 7445) | beginMarkedContent(tag) {
method beginMarkedContentProps (line 7450) | beginMarkedContentProps(tag, properties) {
method endMarkedContent (line 7462) | endMarkedContent() {
method beginCompat (line 7466) | beginCompat() {}
method endCompat (line 7467) | endCompat() {}
method consumePath (line 7468) | consumePath(clipBox) {
method getSinglePixelWidth (line 7490) | getSinglePixelWidth() {
method getScaleForStroking (line 7504) | getScaleForStroking() {
method rescaleAndStroke (line 7553) | rescaleAndStroke(saveRestore) {
method isContentVisible (line 7581) | isContentVisible() {
class PixelsPerInch (line 7633) | class PixelsPerInch {
class DOMFilterFactory (line 7638) | class DOMFilterFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE...
method constructor (line 7645) | constructor({
method #cache (line 7653) | get #cache() {
method #hcmCache (line 7656) | get #hcmCache() {
method #defs (line 7659) | get #defs() {
method addFilter (line 7681) | addFilter(maps) {
method addHCMFilter (line 7725) | addHCMFilter(fgColor, bgColor) {
method addHighlightHCMFilter (line 7779) | addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgC...
method destroy (line 7835) | destroy(keepHCM = false) {
method #addGrayConversion (line 7849) | #addGrayConversion(filter) {
method #createFilter (line 7855) | #createFilter(id) {
method #appendFeFunc (line 7862) | #appendFeFunc(feComponentTransfer, func, table) {
method #addTransferMapConversion (line 7868) | #addTransferMapConversion(rTable, gTable, bTable, filter) {
method #getRGB (line 7875) | #getRGB(color) {
class DOMCanvasFactory (line 7880) | class DOMCanvasFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE...
method constructor (line 7881) | constructor({
method _createCanvas (line 7887) | _createCanvas(width, height) {
function fetchData (line 7894) | async function fetchData(url, type = "text") {
class DOMCMapReaderFactory (line 7934) | class DOMCMapReaderFactory extends _base_factory_js__WEBPACK_IMPORTED_MO...
method _fetchData (line 7935) | _fetchData(url, compressionType) {
class DOMStandardFontDataFactory (line 7942) | class DOMStandardFontDataFactory extends _base_factory_js__WEBPACK_IMPOR...
method _fetchData (line 7943) | _fetchData(url) {
class DOMSVGFactory (line 7947) | class DOMSVGFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0_...
method _createSVG (line 7948) | _createSVG(type) {
class PageViewport (line 7952) | class PageViewport {
method constructor (line 7953) | constructor({
method rawDims (line 8022) | get rawDims() {
method clone (line 8033) | clone({
method convertToViewportPoint (line 8049) | convertToViewportPoint(x, y) {
method convertToViewportRectangle (line 8052) | convertToViewportRectangle(rect) {
method convertToPdfPoint (line 8057) | convertToPdfPoint(x, y) {
class RenderingCancelledException (line 8061) | class RenderingCancelledException extends _shared_util_js__WEBPACK_IMPOR...
method constructor (line 8062) | constructor(msg, extraDelay = 0) {
function isDataScheme (line 8067) | function isDataScheme(url) {
function isPdfFile (line 8075) | function isPdfFile(filename) {
function getFilenameFromUrl (line 8078) | function getFilenameFromUrl(url, onlyStripPath = false) {
function getPdfFilenameFromUrl (line 8084) | function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
class StatTimer (line 8106) | class StatTimer {
method time (line 8109) | time(name) {
method timeEnd (line 8115) | timeEnd(name) {
method toString (line 8126) | toString() {
function isValidFetchUrl (line 8144) | function isValidFetchUrl(url, baseUrl) {
function noContextMenu (line 8154) | function noContextMenu(e) {
function deprecated (line 8157) | function deprecated(details) {
class PDFDateString (line 8161) | class PDFDateString {
method toDateObject (line 8162) | static toDateObject(input) {
function getXfaPageViewport (line 8197) | function getXfaPageViewport(xfaPage, {
function getRGB (line 8212) | function getRGB(color) {
function getColorValues (line 8226) | function getColorValues(colors) {
function getCurrentTransform (line 8237) | function getCurrentTransform(ctx) {
function getCurrentTransformInverse (line 8248) | function getCurrentTransformInverse(ctx) {
function setLayerDimensions (line 8259) | function setLayerDimensions(div, viewport, mustFlip = false, mustRotate ...
class DrawLayer (line 8299) | class DrawLayer {
method constructor (line 8304) | constructor({
method setParent (line 8309) | setParent(parent) {
method _svgFactory (line 8324) | static get _svgFactory() {
method #setBox (line 8327) | static #setBox(element, {
method #createSVG (line 8341) | #createSVG(box) {
method #createClipPath (line 8348) | #createClipPath(defs, pathId) {
method highlight (line 8360) | highlight(outlines, color, opacity, isPathUpdatable = false) {
method highlightOutline (line 8389) | highlightOutline(outlines) {
method finalizeLine (line 8435) | finalizeLine(id, line) {
method updateLine (line 8441) | updateLine(id, line) {
method removeFreeHighlight (line 8447) | removeFreeHighlight(id) {
method updatePath (line 8451) | updatePath(id, line) {
method updateBox (line 8454) | updateBox(id, box) {
method show (line 8457) | show(id, visible) {
method rotate (line 8460) | rotate(id, angle) {
method changeColor (line 8463) | changeColor(id, color) {
method changeOpacity (line 8466) | changeOpacity(id, opacity) {
method addClass (line 8469) | addClass(id, className) {
method removeClass (line 8472) | removeClass(id, className) {
method remove (line 8475) | remove(id) {
method destroy (line 8482) | destroy() {
class FreeTextEditor (line 8517) | class FreeTextEditor extends editor_editor.AnnotationEditor {
method _keyboardManager (line 8532) | static get _keyboardManager() {
method constructor (line 8567) | constructor(params) {
method initialize (line 8575) | static initialize(l10n, uiManager) {
method updateDefaultParams (line 8582) | static updateDefaultParams(type, value) {
method updateParams (line 8592) | updateParams(type, value) {
method defaultPropertiesToUpdate (line 8602) | static get defaultPropertiesToUpdate() {
method propertiesToUpdate (line 8605) | get propertiesToUpdate() {
method #updateFontSize (line 8608) | #updateFontSize(fontSize) {
method #updateColor (line 8626) | #updateColor(color) {
method _translateEmpty (line 8641) | _translateEmpty(x, y) {
method getInitialTranslation (line 8644) | getInitialTranslation() {
method rebuild (line 8648) | rebuild() {
method enableEditMode (line 8660) | enableEditMode() {
method disableEditMode (line 8677) | disableEditMode() {
method focusin (line 8698) | focusin(event) {
method onceAdded (line 8707) | onceAdded() {
method isEmpty (line 8718) | isEmpty() {
method remove (line 8721) | remove() {
method #extractText (line 8729) | #extractText() {
method #setEditorDimensions (line 8737) | #setEditorDimensions() {
method commit (line 8766) | commit() {
method shouldGetKeyboardEvents (line 8798) | shouldGetKeyboardEvents() {
method enterInEditMode (line 8801) | enterInEditMode() {
method dblclick (line 8805) | dblclick(event) {
method keydown (line 8808) | keydown(event) {
method editorDivKeydown (line 8814) | editorDivKeydown(event) {
method editorDivFocus (line 8817) | editorDivFocus(event) {
method editorDivBlur (line 8820) | editorDivBlur(event) {
method editorDivInput (line 8823) | editorDivInput(event) {
method disableEditing (line 8826) | disableEditing() {
method enableEditing (line 8830) | enableEditing() {
method render (line 8834) | render() {
method #getNodeContent (line 8906) | static #getNodeContent(node) {
method editorDivPaste (line 8909) | editorDivPaste(event) {
method #setContent (line 8985) | #setContent() {
method #serializeContent (line 8996) | #serializeContent() {
method #deserializeContent (line 8999) | static #deserializeContent(content) {
method contentDiv (line 9002) | get contentDiv() {
method deserialize (line 9005) | static deserialize(data, parent, uiManager) {
method serialize (line 9050) | serialize(isForCopying = false) {
method #hasElementChanged (line 9083) | #hasElementChanged(serialized) {
method renderAnnotationElement (line 9092) | renderAnnotationElement(annotation) {
method resetAnnotationElement (line 9114) | resetAnnotationElement(annotation) {
class HighlightEditor (line 9133) | class HighlightEditor extends editor_editor.AnnotationEditor {
method _keyboardManager (line 9162) | static get _keyboardManager() {
method constructor (line 9174) | constructor(params) {
method telemetryInitialData (line 9200) | get telemetryInitialData() {
method telemetryFinalData (line 9209) | get telemetryFinalData() {
method computeTelemetryFinalData (line 9215) | static computeTelemetryFinalData(data) {
method #createOutlines (line 9220) | #createOutlines() {
method #createFreeOutlines (line 9236) | #createFreeOutlines({
method initialize (line 9299) | static initialize(l10n, uiManager) {
method updateDefaultParams (line 9303) | static updateDefaultParams(type, value) {
method translateInPage (line 9313) | translateInPage(x, y) {}
method toolbarPosition (line 9314) | get toolbarPosition() {
method updateParams (line 9317) | updateParams(type, value) {
method defaultPropertiesToUpdate (line 9327) | static get defaultPropertiesToUpdate() {
method propertiesToUpdate (line 9330) | get propertiesToUpdate() {
method #updateColor (line 9333) | #updateColor(color) {
method #updateThickness (line 9354) | #updateThickness(thickness) {
method addEditToolbar (line 9374) | async addEditToolbar() {
method disableEditing (line 9387) | disableEditing() {
method enableEditing (line 9391) | enableEditing() {
method fixAndSetPosition (line 9395) | fixAndSetPosition() {
method getBaseTranslation (line 9398) | getBaseTranslation() {
method getRect (line 9401) | getRect(tx, ty) {
method onceAdded (line 9404) | onceAdded() {
method remove (line 9408) | remove() {
method rebuild (line 9415) | rebuild() {
method setParent (line 9428) | setParent(parent) {
method #changeThickness (line 9442) | #changeThickness(thickness) {
method #cleanDrawLayer (line 9453) | #cleanDrawLayer() {
method #addToDrawLayer (line 9462) | #addToDrawLayer(parent = this.parent) {
method #rotateBbox (line 9475) | static #rotateBbox({
method rotate (line 9511) | rotate(angle) {
method render (line 9527) | render() {
method pointerover (line 9552) | pointerover() {
method pointerleave (line 9555) | pointerleave() {
method #keydown (line 9558) | #keydown(event) {
method _moveCaret (line 9561) | _moveCaret(direction) {
method #setCaret (line 9574) | #setCaret(start) {
method select (line 9585) | select() {
method unselect (line 9593) | unselect() {
method _mustFixPosition (line 9603) | get _mustFixPosition() {
method show (line 9606) | show(visible = this._isVisible) {
method #getRotation (line 9613) | #getRotation() {
method #serializeBoxes (line 9616) | #serializeBoxes() {
method #serializeOutlines (line 9640) | #serializeOutlines(rect) {
method startHighlighting (line 9643) | static startHighlighting(parent, isLTR, {
method #highlightMove (line 9687) | static #highlightMove(parent, event) {
method #endHighlight (line 9692) | static #endHighlight(parent, event) {
method deserialize (line 9707) | static deserialize(data, parent, uiManager) {
method serialize (line 9731) | serialize(isForCopying = false) {
method canCreateNewEmptyEditor (line 9750) | static canCreateNewEmptyEditor() {
class InkEditor (line 9761) | class InkEditor extends editor_editor.AnnotationEditor {
method constructor (line 9782) | constructor(params) {
method initialize (line 9800) | static initialize(l10n, uiManager) {
method updateDefaultParams (line 9803) | static updateDefaultParams(type, value) {
method updateParams (line 9816) | updateParams(type, value) {
method defaultPropertiesToUpdate (line 9829) | static get defaultPropertiesToUpdate() {
method propertiesToUpdate (line 9832) | get propertiesToUpdate() {
method #updateThickness (line 9835) | #updateThickness(thickness) {
method #updateColor (line 9851) | #updateColor(color) {
method #updateOpacity (line 9867) | #updateOpacity(opacity) {
method rebuild (line 9884) | rebuild() {
method remove (line 9902) | remove() {
method setParent (line 9920) | setParent(parent) {
method onScaleChanging (line 9928) | onScaleChanging() {
method enableEditMode (line 9934) | enableEditMode() {
method disableEditMode (line 9942) | disableEditMode() {
method onceAdded (line 9951) | onceAdded() {
method isEmpty (line 9954) | isEmpty() {
method #getInitialBBox (line 9957) | #getInitialBBox() {
method #setStroke (line 9973) | #setStroke() {
method #startDrawing (line 9988) | #startDrawing(x, y) {
method #draw (line 10013) | #draw(x, y) {
method #endPath (line 10033) | #endPath() {
method #stopDrawing (line 10040) | #stopDrawing(x, y) {
method #drawPoints (line 10083) | #drawPoints() {
method #makeBezierCurve (line 10107) | #makeBezierCurve(path2D, x0, y0, x1, y1, x2, y2) {
method #generateBezierPoints (line 10114) | #generateBezierPoints() {
method #redraw (line 10139) | #redraw() {
method commit (line 10156) | commit() {
method focusin (line 10174) | focusin(event) {
method canvasPointerdown (line 10181) | canvasPointerdown(event) {
method canvasPointermove (line 10194) | canvasPointermove(event) {
method canvasPointerup (line 10198) | canvasPointerup(event) {
method canvasPointerleave (line 10202) | canvasPointerleave(event) {
method #endDrawing (line 10205) | #endDrawing(event) {
method #createCanvas (line 10221) | #createCanvas() {
method #createObserver (line 10229) | #createObserver() {
method isResizable (line 10238) | get isResizable() {
method render (line 10241) | render() {
method #setCanvasDims (line 10272) | #setCanvasDims() {
method setDimensions (line 10281) | setDimensions(width, height) {
method #setScaleFactor (line 10302) | #setScaleFactor(width, height) {
method #updateTransform (line 10308) | #updateTransform() {
method #buildPath2D (line 10312) | static #buildPath2D(bezier) {
method #toPDFCoordinates (line 10323) | static #toPDFCoordinates(points, rect, rotation) {
method #fromPDFCoordinates (line 10357) | static #fromPDFCoordinates(points, rect, rotation) {
method #serializePaths (line 10391) | #serializePaths(s, tx, ty, rect) {
method #getBbox (line 10433) | #getBbox() {
method #getPadding (line 10449) | #getPadding() {
method #fitToContent (line 10452) | #fitToContent(firstTime = false) {
method deserialize (line 10482) | static deserialize(data, parent, uiManager) {
method serialize (line 10531) | serialize() {
class StampEditor (line 10556) | class StampEditor extends editor_editor.AnnotationEditor {
method constructor (line 10570) | constructor(params) {
method initialize (line 10578) | static initialize(l10n, uiManager) {
method supportedTypes (line 10581) | static get supportedTypes() {
method supportedTypesStr (line 10585) | static get supportedTypesStr() {
method isHandlingMimeForPasting (line 10588) | static isHandlingMimeForPasting(mime) {
method paste (line 10591) | static paste(item, parent) {
method #getBitmapFetched (line 10596) | #getBitmapFetched(data, fromId = false) {
method #getBitmapDone (line 10611) | #getBitmapDone() {
method #getBitmap (line 10618) | #getBitmap() {
method remove (line 10659) | remove() {
method rebuild (line 10674) | rebuild() {
method onceAdded (line 10692) | onceAdded() {
method isEmpty (line 10696) | isEmpty() {
method isResizable (line 10699) | get isResizable() {
method render (line 10702) | render() {
method #createCanvas (line 10725) | #createCanvas() {
method #setDimensions (line 10762) | #setDimensions(width, height) {
method #scaleBitmap (line 10782) | #scaleBitmap(width, height) {
method #drawBitmap (line 10806) | #drawBitmap(width, height) {
method getImageForAltText (line 10846) | getImageForAltText() {
method #serializeBitmap (line 10849) | #serializeBitmap(toUrl) {
method #createObserver (line 10877) | #createObserver() {
method deserialize (line 10886) | static deserialize(data, parent, uiManager) {
method serialize (line 10912) | serialize(isForCopying = false, context = null) {
class AnnotationEditorLayer (line 10971) | class AnnotationEditorLayer {
method constructor (line 10987) | constructor({
method isEmpty (line 11016) | get isEmpty() {
method isInvisible (line 11019) | get isInvisible() {
method updateToolbar (line 11022) | updateToolbar(mode) {
method updateMode (line 11025) | updateMode(mode = this.#uiManager.getMode()) {
method hasTextLayer (line 11059) | hasTextLayer(textLayer) {
method addInkEditorIfNeeded (line 11062) | addInkEditorIfNeeded(isCommitting) {
method setEditingState (line 11080) | setEditingState(isEditing) {
method addCommands (line 11083) | addCommands(params) {
method togglePointerEvents (line 11086) | togglePointerEvents(enabled = false) {
method toggleAnnotationLayerPointerEvents (line 11089) | toggleAnnotationLayerPointerEvents(enabled = false) {
method enable (line 11092) | enable() {
method disable (line 11124) | disable() {
method getEditableAnnotation (line 11183) | getEditableAnnotation(id) {
method setActiveEditor (line 11186) | setActiveEditor(editor) {
method enableTextSelection (line 11193) | enableTextSelection() {
method disableTextSelection (line 11201) | disableTextSelection() {
method #textLayerPointerDown (line 11209) | #textLayerPointerDown(event) {
method enableClick (line 11229) | enableClick() {
method disableClick (line 11238) | disableClick() {
method attach (line 11247) | attach(editor) {
method detach (line 11256) | detach(editor) {
method remove (line 11263) | remove(editor) {
method changeParent (line 11272) | changeParent(editor) {
method add (line 11289) | add(editor) {
method moveEditorInDOM (line 11306) | moveEditorInDOM(editor) {
method addOrRebuild (line 11331) | addOrRebuild(editor) {
method addUndoableEditor (line 11340) | addUndoableEditor(editor) {
method getNextId (line 11351) | getNextId() {
method #currentEditorType (line 11354) | get #currentEditorType() {
method #createNewEditor (line 11357) | #createNewEditor(params) {
method canCreateNewEmptyEditor (line 11361) | canCreateNewEmptyEditor() {
method pasteEditor (line 11364) | pasteEditor(mode, params) {
method deserialize (line 11385) | deserialize(data) {
method createAndAddNewEditor (line 11388) | createAndAddNewEditor(event, isCentered, data = {}) {
method #getCenterPoint (line 11404) | #getCenterPoint() {
method addNewEditor (line 11423) | addNewEditor() {
method setSelected (line 11426) | setSelected(editor) {
method toggleSelected (line 11429) | toggleSelected(editor) {
method isSelected (line 11432) | isSelected(editor) {
method unselect (line 11435) | unselect(editor) {
method pointerup (line 11438) | pointerup(event) {
method pointerdown (line 11462) | pointerdown(event) {
method findNewParent (line 11483) | findNewParent(editor, x, y) {
method destroy (line 11491) | destroy() {
method #cleanup (line 11510) | #cleanup() {
method render (line 11519) | render({
method update (line 11530) | update({
method pageDimensions (line 11548) | get pageDimensions() {
method scale (line 11555) | get scale() {
class ColorPicker (line 11575) | class ColorPicker {
method _keyboardManager (line 11588) | static get _keyboardManager() {
method constructor (line 11591) | constructor({
method renderButton (line 11607) | renderButton() {
method renderMainDropdown (line 11622) | renderMainDropdown() {
method #getDropdownRoot (line 11628) | #getDropdownRoot() {
method #colorSelect (line 11654) | #colorSelect(color, event) {
method _colorSelectFromKeyboard (line 11662) | _colorSelectFromKeyboard(event) {
method _moveToNext (line 11673) | _moveToNext(event) {
method _moveToPrevious (line 11684) | _moveToPrevious(event) {
method _moveToBeginning (line 11696) | _moveToBeginning(event) {
method _moveToEnd (line 11703) | _moveToEnd(event) {
method #keyDown (line 11710) | #keyDown(event) {
method #openDropdown (line 11713) | #openDropdown(event) {
method #pointerDown (line 11727) | #pointerDown(event) {
method hideDropdown (line 11733) | hideDropdown() {
method #isDropdownVisible (line 11737) | get #isDropdownVisible() {
method _hideDropdownFromKeyboard (line 11740) | _hideDropdownFromKeyboard() {
method updateColor (line 11754) | updateColor(color) {
method destroy (line 11766) | destroy() {
class AltText (line 11795) | class AltText {
method constructor (line 11804) | constructor(editor) {
method initialize (line 11807) | static initialize(l10nPromise) {
method render (line 11810) | async render() {
method finish (line 11835) | finish() {
method isEmpty (line 11844) | isEmpty() {
method data (line 11847) | get data() {
method data (line 11853) | set data({
method toggle (line 11864) | toggle(enabled = false) {
method destroy (line 11874) | destroy() {
method #setState (line 11879) | async #setState() {
class AnnotationEditor (line 11935) | class AnnotationEditor {
method _resizerKeyboardManager (line 11966) | static get _resizerKeyboardManager() {
method constructor (line 11988) | constructor(parameters) {
method editorType (line 12022) | get editorType() {
method _defaultLineColor (line 12025) | static get _defaultLineColor() {
method deleteAnnotationElement (line 12028) | static deleteAnnotationElement(editor) {
method initialize (line 12038) | static initialize(l10n, _uiManager, options) {
method updateDefaultParams (line 12051) | static updateDefaultParams(_type, _value) {}
method defaultPropertiesToUpdate (line 12052) | static get defaultPropertiesToUpdate() {
method isHandlingMimeForPasting (line 12055) | static isHandlingMimeForPasting(mime) {
method paste (line 12058) | static paste(item, parent) {
method propertiesToUpdate (line 12061) | get propertiesToUpdate() {
method _isDraggable (line 12064) | get _isDraggable() {
method _isDraggable (line 12067) | set _isDraggable(value) {
method isEnterHandled (line 12071) | get isEnterHandled() {
method center (line 12074) | center() {
method addCommands (line 12096) | addCommands(params) {
method currentLayer (line 12099) | get currentLayer() {
method setInBackground (line 12102) | setInBackground() {
method setInForeground (line 12105) | setInForeground() {
method setParent (line 12108) | setParent(parent) {
method focusin (line 12117) | focusin(event) {
method focusout (line 12127) | focusout(event) {
method commitOrRemove (line 12143) | commitOrRemove() {
method commit (line 12150) | commit() {
method addToAnnotationStorage (line 12153) | addToAnnotationStorage() {
method setAt (line 12156) | setAt(x, y, tx, ty) {
method #translate (line 12163) | #translate([width, height], x, y) {
method translate (line 12169) | translate(x, y) {
method translateInPage (line 12172) | translateInPage(x, y) {
method drag (line 12179) | drag(tx, ty) {
method _hasBeenMoved (line 12207) | get _hasBeenMoved() {
method getBaseTranslation (line 12210) | getBaseTranslation() {
method _mustFixPosition (line 12228) | get _mustFixPosition() {
method fixAndSetPosition (line 12231) | fixAndSetPosition(rotation = this.rotation) {
method #rotatePoint (line 12275) | static #rotatePoint(x, y, angle) {
method screenToPageTranslation (line 12287) | screenToPageTranslation(x, y) {
method pageTranslationToScreen (line 12290) | pageTranslationToScreen(x, y) {
method #getRotationMatrix (line 12293) | #getRotationMatrix(rotation) {
method parentScale (line 12311) | get parentScale() {
method parentRotation (line 12314) | get parentRotation() {
method parentDimensions (line 12317) | get parentDimensions() {
method setDims (line 12326) | setDims(width, height) {
method fixDims (line 12333) | fixDims() {
method getInitialTranslation (line 12354) | getInitialTranslation() {
method #createResizers (line 12357) | #createResizers() {
method #resizerPointerdown (line 12375) | #resizerPointerdown(name, event) {
method #addResizeToUndoStack (line 12416) | #addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight) {
method #resizerPointermove (line 12446) | #resizerPointermove(name, event) {
method altTextFinish (line 12532) | altTextFinish() {
method addEditToolbar (line 12535) | async addEditToolbar() {
method removeEditToolbar (line 12546) | removeEditToolbar() {
method getClientDimensions (line 12554) | getClientDimensions() {
method addAltTextButton (line 12557) | async addAltTextButton() {
method altTextData (line 12565) | get altTextData() {
method altTextData (line 12568) | set altTextData(data) {
method hasAltText (line 12574) | hasAltText() {
method render (line 12577) | render() {
method pointerdown (line 12599) | pointerdown(event) {
method #selectOnPointerEvent (line 12614) | #selectOnPointerEvent(event) {
method #setUpDragSession (line 12624) | #setUpDragSession(event) {
method moveInDOM (line 12663) | moveInDOM() {
method _setParentAndPosition (line 12672) | _setParentAndPosition(parent, x, y) {
method getRect (line 12678) | getRect(tx, ty, rotation = this.rotation) {
method getRectInCurrentCoords (line 12701) | getRectInCurrentCoords(rect, pageHeight) {
method onceAdded (line 12718) | onceAdded() {}
method isEmpty (line 12719) | isEmpty() {
method enableEditMode (line 12722) | enableEditMode() {
method disableEditMode (line 12725) | disableEditMode() {
method isInEditMode (line 12728) | isInEditMode() {
method shouldGetKeyboardEvents (line 12731) | shouldGetKeyboardEvents() {
method needsToBeRebuilt (line 12734) | needsToBeRebuilt() {
method rebuild (line 12737) | rebuild() {
method rotate (line 12741) | rotate(_angle) {}
method serialize (line 12742) | serialize(isForCopying = false, context = null) {
method deserialize (line 12745) | static deserialize(data, parent, uiManager) {
method hasBeenModified (line 12760) | get hasBeenModified() {
method remove (line 12763) | remove() {
method isResizable (line 12788) | get isResizable() {
method makeResizable (line 12791) | makeResizable() {
method toolbarPosition (line 12798) | get toolbarPosition() {
method keydown (line 12801) | keydown(event) {
method #resizerKeydown (line 12860) | #resizerKeydown(event) {
method #resizerBlur (line 12863) | #resizerBlur(event) {
method #resizerFocus (line 12868) | #resizerFocus(name) {
method #setResizerTabIndex (line 12871) | #setResizerTabIndex(value) {
method _resizeWithKeyboard (line 12879) | _resizeWithKeyboard(x, y) {
method #stopResizing (line 12888) | #stopResizing() {
method _stopResizingWithKeyboard (line 12902) | _stopResizingWithKeyboard() {
method select (line 12906) | select() {
method unselect (line 12919) | unselect() {
method updateParams (line 12929) | updateParams(type, value) {}
method disableEditing (line 12930) | disableEditing() {}
method enableEditing (line 12931) | enableEditing() {}
method enterInEditMode (line 12932) | enterInEditMode() {}
method getImageForAltText (line 12933) | getImageForAltText() {
method contentDiv (line 12936) | get contentDiv() {
method isEditing (line 12939) | get isEditing() {
method isEditing (line 12942) | set isEditing(value) {
method setAspectRatio (line 12954) | setAspectRatio(width, height) {
method MIN_SIZE (line 12963) | static get MIN_SIZE() {
method canCreateNewEmptyEditor (line 12966) | static canCreateNewEmptyEditor() {
method telemetryInitialData (line 12969) | get telemetryInitialData() {
method telemetryFinalData (line 12974) | get telemetryFinalData() {
method _reportTelemetry (line 12977) | _reportTelemetry(data, mustWait = false) {
method show (line 13006) | show(visible = this._isVisible) {
method enable (line 13010) | enable() {
method disable (line 13016) | disable() {
method renderAnnotationElement (line 13022) | renderAnnotationElement(annotation) {
method resetAnnotationElement (line 13036) | resetAnnotationElement(annotation) {
class FakeEditor (line 13045) | class FakeEditor extends AnnotationEditor {
method constructor (line 13046) | constructor(params) {
method serialize (line 13051) | serialize() {
class Outliner (line 13072) | class Outliner {
method constructor (line 13076) | constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) {
method getOutlines (line 13121) | getOutlines() {
method #getOutlines (line 13135) | #getOutlines(outlineVerticalEdges) {
method #binarySearch (line 13182) | #binarySearch(y) {
method #insert (line 13200) | #insert([, y1, y2]) {
method #remove (line 13204) | #remove([, y1, y2]) {
method #breakEdge (line 13227) | #breakEdge(edge) {
class Outline (line 13260) | class Outline {
method toSVGPath (line 13261) | toSVGPath() {
method box (line 13264) | get box() {
method serialize (line 13267) | serialize(_bbox, _rotation) {
method free (line 13270) | get free() {
class HighlightOutline (line 13274) | class HighlightOutline extends Outline {
method constructor (line 13277) | constructor(outlines, box) {
method toSVGPath (line 13282) | toSVGPath() {
method serialize (line 13302) | serialize([blX, blY, trX, trY], _rotation) {
method box (line 13316) | get box() {
class FreeOutliner (line 13320) | class FreeOutliner {
method constructor (line 13337) | constructor({
method free (line 13351) | get free() {
method isEmpty (line 13354) | isEmpty() {
method #getLastCoords (line 13357) | #getLastCoords() {
method add (line 13363) | add({
method toSVGPath (line 13421) | toSVGPath() {
method getOutlines (line 13454) | getOutlines() {
class FreeHighlightOutline (line 13502) | class FreeHighlightOutline extends Outline {
method constructor (line 13510) | constructor(outline, points, box, scaleFactor, innerMargin, isLTR) {
method toSVGPath (line 13534) | toSVGPath() {
method serialize (line 13546) | serialize([blX, blY, trX, trY], rotation) {
method #rescale (line 13574) | #rescale(src, tx, ty, sx, sy) {
method #rescaleAndSwap (line 13582) | #rescaleAndSwap(src, tx, ty, sx, sy) {
method #computeMinMax (line 13590) | #computeMinMax(isLTR) {
method box (line 13641) | get box() {
method getNewOutline (line 13644) | getNewOutline(thickness, innerMargin) {
class EditorToolbar (line 13682) | class EditorToolbar {
method constructor (line 13687) | constructor(editor) {
method render (line 13690) | render() {
method #pointerDown (line 13711) | static #pointerDown(e) {
method #focusIn (line 13714) | #focusIn(e) {
method #focusOut (line 13719) | #focusOut(e) {
method #addListenersToElement (line 13724) | #addListenersToElement(element) {
method hide (line 13733) | hide() {
method show (line 13737) | show() {
method #addDeleteButton (line 13740) | #addDeleteButton() {
method #divider (line 13751) | get #divider() {
method addAltTextButton (line 13756) | addAltTextButton(button) {
method addColorPicker (line 13760) | addColorPicker(colorPicker) {
method remove (line 13766) | remove() {
class HighlightToolbar (line 13772) | class HighlightToolbar {
method constructor (line 13776) | constructor(uiManager) {
method #render (line 13779) | #render() {
method #getLastPoint (line 13790) | #getLastPoint(boxes, isLTR) {
method show (line 13814) | show(parent, boxes, isLTR) {
method hide (line 13823) | hide() {
method #addHighlightButton (line 13826) | #addHighlightButton() {
function bindEvents (line 13863) | function bindEvents(obj, element, names) {
function opacityToHex (line 13868) | function opacityToHex(opacity) {
class IdManager (line 13871) | class IdManager {
method constructor (line 13873) | constructor() {}
method id (line 13874) | get id() {
class ImageManager (line 13878) | class ImageManager {
method _isSVGFittingCanvas (line 13882) | static get _isSVGFittingCanvas() {
method #get (line 13894) | async #get(key, rawData) {
method getFromFile (line 13950) | async getFromFile(file) {
method getFromUrl (line 13959) | async getFromUrl(url) {
method getFromId (line 13962) | async getFromId(id) {
method getSvgUrl (line 13977) | getSvgUrl(id) {
method deleteId (line 13984) | deleteId(id) {
method isValidId (line 13996) | isValidId(id) {
class CommandManager (line 14000) | class CommandManager {
method constructor (line 14005) | constructor(maxSize = 128) {
method add (line 14008) | add({
method undo (line 14055) | undo() {
method redo (line 14069) | redo() {
method hasSomethingToUndo (line 14082) | hasSomethingToUndo() {
method hasSomethingToRedo (line 14085) | hasSomethingToRedo() {
method destroy (line 14088) | destroy() {
class KeyboardManager (line 14092) | class KeyboardManager {
method constructor (line 14093) | constructor(callbacks) {
method #serialize (line 14119) | #serialize(event) {
method exec (line 14137) | exec(self, event) {
class ColorManager (line 14163) | class ColorManager {
method _colors (line 14165) | get _colors() {
method convert (line 14170) | convert(color) {
method getHexCode (line 14182) | getHexCode(name) {
class AnnotationEditorUIManager (line 14190) | class AnnotationEditorUIManager {
method _keyboardManager (line 14246) | static get _keyboardManager() {
method constructor (line 14304) | constructor(container, viewer, altTextManager, eventBus, pdfDocument, ...
method destroy (line 14327) | destroy() {
method mlGuess (line 14356) | async mlGuess(data) {
method hasMLManager (line 14359) | get hasMLManager() {
method hcmFilter (line 14362) | get hcmFilter() {
method direction (line 14365) | get direction() {
method highlightColors (line 14368) | get highlightColors() {
method highlightColorNames (line 14371) | get highlightColorNames() {
method setMainHighlightColorPicker (line 14374) | setMainHighlightColorPicker(colorPicker) {
method editAltText (line 14377) | editAltText(editor) {
method onPageChanging (line 14380) | onPageChanging({
method focusMainContainer (line 14385) | focusMainContainer() {
method findParent (line 14388) | findParent(x, y) {
method disableUserSelect (line 14402) | disableUserSelect(value = false) {
method addShouldRescale (line 14405) | addShouldRescale(editor) {
method removeShouldRescale (line 14408) | removeShouldRescale(editor) {
method onScaleChanging (line 14411) | onScaleChanging({
method onRotationChanging (line 14420) | onRotationChanging({
method #getAnchorElementForSelection (line 14426) | #getAnchorElementForSelection({
method highlightSelection (line 14431) | highlightSelection(methodOfCreation = "") {
method #displayHighlightToolbar (line 14475) | #displayHighlightToolbar() {
method addToAnnotationStorage (line 14489) | addToAnnotationStorage(editor) {
method #selectionChange (line 14494) | #selectionChange() {
method #onSelectEnd (line 14551) | #onSelectEnd(methodOfCreation = "") {
method #addSelectionListener (line 14558) | #addSelectionListener() {
method #removeSelectionListener (line 14561) | #removeSelectionListener() {
method #addFocusManager (line 14564) | #addFocusManager() {
method #removeFocusManager (line 14568) | #removeFocusManager() {
method blur (line 14572) | blur() {
method focus (line 14592) | focus() {
method #addKeyboardManager (line 14605) | #addKeyboardManager() {
method #removeKeyboardManager (line 14609) | #removeKeyboardManager() {
method #addCopyPasteListeners (line 14613) | #addCopyPasteListeners() {
method #removeCopyPasteListeners (line 14618) | #removeCopyPasteListeners() {
method addEditListeners (line 14623) | addEditListeners() {
method removeEditListeners (line 14627) | removeEditListeners() {
method copy (line 14631) | copy(event) {
method cut (line 14649) | cut(event) {
method paste (line 14653) | paste(event) {
method keydown (line 14710) | keydown(event) {
method keyup (line 14718) | keyup(event) {
method onEditingAction (line 14727) | onEditingAction({
method #dispatchUpdateStates (line 14742) | #dispatchUpdateStates(details) {
method #dispatchUpdateUI (line 14754) | #dispatchUpdateUI(details) {
method setEditingState (line 14760) | setEditingState(isEditing) {
method registerEditorTypes (line 14780) | registerEditorTypes(types) {
method getId (line 14789) | getId() {
method currentLayer (line 14792) | get currentLayer() {
method getLayer (line 14795) | getLayer(pageIndex) {
method currentPageIndex (line 14798) | get currentPageIndex() {
method addLayer (line 14801) | addLayer(layer) {
method removeLayer (line 14809) | removeLayer(layer) {
method updateMode (line 14812) | updateMode(mode, editId = null, isFromKeyboard = false) {
method addNewEditorFromKeyboard (line 14843) | addNewEditorFromKeyboard() {
method updateToolbar (line 14848) | updateToolbar(mode) {
method updateParams (line 14857) | updateParams(type, value) {
method showAllEditors (line 14890) | showAllEditors(type, visible, updateButton = false) {
method enableWaiting (line 14901) | enableWaiting(mustWait = false) {
method #enableAll (line 14915) | #enableAll() {
method #disableAll (line 14926) | #disableAll() {
method getEditors (line 14938) | getEditors(pageIndex) {
method getEditor (line 14947) | getEditor(id) {
method addEditor (line 14950) | addEditor(editor) {
method removeEditor (line 14953) | removeEditor(editor) {
method addDeletedAnnotationElement (line 14969) | addDeletedAnnotationElement(editor) {
method isDeletedAnnotationElement (line 14974) | isDeletedAnnotationElement(annotationElementId) {
method removeDeletedAnnotationElement (line 14977) | removeDeletedAnnotationElement(editor) {
method #addEditorToLayer (line 14982) | #addEditorToLayer(editor) {
method setActiveEditor (line 14991) | setActiveEditor(editor) {
method #lastSelectedEditor (line 15000) | get #lastSelectedEditor() {
method updateUI (line 15005) | updateUI(editor) {
method toggleSelected (line 15010) | toggleSelected(editor) {
method setSelected (line 15026) | setSelected(editor) {
method isSelected (line 15040) | isSelected(editor) {
method firstSelectedEditor (line 15043) | get firstSelectedEditor() {
method unselect (line 15046) | unselect(editor) {
method hasSelection (line 15053) | get hasSelection() {
method isEnterHandled (line 15056) | get isEnterHandled() {
method undo (line 15059) | undo() {
method redo (line 15067) | redo() {
method addCommands (line 15075) | addCommands(params) {
method #isEmpty (line 15083) | #isEmpty() {
method delete (line 15094) | delete() {
method commitOrRemove (line 15116) | commitOrRemove() {
method hasSomethingToControl (line 15119) | hasSomethingToControl() {
method #selectEditors (line 15122) | #selectEditors(editors) {
method selectAll (line 15138) | selectAll() {
method unselectAll (line 15144) | unselectAll() {
method translateSelectedEditors (line 15162) | translateSelectedEditors(x, y, noCommit = false) {
method setUpDragSession (line 15202) | setUpDragSession() {
method endDragSession (line 15219) | endDragSession() {
method dragSelectedEditors (line 15275) | dragSelectedEditors(tx, ty) {
method rebuild (line 15283) | rebuild(editor) {
method isEditorHandlingKeyboard (line 15298) | get isEditorHandlingKeyboard() {
method isActive (line 15301) | isActive(editor) {
method getActive (line 15304) | getActive() {
method getMode (line 15307) | getMode() {
method imageManager (line 15310) | get imageManager() {
method getSelectionBoxes (line 15313) | getSelectionBoxes(textLayer) {
method addChangedExistingAnnotation (line 15384) | addChangedExistingAnnotation({
method removeChangedExistingAnnotation (line 15390) | removeChangedExistingAnnotation({
method renderAnnotationElement (line 15395) | renderAnnotationElement(annotation) {
function createFetchOptions (line 15424) | function createFetchOptions(headers, withCredentials, abortController) {
function createHeaders (line 15434) | function createHeaders(httpHeaders) {
function getArrayBuffer (line 15445) | function getArrayBuffer(val) {
class PDFFetchStream (line 15455) | class PDFFetchStream {
method constructor (line 15456) | constructor(source) {
method _progressiveDataLength (line 15463) | get _progressiveDataLength() {
method getFullReader (line 15466) | getFullReader() {
method getRangeReader (line 15471) | getRangeReader(begin, end) {
method cancelAllRequests (line 15479) | cancelAllRequests(reason) {
class PDFFetchStreamReader (line 15486) | class PDFFetchStreamReader {
method constructor (line 15487) | constructor(stream) {
method headersReady (line 15531) | get headersReady() {
method filename (line 15534) | get filename() {
method contentLength (line 15537) | get contentLength() {
method isRangeSupported (line 15540) | get isRangeSupported() {
method isStreamingSupported (line 15543) | get isStreamingSupported() {
method read (line 15546) | async read() {
method cancel (line 15568) | cancel(reason) {
class PDFFetchStreamRangeReader (line 15573) | class PDFFetchStreamRangeReader {
method constructor (line 15574) | constructor(stream, begin, end) {
method isStreamingSupported (line 15595) | get isStreamingSupported() {
method read (line 15598) | async read() {
method cancel (line 15619) | cancel(reason) {
class FontLoader (line 15637) | class FontLoader {
method constructor (line 15639) | constructor({
method addNativeFontFace (line 15649) | addNativeFontFace(nativeFontFace) {
method removeNativeFontFace (line 15653) | removeNativeFontFace(nativeFontFace) {
method insertRule (line 15657) | insertRule(rule) {
method clear (line 15665) | clear() {
method loadSystemFont (line 15676) | async loadSystemFont({
method bind (line 15704) | async bind(font) {
method isFontLoadingAPISupported (line 15739) | get isFontLoadingAPISupported() {
method isSyncFontLoadingSupported (line 15743) | get isSyncFontLoadingSupported() {
method _queueLoadingCallback (line 15752) | _queueLoadingCallback(callback) {
method _loadTestFont (line 15772) | get _loadTestFont() {
method _prepareFontLoadEvent (line 15776) | _prepareFontLoadEvent(font, request) {
class FontFaceObject (line 15841) | class FontFaceObject {
method constructor (line 15842) | constructor(translatedData, {
method createNativeFontFace (line 15855) | createNativeFontFace() {
method createFontFaceRule (line 15874) | createFontFaceRule() {
method getPathGenerator (line 15893) | getPathGenerator(objs, character) {
class Metadata (line 15987) | class Metadata {
method constructor (line 15990) | constructor({
method getRaw (line 15997) | getRaw() {
method get (line 16000) | get(name) {
method getAll (line 16003) | getAll() {
method has (line 16006) | has(name) {
function getArrayBuffer (line 16026) | function getArrayBuffer(xhr) {
class NetworkManager (line 16033) | class NetworkManager {
method constructor (line 16034) | constructor(url, args = {}) {
method requestRange (line 16042) | requestRange(begin, end, listeners) {
method requestFull (line 16052) | requestFull(listeners) {
method request (line 16055) | request(args) {
method onProgress (line 16091) | onProgress(xhrId, evt) {
method onStateChange (line 16098) | onStateChange(xhrId, evt) {
method getRequestXhr (line 16142) | getRequestXhr(xhrId) {
method isPendingRequest (line 16145) | isPendingRequest(xhrId) {
method abortRequest (line 16148) | abortRequest(xhrId) {
class PDFNetworkStream (line 16154) | class PDFNetworkStream {
method constructor (line 16155) | constructor(source) {
method _onRangeRequestReaderClosed (line 16165) | _onRangeRequestReaderClosed(reader) {
method getFullReader (line 16171) | getFullReader() {
method getRangeReader (line 16176) | getRangeReader(begin, end) {
method cancelAllRequests (line 16182) | cancelAllRequests(reason) {
class PDFNetworkStreamFullRequestReader (line 16189) | class PDFNetworkStreamFullRequestReader {
method constructor (line 16190) | constructor(manager, source) {
method _onHeadersReceived (line 16216) | _onHeadersReceived() {
method _onDone (line 16239) | _onDone(data) {
method _onError (line 16263) | _onError(status) {
method _onProgress (line 16272) | _onProgress(evt) {
method filename (line 16278) | get filename() {
method isRangeSupported (line 16281) | get isRangeSupported() {
method isStreamingSupported (line 16284) | get isStreamingSupported() {
method contentLength (line 16287) | get contentLength() {
method headersReady (line 16290) | get headersReady() {
method read (line 16293) | async read() {
method cancel (line 16314) | cancel(reason) {
class PDFNetworkStreamRangeRequestReader (line 16330) | class PDFNetworkStreamRangeRequestReader {
method constructor (line 16331) | constructor(manager, begin, end) {
method _close (line 16347) | _close() {
method _onDone (line 16350) | _onDone(data) {
method _onError (line 16371) | _onError(status) {
method _onProgress (line 16379) | _onProgress(evt) {
method isStreamingSupported (line 16386) | get isStreamingSupported() {
method read (line 16389) | async read() {
method cancel (line 16411) | cancel(reason) {
function getFilenameFromContentDispositionHeader (line 16446) | function getFilenameFromContentDispositionHeader(contentDisposition) {
function validateRangeRequestCapabilities (line 16581) | function validateRangeRequestCapabilities({
function extractFilenameFromHeader (line 16612) | function extractFilenameFromHeader(getResponseHeader) {
function createResponseStatusError (line 16627) | function createResponseStatusError(status, url) {
function validateResponseStatus (line 16633) | function validateResponseStatus(status) {
function parseUrl (line 16659) | function parseUrl(sourceUrl) {
class PDFNodeStream (line 16672) | class PDFNodeStream {
method constructor (line 16673) | constructor(source) {
method _progressiveDataLength (line 16682) | get _progressiveDataLength() {
method getFullReader (line 16685) | getFullReader() {
method getRangeReader (line 16690) | getRangeReader(start, end) {
method cancelAllRequests (line 16698) | cancelAllRequests(reason) {
class BaseFullReader (line 16705) | class BaseFullReader {
method constructor (line 16706) | constructor(stream) {
method headersReady (line 16726) | get headersReady() {
method filename (line 16729) | get filename() {
method contentLength (line 16732) | get contentLength() {
method isRangeSupported (line 16735) | get isRangeSupported() {
method isStreamingSupported (line 16738) | get isStreamingSupported() {
method read (line 16741) | async read() {
method cancel (line 16768) | cancel(reason) {
method _error (line 16775) | _error(reason) {
method _setReadableStream (line 16779) | _setReadableStream(readableStream) {
class BaseRangeReader (line 16800) | class BaseRangeReader {
method constructor (line 16801) | constructor(stream) {
method isStreamingSupported (line 16812) | get isStreamingSupported() {
method read (line 16815) | async read() {
method cancel (line 16841) | cancel(reason) {
method _error (line 16848) | _error(reason) {
method _setReadableStream (line 16852) | _setReadableStream(readableStream) {
function createRequestOptions (line 16870) | function createRequestOptions(parsedUrl, headers) {
class PDFNodeStreamFullReader (line 16881) | class PDFNodeStreamFullReader extends BaseFullReader {
method constructor (line 16882) | constructor(stream) {
class PDFNodeStreamRangeReader (line 16920) | class PDFNodeStreamRangeReader extends BaseRangeReader {
method constructor (line 16921) | constructor(stream, start, end) {
class PDFNodeStreamFsFullReader (line 16952) | class PDFNodeStreamFsFullReader extends BaseFullReader {
method constructor (line 16953) | constructor(stream) {
class PDFNodeStreamFsRangeReader (line 16972) | class PDFNodeStreamFsRangeReader extends BaseRangeReader {
method constructor (line 16973) | constructor(stream, start, end) {
class NodeFilterFactory (line 17018) | class NodeFilterFactory extends _base_factory_js__WEBPACK_IMPORTED_MODUL...
class NodeCanvasFactory (line 17019) | class NodeCanvasFactory extends _base_factory_js__WEBPACK_IMPORTED_MODUL...
method _createCanvas (line 17020) | _createCanvas(width, height) {
class NodeCMapReaderFactory (line 17024) | class NodeCMapReaderFactory extends _base_factory_js__WEBPACK_IMPORTED_M...
method _fetchData (line 17025) | _fetchData(url, compressionType) {
class NodeStandardFontDataFactory (line 17032) | class NodeStandardFontDataFactory extends _base_factory_js__WEBPACK_IMPO...
method _fetchData (line 17033) | _fetchData(url) {
class OptionalContentGroup (line 17054) | class OptionalContentGroup {
method constructor (line 17059) | constructor(renderingIntent, {
method visible (line 17070) | get visible() {
method _setVisible (line 17088) | _setVisible(internal, visible, userSet = false) {
class OptionalContentConfig (line 17096) | class OptionalContentConfig {
method constructor (line 17101) | constructor(data, renderingIntent = _shared_util_js__WEBPACK_IMPORTED_...
method #evaluateVisibilityExpression (line 17127) | #evaluateVisibilityExpression(array) {
method isVisible (line 17163) | isVisible(group) {
method setVisibility (line 17232) | setVisibility(id, visible = true) {
method setOCGState (line 17241) | setOCGState({
method hasInitialVisibility (line 17272) | get hasInitialVisibility() {
method getOrder (line 17275) | getOrder() {
method getGroups (line 17284) | getGroups() {
method getGroup (line 17287) | getGroup(id) {
method getHash (line 17290) | getHash() {
function getCtx (line 17323) | function getCtx() {
function cleanupTextLayer (line 17334) | function cleanupTextLayer() {
function getAscent (line 17338) | function getAscent(fontFamily) {
function appendText (line 17388) | function appendText(task, geom, styles) {
function layout (line 17454) | function layout(params) {
function render (line 17494) | function render(task) {
class TextLayerRenderTask (line 17512) | class TextLayerRenderTask {
method constructor (line 17513) | constructor({
method promise (line 17553) | get promise() {
method cancel (line 17556) | cancel() {
method _processItems (line 17564) | _processItems(items, styleCache) {
method _layoutText (line 17584) | _layoutText(textDiv) {
method _render (line 17597) | _render() {
function renderTextLayer (line 17637) | function renderTextLayer(params) {
function updateTextLayer (line 17642) | function updateTextLayer({
class PDFDataTransportStream (line 17687) | class PDFDataTransportStream {
method constructor (line 17688) | constructor(pdfDataRangeTransport, {
method _onReceiveData (line 17734) | _onReceiveData({
method _progressiveDataLength (line 17756) | get _progressiveDataLength() {
method _onProgress (line 17759) | _onProgress(evt) {
method _onProgressiveDone (line 17771) | _onProgressiveDone() {
method _removeRangeReader (line 17775) | _removeRangeReader(reader) {
method getFullReader (line 17781) | getFullReader() {
method getRangeReader (line 17787) | getRangeReader(begin, end) {
method cancelAllRequests (line 17796) | cancelAllRequests(reason) {
class PDFDataTransportStreamReader (line 17804) | class PDFDataTransportStreamReader {
method constructor (line 17805) | constructor(stream, queuedChunks, progressiveDone = false, contentDisp...
method _enqueue (line 17819) | _enqueue(chunk) {
method headersReady (line 17834) | get headersReady() {
method filename (line 17837) | get filename() {
method isRangeSupported (line 17840) | get isRangeSupported() {
method isStreamingSupported (line 17843) | get isStreamingSupported() {
method contentLength (line 17846) | get contentLength() {
method read (line 17849) | async read() {
method cancel (line 17867) | cancel(reason) {
method progressiveDone (line 17877) | progressiveDone() {
class PDFDataTransportStreamRangeReader (line 17884) | class PDFDataTransportStreamRangeReader {
method constructor (line 17885) | constructor(stream, begin, end) {
method _enqueue (line 17894) | _enqueue(chunk) {
method isStreamingSupported (line 17917) | get isStreamingSupported() {
method read (line 17920) | async read() {
method cancel (line 17939) | cancel(reason) {
class GlobalWorkerOptions (line 17961) | class GlobalWorkerOptions {
method workerPort (line 17964) | static get workerPort() {
method workerPort (line 17967) | static set workerPort(val) {
method workerSrc (line 17973) | static get workerSrc() {
method workerSrc (line 17976) | static set workerSrc(val) {
class XfaLayer (line 17995) | class XfaLayer {
method setupStorage (line 17996) | static setupStorage(html, id, element, storage, intent) {
method setAttributes (line 18064) | static setAttributes({
method render (line 18112) | static render(parameters) {
method update (line 18197) | static update(parameters) {
class XfaText (line 18213) | class XfaText {
method textContent (line 18214) | static textContent(xfa) {
method shouldBuildText (line 18250) | static shouldBuildText(name) {
function wrapReason (line 18367) | function wrapReason(reason) {
class MessageHandler (line 18386) | class MessageHandler {
method constructor (line 18387) | constructor(sourceName, targetName, comObj) {
method on (line 18458) | on(actionName, handler) {
method send (line 18465) | send(actionName, data, transfers) {
method sendWithPromise (line 18473) | sendWithPromise(actionName, data, transfers) {
method sendWithStream (line 18490) | sendWithStream(actionName, data, queueingStrategy, transfers) {
method #createStreamSink (line 18543) | #createStreamSink(data) {
method #processStreamMessage (line 18626) | #processStreamMessage(data) {
method #deleteStreamController (line 18743) | async #deleteStreamController(streamController, streamId) {
method destroy (line 18747) | destroy() {
class MurmurHash3_64 (line 18764) | class MurmurHash3_64 {
method constructor (line 18765) | constructor(seed) {
method update (line 18769) | update(input) {
method hexdigest (line 18839) | hexdigest() {
function setVerbosityLevel (line 19184) | function setVerbosityLevel(level) {
function getVerbosityLevel (line 19189) | function getVerbosityLevel() {
function info (line 19192) | function info(msg) {
function warn (line 19197) | function warn(msg) {
function unreachable (line 19202) | function unreachable(msg) {
function assert (line 19205) | function assert(cond, msg) {
function _isValidProtocol (line 19210) | function _isValidProtocol(url) {
function createValidAbsoluteUrl (line 19222) | function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
function shadow (line 19247) | function shadow(obj, prop, value, nonSerializable = false) {
function BaseException (line 19257) | function BaseException(message, name) {
class PasswordException (line 19268) | class PasswordException extends BaseException {
method constructor (line 19269) | constructor(msg, code) {
class UnknownErrorException (line 19274) | class UnknownErrorException extends BaseException {
method constructor (line 19275) | constructor(msg, details) {
class InvalidPDFException (line 19280) | class InvalidPDFException extends BaseException {
method constructor (line 19281) | constructor(msg) {
class MissingPDFException (line 19285) | class MissingPDFException extends BaseException {
method constructor (line 19286) | constructor(msg) {
class UnexpectedResponseException (line 19290) | class UnexpectedResponseException extends BaseException {
method constructor (line 19291) | constructor(msg, status) {
class FormatError (line 19296) | class FormatError extends BaseException {
method constructor (line 19297) | constructor(msg) {
class AbortException (line 19301) | class AbortException extends BaseException {
method constructor (line 19302) | constructor(msg) {
function bytesToString (line 19306) | function bytesToString(bytes) {
function stringToBytes (line 19323) | function stringToBytes(str) {
function string32 (line 19334) | function string32(value) {
function objectSize (line 19337) | function objectSize(obj) {
function objectFromMap (line 19340) | function objectFromMap(map) {
function isLittleEndian (line 19347) | function isLittleEndian() {
function isEvalSupported (line 19353) | function isEvalSupported() {
class FeatureTest (line 19361) | class FeatureTest {
method isLittleEndian (line 19362) | static get isLittleEndian() {
method isEvalSupported (line 19365) | static get isEvalSupported() {
method isOffscreenCanvasSupported (line 19368) | static get isOffscreenCanvasSupported() {
method platform (line 19371) | static get platform() {
method isCSSRoundSupported (line 19381) | static get isCSSRoundSupported() {
class Util (line 19386) | class Util {
method makeHexColor (line 19387) | static makeHexColor(r, g, b) {
method scaleMinMax (line 19390) | static scaleMinMax(transform, minMax) {
method transform (line 19434) | static transform(m1, m2) {
method applyTransform (line 19437) | static applyTransform(p, m) {
method applyInverseTransform (line 19442) | static applyInverseTransform(p, m) {
method getAxialAlignedBoundingBox (line 19448) | static getAxialAlignedBoundingBox(r, m) {
method inverseTransform (line 19455) | static inverseTransform(m) {
method singularValueDecompose2dScale (line 19459) | static singularValueDecompose2dScale(m) {
method normalizeRect (line 19471) | static normalizeRect(rect) {
method intersect (line 19483) | static intersect(rect1, rect2) {
method #getExtremumOnCurve (line 19496) | static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {
method #getExtremum (line 19510) | static #getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, a, b, c, minMax) {
method bezierBoundingBox (line 19526) | static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {
function stringToPDFString (line 19541) | function stringToPDFString(str) {
function stringToUTF8String (line 19585) | function stringToUTF8String(str) {
function utf8StringToString (line 19588) | function utf8StringToString(str) {
function isArrayEqual (line 19591) | function isArrayEqual(arr1, arr2) {
function getModificationDate (line 19602) | function getModificationDate(date = new Date()) {
function normalizeUnicode (line 19608) | function normalizeUnicode(str) {
function getUuid (line 19615) | function getUuid() {
function __webpack_require__ (line 19651) | function __webpack_require__(moduleId) {
FILE: src/StaffWebUI/wwwroot/pdfjs-4.2.67-dist/build/pdf.sandbox.mjs
function D (line 53) | function D(){var a=x.buffer;d.HEAP8=z=new Int8Array(a);d.HEAP16=new Int1...
function ba (line 53) | function ba(){var a=d.preRun.shift();E.unshift(a);}
function w (line 53) | function w(a){d.onAbort?.(a);a="Aborted("+a+")";u(a);y=!0;a=new WebAssem...
function ca (line 53) | function ca(){var a=L;return Promise.resolve().then(()=>{if(a==L&&v)var ...
function da (line 53) | function da(a,b){return ca().then(c=>WebAssembly.instantiate(c,a)).then(...
function ea (line 53) | function ea(a,b){return da(a,b);}
function U (line 53) | function U(){}
function e (line 53) | function e(t){return(t=t.toTimeString().match(/\(([A-Za-z ]+)\)$/))?t[1]...
function a (line 53) | function a(c){X=c.exports;x=X.m;D();F.unshift(X.n);H--;d.monitorRunDepen...
function na (line 53) | function na(){function a(){if(!Z&&(Z=!0,d.calledRun=!0,!y)){N(F);k(d);if...
class SandboxSupportBase (line 55) | class SandboxSupportBase {
method constructor (line 56) | constructor(win) {
method destroy (line 61) | destroy() {
method exportValueToSandbox (line 68) | exportValueToSandbox(val) {
method importValueFromSandbox (line 71) | importValueFromSandbox(val) {
method createErrorForSandbox (line 74) | createErrorForSandbox(errorMessage) {
method callSandboxFunction (line 77) | callSandboxFunction(name, args) {
method createSandboxExternals (line 85) | createSandboxExternals() {
class SandboxSupport (line 172) | class SandboxSupport extends SandboxSupportBase {
method exportValueToSandbox (line 173) | exportValueToSandbox(val) {
method importValueFromSandbox (line 176) | importValueFromSandbox(val) {
method createErrorForSandbox (line 179) | createErrorForSandbox(errorMessage) {
class Sandbox (line 183) | class Sandbox {
method constructor (line 184) | constructor(win, module) {
method create (line 190) | create(data) {
method dispatchEvent (line 214) | dispatchEvent(event) {
method dumpMemoryUse (line 217) | dumpMemoryUse() {
method nukeSandbox (line 220) | nukeSandbox() {
method evalForTesting (line 228) | evalForTesting(code, key) {
function QuickJSSandbox (line 232) | function QuickJSSandbox() {
FILE: src/StaffWebUI/wwwroot/pdfjs-4.2.67-dist/build/pdf.worker.mjs
constant IDENTITY_MATRIX (line 54) | const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
constant FONT_IDENTITY_MATRIX (line 55) | const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
constant MAX_IMAGE_SIZE_TO_CACHE (line 56) | const MAX_IMAGE_SIZE_TO_CACHE = 10e6;
constant LINE_FACTOR (line 57) | const LINE_FACTOR = 1.35;
constant LINE_DESCENT_FACTOR (line 58) | const LINE_DESCENT_FACTOR = 0.35;
constant BASELINE_FACTOR (line 59) | const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;
constant OPS (line 235) | const OPS = {
function setVerbosityLevel (line 330) | function setVerbosityLevel(level) {
function getVerbosityLevel (line 335) | function getVerbosityLevel() {
function info (line 338) | function info(msg) {
function warn (line 343) | function warn(msg) {
function unreachable (line 348) | function unreachable(msg) {
function assert (line 351) | function assert(cond, msg) {
function _isValidProtocol (line 356) | function _isValidProtocol(url) {
function createValidAbsoluteUrl (line 368) | function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
function shadow (line 393) | function shadow(obj, prop, value, nonSerializable = false) {
function BaseException (line 403) | function BaseException(message, name) {
class PasswordException (line 414) | class PasswordException extends BaseException {
method constructor (line 415) | constructor(msg, code) {
class UnknownErrorException (line 420) | class UnknownErrorException extends BaseException {
method constructor (line 421) | constructor(msg, details) {
class InvalidPDFException (line 426) | class InvalidPDFException extends BaseException {
method constructor (line 427) | constructor(msg) {
class MissingPDFException (line 431) | class MissingPDFException extends BaseException {
method constructor (line 432) | constructor(msg) {
class UnexpectedResponseException (line 436) | class UnexpectedResponseException extends BaseException {
method constructor (line 437) | constructor(msg, status) {
class FormatError (line 442) | class FormatError extends BaseException {
method constructor (line 443) | constructor(msg) {
class AbortException (line 447) | class AbortException extends BaseException {
method constructor (line 448) | constructor(msg) {
function bytesToString (line 452) | function bytesToString(bytes) {
function stringToBytes (line 469) | function stringToBytes(str) {
function string32 (line 480) | function string32(value) {
function objectSize (line 483) | function objectSize(obj) {
function objectFromMap (line 486) | function objectFromMap(map) {
function isLittleEndian (line 493) | function isLittleEndian() {
function isEvalSupported (line 499) | function isEvalSupported() {
class FeatureTest (line 507) | class FeatureTest {
method isLittleEndian (line 508) | static get isLittleEndian() {
method isEvalSupported (line 511) | static get isEvalSupported() {
method isOffscreenCanvasSupported (line 514) | static get isOffscreenCanvasSupported() {
method platform (line 517) | static get platform() {
method isCSSRoundSupported (line 527) | static get isCSSRoundSupported() {
class Util (line 532) | class Util {
method makeHexColor (line 533) | static makeHexColor(r, g, b) {
method scaleMinMax (line 536) | static scaleMinMax(transform, minMax) {
method transform (line 580) | static transform(m1, m2) {
method applyTransform (line 583) | static applyTransform(p, m) {
method applyInverseTransform (line 588) | static applyInverseTransform(p, m) {
method getAxialAlignedBoundingBox (line 594) | static getAxialAlignedBoundingBox(r, m) {
method inverseTransform (line 601) | static inverseTransform(m) {
method singularValueDecompose2dScale (line 605) | static singularValueDecompose2dScale(m) {
method normalizeRect (line 617) | static normalizeRect(rect) {
method intersect (line 629) | static intersect(rect1, rect2) {
method #getExtremumOnCurve (line 642) | static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {
method #getExtremum (line 656) | static #getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, a, b, c, minMax) {
method bezierBoundingBox (line 672) | static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {
function stringToPDFString (line 687) | function stringToPDFString(str) {
function stringToUTF8String (line 731) | function stringToUTF8String(str) {
function utf8StringToString (line 734) | function utf8StringToString(str) {
function isArrayEqual (line 737) | function isArrayEqual(arr1, arr2) {
function getModificationDate (line 748) | function getModificationDate(date = new Date()) {
function normalizeUnicode (line 754) | function normalizeUnicode(str) {
function getUuid (line 761) | function getUuid() {
constant CIRCULAR_REF (line 790) | const CIRCULAR_REF = Symbol("CIRCULAR_REF");
constant EOF (line 791) | const EOF = Symbol("EOF");
function clearPrimitiveCaches (line 795) | function clearPrimitiveCaches() {
class Name (line 800) | class Name {
method constructor (line 801) | constructor(name) {
method get (line 804) | static get(name) {
class Cmd (line 808) | class Cmd {
method constructor (line 809) | constructor(cmd) {
method get (line 812) | static get(cmd) {
class Dict (line 819) | class Dict {
method constructor (line 820) | constructor(xref = null) {
method assignXref (line 827) | assignXref(newXref) {
method size (line 830) | get size() {
method get (line 833) | get(key1, key2, key3) {
method getAsync (line 846) | async getAsync(key1, key2, key3) {
method getArray (line 859) | getArray(key1, key2, key3) {
method getRaw (line 880) | getRaw(key) {
method getKeys (line 883) | getKeys() {
method getRawValues (line 886) | getRawValues() {
method set (line 889) | set(key, value) {
method has (line 892) | has(key) {
method forEach (line 895) | forEach(callback) {
method empty (line 900) | static get empty() {
method merge (line 907) | static merge({
method clone (line 949) | clone() {
class Ref (line 957) | class Ref {
method constructor (line 958) | constructor(num, gen) {
method toString (line 962) | toString() {
method fromString (line 968) | static fromString(str) {
method get (line 979) | static get(num, gen) {
class RefSet (line 984) | class RefSet {
method constructor (line 985) | constructor(parent = null) {
method has (line 988) | has(ref) {
method put (line 991) | put(ref) {
method remove (line 994) | remove(ref) {
method clear (line 1000) | clear() {
method [Symbol.iterator] (line 997) | [Symbol.iterator]() {
class RefSetCache (line 1004) | class RefSetCache {
method constructor (line 1005) | constructor() {
method size (line 1008) | get size() {
method get (line 1011) | get(ref) {
method has (line 1014) | has(ref) {
method put (line 1017) | put(ref, obj) {
method putAlias (line 1020) | putAlias(ref, aliasRef) {
method clear (line 1026) | clear() {
method items (line 1029) | *items() {
method [Symbol.iterator] (line 1023) | [Symbol.iterator]() {
function isName (line 1035) | function isName(v, name) {
function isCmd (line 1038) | function isCmd(v, cmd) {
function isDict (line 1041) | function isDict(v, type) {
function isRefsEqual (line 1044) | function isRefsEqual(v1, v2) {
class BaseStream (line 1050) | class BaseStream {
method constructor (line 1051) | constructor() {
method length (line 1056) | get length() {
method isEmpty (line 1059) | get isEmpty() {
method isDataLoaded (line 1062) | get isDataLoaded() {
method getByte (line 1065) | getByte() {
method getBytes (line 1068) | getBytes(length) {
method peekByte (line 1071) | peekByte() {
method peekBytes (line 1078) | peekBytes(length) {
method getUint16 (line 1083) | getUint16() {
method getInt32 (line 1091) | getInt32() {
method getByteRange (line 1098) | getByteRange(begin, end) {
method getString (line 1101) | getString(length) {
method skip (line 1104) | skip(n) {
method reset (line 1107) | reset() {
method moveStart (line 1110) | moveStart() {
method makeSubStream (line 1113) | makeSubStream(start, length, dict = null) {
method getBaseStreams (line 1116) | getBaseStreams() {
constant PDF_VERSION_REGEXP (line 1125) | const PDF_VERSION_REGEXP = /^[1-9]\.\d$/;
function getLookupTableFactory (line 1126) | function getLookupTableFactory(initializer) {
class MissingDataException (line 1137) | class MissingDataException extends BaseException {
method constructor (line 1138) | constructor(begin, end) {
class ParserEOFException (line 1144) | class ParserEOFException extends BaseException {
method constructor (line 1145) | constructor(msg) {
class XRefEntryException (line 1149) | class XRefEntryException extends BaseException {
method constructor (line 1150) | constructor(msg) {
class XRefParseException (line 1154) | class XRefParseException extends BaseException {
method constructor (line 1155) | constructor(msg) {
function arrayBuffersToBytes (line 1159) | function arrayBuffersToBytes(arr) {
function getInheritableProperty (line 1180) | function getInheritableProperty({
constant ROMAN_NUMBER_MAP (line 1203) | const ROMAN_NUMBER_MAP = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", ...
function toRomanNumerals (line 1204) | function toRomanNumerals(number, lowerCase = false) {
function log2 (line 1222) | function log2(x) {
function readInt8 (line 1228) | function readInt8(data, offset) {
function readUint16 (line 1231) | function readUint16(data, offset) {
function readUint32 (line 1234) | function readUint32(data, offset) {
function isWhiteSpace (line 1237) | function isWhiteSpace(ch) {
function isNumberArray (line 1240) | function isNumberArray(arr, len) {
function parseXFAPath (line 1243) | function parseXFAPath(path) {
function escapePDFName (line 1259) | function escapePDFName(str) {
function escapeString (line 1280) | function escapeString(str) {
function _collectJS (line 1290) | function _collectJS(entry, xref, list, parents) {
function collectActions (line 1327) | function collectActions(xref, dict, eventType) {
function encodeToXmlString (line 1382) | function encodeToXmlString(str) {
function validateFontName (line 1415) | function validateFontName(fontFamily, mustWarn = false) {
function validateCSSFont (line 1437) | function validateCSSFont(cssFontInfo) {
function recoverJsURL (line 1455) | function recoverJsURL(str) {
function numberToString (line 1472) | function numberToString(value) {
function getNewAnnotationsMap (line 1485) | function getNewAnnotationsMap(annotationStorage) {
function isAscii (line 1503) | function isAscii(str) {
function stringToUTF16HexString (line 1506) | function stringToUTF16HexString(str) {
function stringToUTF16String (line 1514) | function stringToUTF16String(str, bigEndian = false) {
function getRotationMatrix (line 1525) | function getRotationMatrix(rotation, width, height) {
function getSizeInBytes (line 1537) | function getSizeInBytes(x) {
class Stream (line 1544) | class Stream extends BaseStream {
method constructor (line 1545) | constructor(arrayBuffer, start, length, dict) {
method length (line 1553) | get length() {
method isEmpty (line 1556) | get isEmpty() {
method getByte (line 1559) | getByte() {
method getBytes (line 1565) | getBytes(length) {
method getByteRange (line 1579) | getByteRange(begin, end) {
method reset (line 1588) | reset() {
method moveStart (line 1591) | moveStart() {
method makeSubStream (line 1594) | makeSubStream(start, length, dict = null) {
class StringStream (line 1598) | class StringStream extends Stream {
method constructor (line 1599) | constructor(str) {
class NullStream (line 1603) | class NullStream extends Stream {
method constructor (line 1604) | constructor() {
class ChunkedStream (line 1613) | class ChunkedStream extends Stream {
method constructor (line 1614) | constructor(length, chunkSize, manager) {
method getMissingChunks (line 1623) | getMissingChunks() {
method numChunksLoaded (line 1632) | get numChunksLoaded() {
method isDataLoaded (line 1635) | get isDataLoaded() {
method onReceiveData (line 1638) | onReceiveData(begin, chunk) {
method onReceiveProgressiveData (line 1654) | onReceiveProgressiveData(data) {
method ensureByte (line 1665) | ensureByte(pos) {
method ensureRange (line 1681) | ensureRange(begin, end) {
method nextEmptyChunk (line 1699) | nextEmptyChunk(beginChunk) {
method hasChunk (line 1709) | hasChunk(chunk) {
method getByte (line 1712) | getByte() {
method getBytes (line 1722) | getBytes(length) {
method getByteRange (line 1742) | getByteRange(begin, end) {
method makeSubStream (line 1754) | makeSubStream(start, length, dict = null) {
method getBaseStreams (line 1791) | getBaseStreams() {
class ChunkedStreamManager (line 1795) | class ChunkedStreamManager {
method constructor (line 1796) | constructor(pdfNetworkStream, args) {
method sendRequest (line 1811) | sendRequest(begin, end) {
method requestAllChunks (line 1853) | requestAllChunks(noFetch = false) {
method _requestChunks (line 1860) | _requestChunks(chunks) {
method getStream (line 1899) | getStream() {
method requestRange (line 1902) | requestRange(begin, end) {
method requestRanges (line 1912) | requestRanges(ranges = []) {
method groupChunks (line 1928) | groupChunks(chunks) {
method onProgress (line 1954) | onProgress(args) {
method onReceiveData (line 1960) | onReceiveData(args) {
method onError (line 2018) | onError(err) {
method getBeginChunk (line 2021) | getBeginChunk(begin) {
method getEndChunk (line 2024) | getEndChunk(end) {
method abort (line 2027) | abort(reason) {
function resizeRgbImage (line 2041) | function resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) {
class ColorSpace (line 2064) | class ColorSpace {
method constructor (line 2065) | constructor(name, numComps) {
method getRgb (line 2072) | getRgb(src, srcOffset) {
method getRgbItem (line 2077) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2080) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2083) | getOutputLength(inputLength, alpha01) {
method isPassthrough (line 2086) | isPassthrough(bits) {
method isDefaultDecode (line 2089) | isDefaultDecode(decodeMap, bpc) {
method fillRgb (line 2092) | fillRgb(dest, originalWidth, originalHeight, width, height, actualHeig...
method usesZeroToOneRange (line 2146) | get usesZeroToOneRange() {
method _cache (line 2149) | static _cache(cacheKey, xref, localColorSpaceCache, parsedColorSpace) {
method getCached (line 2168) | static getCached(cacheKey, xref, localColorSpaceCache) {
method parseAsync (line 2193) | static async parseAsync({
method parse (line 2204) | static parse({
method _parse (line 2219) | static _parse(cs, xref, resources = null, pdfFunctionFactory) {
method isDefaultDecode (line 2328) | static isDefaultDecode(decode, numComps) {
method singletons (line 2343) | static get singletons() {
class AlternateCS (line 2357) | class AlternateCS extends ColorSpace {
method constructor (line 2358) | constructor(numComps, base, tintFn) {
method getRgbItem (line 2364) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2369) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2400) | getOutputLength(inputLength, alpha01) {
class PatternCS (line 2404) | class PatternCS extends ColorSpace {
method constructor (line 2405) | constructor(baseCS) {
method isDefaultDecode (line 2409) | isDefaultDecode(decodeMap, bpc) {
class IndexedCS (line 2413) | class IndexedCS extends ColorSpace {
method constructor (line 2414) | constructor(base, highVal, lookup) {
method getRgbItem (line 2431) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2436) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2447) | getOutputLength(inputLength, alpha01) {
method isDefaultDecode (line 2450) | isDefaultDecode(decodeMap, bpc) {
class DeviceGrayCS (line 2465) | class DeviceGrayCS extends ColorSpace {
method constructor (line 2466) | constructor() {
method getRgbItem (line 2469) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2473) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2485) | getOutputLength(inputLength, alpha01) {
class DeviceRgbCS (line 2489) | class DeviceRgbCS extends ColorSpace {
method constructor (line 2490) | constructor() {
method getRgbItem (line 2493) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2498) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2513) | getOutputLength(inputLength, alpha01) {
method isPassthrough (line 2516) | isPassthrough(bits) {
class DeviceCmykCS (line 2520) | class DeviceCmykCS extends ColorSpace {
method constructor (line 2521) | constructor() {
method #toRgb (line 2524) | #toRgb(src, srcOffset, srcScale, dest, destOffset) {
method getRgbItem (line 2533) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2536) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2544) | getOutputLength(inputLength, alpha01) {
class CalGrayCS (line 2548) | class CalGrayCS extends ColorSpace {
method constructor (line 2549) | constructor(whitePoint, blackPoint, gamma) {
method #toRgb (line 2572) | #toRgb(src, srcOffset, dest, destOffset, scale) {
method getRgbItem (line 2581) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2584) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2592) | getOutputLength(inputLength, alpha01) {
class CalRGBCS (line 2596) | class CalRGBCS extends ColorSpace {
method constructor (line 2605) | constructor(whitePoint, blackPoint, gamma, matrix) {
method #matrixProduct (line 2626) | #matrixProduct(a, b, result) {
method #toFlat (line 2631) | #toFlat(sourceWhitePoint, LMS, result) {
method #toD65 (line 2636) | #toD65(sourceWhitePoint, LMS, result) {
method #sRGBTransferFunction (line 2644) | #sRGBTransferFunction(color) {
method #adjustToRange (line 2653) | #adjustToRange(min, max, value) {
method #decodeL (line 2656) | #decodeL(L) {
method #compensateBlackPoint (line 2665) | #compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result) {
method #normalizeWhitePointToFlat (line 2689) | #normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result) {
method #normalizeWhitePointToD65 (line 2702) | #normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result) {
method #toRgb (line 2709) | #toRgb(src, srcOffset, dest, destOffset, scale) {
method getRgbItem (line 2735) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2738) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2746) | getOutputLength(inputLength, alpha01) {
class LabCS (line 2750) | class LabCS extends ColorSpace {
method constructor (line 2751) | constructor(whitePoint, blackPoint, range) {
method #fn_g (line 2774) | #fn_g(x) {
method #decode (line 2777) | #decode(value, high1, low2, high2) {
method #toRgb (line 2780) | #toRgb(src, srcOffset, maxVal, dest, destOffset) {
method getRgbItem (line 2819) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 2822) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 2830) | getOutputLength(inputLength, alpha01) {
method isDefaultDecode (line 2833) | isDefaultDecode(decodeMap, bpc) {
method usesZeroToOneRange (line 2836) | get usesZeroToOneRange() {
function hexToInt (line 2843) | function hexToInt(a, size) {
function hexToStr (line 2850) | function hexToStr(a, size) {
function addHex (line 2859) | function addHex(a, b, size) {
function incHex (line 2867) | function incHex(a, size) {
constant MAX_NUM_SIZE (line 2875) | const MAX_NUM_SIZE = 16;
constant MAX_ENCODED_NUM_SIZE (line 2876) | const MAX_ENCODED_NUM_SIZE = 19;
class BinaryCMapStream (line 2877) | class BinaryCMapStream {
method constructor (line 2878) | constructor(data) {
method readByte (line 2884) | readByte() {
method readNumber (line 2890) | readNumber() {
method readSigned (line 2903) | readSigned() {
method readHex (line 2907) | readHex(num, size) {
method readHexNumber (line 2911) | readHexNumber(num, size) {
method readHexSigned (line 2937) | readHexSigned(num, size) {
method readString (line 2946) | readString() {
class BinaryCMapReader (line 2955) | class BinaryCMapReader {
method process (line 2956) | async process(data, cMap, extend) {
class DecodeStream (line 3102) | class DecodeStream extends BaseStream {
method constructor (line 3103) | constructor(maybeMinBufferLength) {
method isEmpty (line 3117) | get isEmpty() {
method ensureBuffer (line 3123) | ensureBuffer(requested) {
method getByte (line 3136) | getByte() {
method getBytes (line 3146) | getBytes(length, ignoreColorSpace = false) {
method reset (line 3168) | reset() {
method makeSubStream (line 3171) | makeSubStream(start, length, dict = null) {
method getBaseStreams (line 3184) | getBaseStreams() {
class StreamsSequenceStream (line 3188) | class StreamsSequenceStream extends DecodeStream {
method constructor (line 3189) | constructor(streams, onError = null) {
method readBlock (line 3198) | readBlock() {
method getBaseStreams (line 3221) | getBaseStreams() {
class Ascii85Stream (line 3236) | class Ascii85Stream extends DecodeStream {
method constructor (line 3237) | constructor(str, maybeLength) {
method readBlock (line 3246) | readBlock() {
class AsciiHexStream (line 3302) | class AsciiHexStream extends DecodeStream {
method constructor (line 3303) | constructor(str, maybeLength) {
method readBlock (line 3312) | readBlock() {
class CCITTFaxDecoder (line 3370) | class CCITTFaxDecoder {
method constructor (line 3371) | constructor(source, options = {}) {
method readNextChar (line 3406) | readNextChar() {
method _addPixels (line 3696) | _addPixels(a1, blackPixels) {
method _addPixelsNeg (line 3712) | _addPixelsNeg(a1, blackPixels) {
method _findTableCode (line 3738) | _findTableCode(start, end, table, limit) {
method _getTwoDimCode (line 3758) | _getTwoDimCode() {
method _getWhiteCode (line 3777) | _getWhiteCode() {
method _getBlackCode (line 3804) | _getBlackCode() {
method _lookBits (line 3840) | _lookBits(n) {
method _eatBits (line 3854) | _eatBits(n) {
class CCITTFaxStream (line 3865) | class CCITTFaxStream extends DecodeStream {
method constructor (line 3866) | constructor(str, maybeLength, params) {
method readBlock (line 3888) | readBlock() {
class FlateStream (line 3909) | class FlateStream extends DecodeStream {
method constructor (line 3910) | constructor(str, maybeLength) {
method getBits (line 3931) | getBits(bits) {
method getCode (line 3948) | getCode(table) {
method generateHuffmanTable (line 3972) | generateHuffmanTable(lengths) {
method #endsStreamOnError (line 4001) | #endsStreamOnError(err) {
method readBlock (line 4005) | readBlock() {
class ArithmeticDecoder (line 4384) | class ArithmeticDecoder {
method constructor (line 4385) | constructor(data, start, end) {
method byteIn (line 4397) | byteIn() {
method readBit (line 4421) | readBit(contexts, pos) {
class Jbig2Error (line 4478) | class Jbig2Error extends BaseException {
method constructor (line 4479) | constructor(msg) {
class ContextCache (line 4483) | class ContextCache {
method getContexts (line 4484) | getContexts(id) {
class DecodingContext (line 4491) | class DecodingContext {
method constructor (line 4492) | constructor(data, start, end) {
method decoder (line 4497) | get decoder() {
method contextCache (line 4501) | get contextCache() {
constant MAX_INT_32 (line 4506) | const MAX_INT_32 = 2 ** 31 - 1;
constant MIN_INT_32 (line 4507) | const MIN_INT_32 = -(2 ** 31);
function decodeInteger (line 4508) | function decodeInteger(contextCache, procedure, decoder) {
function decodeIAID (line 4533) | function decodeIAID(contextCache, decoder, codeLength) {
function decodeBitmapTemplate0 (line 4745) | function decodeBitmapTemplate0(width, height, decodingContext) {
function decodeBitmap (line 4763) | function decodeBitmap(mmr, width, height, templateIndex, prediction, ski...
function decodeRefinement (line 4871) | function decodeRefinement(width, height, templateIndex, referenceBitmap,...
function decodeSymbolDictionary (line 4939) | function decodeSymbolDictionary(huffman, refinement, symbols, numberOfNe...
function decodeTextRegion (line 5049) | function decodeTextRegion(huffman, refinement, width, height, defaultPix...
function decodePatternDictionary (line 5166) | function decodePatternDictionary(mmr, patternWidth, patternHeight, maxPa...
function decodeHalftoneRegion (line 5200) | function decodeHalftoneRegion(mmr, patterns, template, regionWidth, regi...
function readSegmentHeader (line 5297) | function readSegmentHeader(data, start) {
function readSegments (line 5389) | function readSegments(header, data, start, end) {
function readRegionSegmentInformation (line 5418) | function readRegionSegmentInformation(data, start) {
function processSegment (line 5428) | function processSegment(segment, visitor) {
function processSegments (line 5620) | function processSegments(segments, visitor) {
function parseJbig2Chunks (line 5625) | function parseJbig2Chunks(chunks) {
function parseJbig2 (line 5634) | function parseJbig2(data) {
class SimpleSegmentVisitor (line 5637) | class SimpleSegmentVisitor {
method onPageInformation (line 5638) | onPageInformation(info) {
method drawBitmap (line 5647) | drawBitmap(regionInfo, bitmap) {
method onImmediateGenericRegion (line 5696) | onImmediateGenericRegion(region, data, start, end) {
method onImmediateLosslessGenericRegion (line 5702) | onImmediateLosslessGenericRegion() {
method onSymbolDictionary (line 5705) | onSymbolDictionary(dictionary, currentSegment, referredSegments, data,...
method onImmediateTextRegion (line 5725) | onImmediateTextRegion(region, referredSegments, data, start, end) {
method onImmediateLosslessTextRegion (line 5745) | onImmediateLosslessTextRegion() {
method onPatternDictionary (line 5748) | onPatternDictionary(dictionary, currentSegment, data, start, end) {
method onImmediateHalftoneRegion (line 5756) | onImmediateHalftoneRegion(region, referredSegments, data, start, end) {
method onImmediateLosslessHalftoneRegion (line 5763) | onImmediateLosslessHalftoneRegion() {
method onTables (line 5766) | onTables(currentSegment, data, start, end) {
class HuffmanLine (line 5774) | class HuffmanLine {
method constructor (line 5775) | constructor(lineData) {
class HuffmanTreeNode (line 5793) | class HuffmanTreeNode {
method constructor (line 5794) | constructor(line) {
method buildTree (line 5806) | buildTree(line, shift) {
method decodeNode (line 5818) | decodeNode(reader) {
class HuffmanTable (line 5833) | class HuffmanTable {
method constructor (line 5834) | constructor(lines, prefixCodesDone) {
method decode (line 5846) | decode(reader) {
method assignPrefixCodes (line 5849) | assignPrefixCodes(lines) {
function decodeTablesSegment (line 5881) | function decodeTablesSegment(data, start, end) {
function getStandardTable (line 5909) | function getStandardTable(number) {
class Reader (line 5971) | class Reader {
method constructor (line 5972) | constructor(data, start, end) {
method readBit (line 5980) | readBit() {
method readBits (line 5992) | readBits(numBits) {
method byteAlign (line 6000) | byteAlign() {
method next (line 6003) | next() {
function getCustomHuffmanTable (line 6010) | function getCustomHuffmanTable(index, referredTo, customTables) {
function getTextRegionHuffmanTables (line 6023) | function getTextRegionHuffmanTables(textRegion, referredTo, customTables...
function getSymbolDictionaryHuffmanTables (line 6117) | function getSymbolDictionaryHuffmanTables(dictionary, referredTo, custom...
function readUncompressedBitmap (line 6164) | function readUncompressedBitmap(reader, width, height) {
function decodeMMRBitmap (line 6176) | function decodeMMRBitmap(input, width, height, endOfBlock) {
class Jbig2Image (line 6215) | class Jbig2Image {
method parseChunks (line 6216) | parseChunks(chunks) {
method parse (line 6219) | parse(data) {
class Jbig2Stream (line 6230) | class Jbig2Stream extends DecodeStream {
method constructor (line 6231) | constructor(stream, maybeLength, params) {
method bytes (line 6238) | get bytes() {
method ensureBuffer (line 6241) | ensureBuffer(requested) {}
method readBlock (line 6242) | readBlock() {
function convertToRGBA (line 6277) | function convertToRGBA(params) {
function convertBlackAndWhiteToRGBA (line 6286) | function convertBlackAndWhiteToRGBA({
function convertRGBToRGBA (line 6327) | function convertRGBToRGBA({
function grayToRGBA (line 6370) | function grayToRGBA(src, dest) {
class JpegError (line 6386) | class JpegError extends BaseException {
method constructor (line 6387) | constructor(msg) {
class DNLMarkerError (line 6391) | class DNLMarkerError extends BaseException {
method constructor (line 6392) | constructor(message, scanLines) {
class EOIMarkerError (line 6397) | class EOIMarkerError extends BaseException {
method constructor (line 6398) | constructor(msg) {
function buildHuffmanTable (line 6411) | function buildHuffmanTable(codeLengths, values) {
function getBlockBufferOffset (line 6455) | function getBlockBufferOffset(component, row, col) {
function decodeScan (line 6458) | function decodeScan(data, offset, frame, components, resetInterval, spec...
function quantizeAndInverse (line 6726) | function quantizeAndInverse(component, blockBufferOffset, p) {
function buildComponentData (line 6929) | function buildComponentData(frame, component) {
function findNextFileMarker (line 6941) | function findNextFileMarker(data, currentPos, startPos = currentPos) {
class JpegImage (line 6968) | class JpegImage {
method constructor (line 6969) | constructor({
method parse (line 6976) | parse(data, {
method _getLinearizedBlockData (line 7247) | _getLinearizedBlockData(width, height, isSourcePDF = false) {
method _isColorConversionNeeded (line 7297) | get _isColorConversionNeeded() {
method _convertYccToRgb (line 7314) | _convertYccToRgb(data) {
method _convertYccToRgba (line 7326) | _convertYccToRgba(data, out) {
method _convertYcckToRgb (line 7338) | _convertYcckToRgb(data) {
method _convertYcckToRgba (line 7352) | _convertYcckToRgba(data) {
method _convertYcckToCmyk (line 7365) | _convertYcckToCmyk(data) {
method _convertCmykToRgb (line 7377) | _convertCmykToRgb(data) {
method _convertCmykToRgba (line 7391) | _convertCmykToRgba(data) {
method getData (line 7404) | getData({
class JpegStream (line 7459) | class JpegStream extends DecodeStream {
method constructor (line 7460) | constructor(stream, maybeLength, params) {
method bytes (line 7474) | get bytes() {
method ensureBuffer (line 7477) | ensureBuffer(requested) {}
method readBlock (line 7478) | readBlock() {
function intArrayFromBase64 (line 7621) | function intArrayFromBase64(s) {
function tryParseAsDataURI (line 7629) | function tryParseAsDataURI(filename) {
function updateMemoryViews (line 7638) | function updateMemoryViews() {
function preRun (line 7653) | function preRun() {
function initRuntime (line 7662) | function initRuntime() {
function postRun (line 7666) | function postRun() {
function addOnPreRun (line 7675) | function addOnPreRun(cb) {
function addOnInit (line 7678) | function addOnInit(cb) {
function addOnPostRun (line 7681) | function addOnPostRun(cb) {
function addRunDependency (line 7687) | function addRunDependency(id) {
function removeRunDependency (line 7691) | function removeRunDependency(id) {
function getBinarySync (line 7710) | function getBinarySync(file) {
function instantiateSync (line 7723) | function instantiateSync(file, info) {
function createWasm (line 7730) | function createWasm() {
function _jsPrintWarning (line 7899) | function _jsPrintWarning(message_ptr) {
function _setImageData (line 7903) | function _setImageData(array_ptr, array_size) {
function _storeErrorMessage (line 7906) | function _storeErrorMessage(message_ptr) {
function run (line 7937) | function run() {
class JpxError (line 7982) | class JpxError extends BaseException {
method constructor (line 7983) | constructor(msg) {
class JpxImage (line 7987) | class JpxImage {
method decode (line 7989) | static decode(data, ignoreColorSpace = false) {
method cleanup (line 7999) | static cleanup() {
method parseImageProperties (line 8002) | static parseImageProperties(stream) {
class JpxStream (line 8032) | class JpxStream extends DecodeStream {
method constructor (line 8033) | constructor(stream, maybeLength, params) {
method bytes (line 8040) | get bytes() {
method ensureBuffer (line 8043) | ensureBuffer(requested) {}
method readBlock (line 8044) | readBlock(ignoreColorSpace) {
class LZWStream (line 8056) | class LZWStream extends DecodeStream {
method constructor (line 8057) | constructor(str, maybeLength, earlyChange) {
method readBits (line 8080) | readBits(n) {
method readBlock (line 8097) | readBlock() {
class PredictorStream (line 8175) | class PredictorStream extends DecodeStream {
method constructor (line 8176) | constructor(str, maybeLength, params) {
method readBlockTiff (line 8198) | readBlockTiff() {
method readBlockPng (line 8270) | readBlockPng() {
class RunLengthStream (line 8360) | class RunLengthStream extends DecodeStream {
method constructor (line 8361) | constructor(str, maybeLength) {
method readBlock (line 8366) | readBlock() {
constant MAX_LENGTH_TO_CACHE (line 8410) | const MAX_LENGTH_TO_CACHE = 1000;
function getInlineImageCacheKey (line 8411) | function getInlineImageCacheKey(bytes) {
class Parser (line 8423) | class Parser {
method constructor (line 8424) | constructor({
method refill (line 8438) | refill() {
method shift (line 8442) | shift() {
method tryShift (line 8451) | tryShift() {
method getObj (line 8462) | getObj(cipherTransform = null) {
method findDefaultInlineStreamEnd (line 8529) | findDefaultInlineStreamEnd(stream) {
method findDCTDecodeInlineStreamEnd (line 8620) | findDCTDecodeInlineStreamEnd(stream) {
method findASCII85DecodeInlineStreamEnd (line 8697) | findASCII85DecodeInlineStreamEnd(stream) {
method findASCIIHexDecodeInlineStreamEnd (line 8731) | findASCIIHexDecodeInlineStreamEnd(stream) {
method inlineStreamSkipEI (line 8749) | inlineStreamSkipEI(stream) {
method makeInlineImage (line 8764) | makeInlineImage(cipherTransform) {
method _findStreamLength (line 8843) | _findStreamLength(startPos, signature) {
method makeStream (line 8872) | makeStream(dict, cipherTransform) {
method filter (line 8923) | filter(stream, dict, length) {
method makeFilter (line 8951) | makeFilter(stream, name, maybeLength, params) {
function toHexDigit (line 9007) | function toHexDigit(ch) {
class Lexer (line 9016) | class Lexer {
method constructor (line 9017) | constructor(stream, knownCommands = null) {
method nextChar (line 9025) | nextChar() {
method peekChar (line 9028) | peekChar() {
method getNumber (line 9031) | getNumber() {
method getString (line 9105) | getString() {
method getName (line 9203) | getName() {
method _hexStringWarn (line 9242) | _hexStringWarn(ch) {
method getHexString (line 9253) | getHexString() {
method getObj (line 9293) | getObj() {
method skipToNextLine (line 9395) | skipToNextLine() {
class Linearization (line 9412) | class Linearization {
method create (line 9413) | static create(stream) {
constant BUILT_IN_CMAPS (line 9469) | const BUILT_IN_CMAPS = ["Adobe-GB1-UCS2", "Adobe-CNS1-UCS2", "Adobe-Japa...
constant MAX_MAP_RANGE (line 9470) | const MAX_MAP_RANGE = 2 ** 24 - 1;
class CMap (line 9471) | class CMap {
method constructor (line 9472) | constructor(builtInCMap = false) {
method addCodespaceRange (line 9481) | addCodespaceRang
Condensed preview — 302 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,548K chars).
[
{
"path": ".config/dotnet-tools.json",
"chars": 229,
"preview": "{\n \"version\": 1,\n \"isRoot\": true,\n \"tools\": {\n \"microsoft.extensions.ai.evaluation.console\": {\n \"version\": \"9"
},
{
"path": ".editorconfig",
"chars": 6126,
"preview": "###############################\n# Core EditorConfig Options #\n###############################\nroot = true\n# All files\n"
},
{
"path": ".gitignore",
"chars": 6860,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 444,
"preview": "# Microsoft Open Source Code of Conduct\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://op"
},
{
"path": "Directory.Build.props",
"chars": 182,
"preview": "<Project>\n\n <PropertyGroup>\n <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>\n <Implicit"
},
{
"path": "Directory.Packages.props",
"chars": 5339,
"preview": "<Project>\n <PropertyGroup>\n <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\n <CentralPackag"
},
{
"path": "LICENSE",
"chars": 1156,
"preview": " MIT License\n\n Copyright (c) .NET Foundation. All rights reserved.\n\n Permission is hereby granted, free of char"
},
{
"path": "README.md",
"chars": 4471,
"preview": "# eShopSupport \n\nA sample .NET application showcasing common use cases and development practices for build AI solutions "
},
{
"path": "SECURITY.md",
"chars": 2656,
"preview": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.9 BLOCK -->\n\n## Security\n\nMicrosoft takes the security of our software products an"
},
{
"path": "eShopSupport.sln",
"chars": 9374,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.0.3190"
},
{
"path": "nuget.config",
"chars": 526,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n <packageSources>\n <!--To inherit the global NuGet package so"
},
{
"path": "seeddata/DataGenerator/.gitignore",
"chars": 44,
"preview": "appsettings.Local.json\noutput/\noutput-demo/\n"
},
{
"path": "seeddata/DataGenerator/ChatCompletionServiceExtensions.cs",
"chars": 1853,
"preview": "using Microsoft.Extensions.DependencyInjection;\nusing System.Data.Common;\nusing Microsoft.Extensions.Hosting;\nusing Mic"
},
{
"path": "seeddata/DataGenerator/DataGenerator.csproj",
"chars": 1032,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net8.0</Targ"
},
{
"path": "seeddata/DataGenerator/Generators/CategoryGenerator.cs",
"chars": 3064,
"preview": "using eShopSupport.DataGenerator.Model;\nusing System.Text.RegularExpressions;\n\nnamespace eShopSupport.DataGenerator.Gen"
},
{
"path": "seeddata/DataGenerator/Generators/EvalQuestionGenerator.cs",
"chars": 6021,
"preview": "using System.Text;\nusing System.Threading.Channels;\nusing eShopSupport.DataGenerator.Model;\n\nnamespace eShopSupport.Dat"
},
{
"path": "seeddata/DataGenerator/Generators/GeneratorBase.cs",
"chars": 5656,
"preview": "using Microsoft.Extensions.AI;\nusing Microsoft.Extensions.DependencyInjection;\nusing System.Diagnostics;\nusing System.T"
},
{
"path": "seeddata/DataGenerator/Generators/LocalTextEmbeddingGenerator.cs",
"chars": 935,
"preview": "using Microsoft.Extensions.AI;\nusing SmartComponents.LocalEmbeddings;\n\nnamespace eShopSupport.DataGenerator.Generators;"
},
{
"path": "seeddata/DataGenerator/Generators/ManualGenerator.cs",
"chars": 6108,
"preview": "using eShopSupport.DataGenerator.Model;\nusing System.Text;\n\nnamespace eShopSupport.DataGenerator.Generators;\n\npublic cl"
},
{
"path": "seeddata/DataGenerator/Generators/ManualPdfConverter.cs",
"chars": 3082,
"preview": "using eShopSupport.DataGenerator.Model;\nusing Markdown2Pdf;\nusing Markdown2Pdf.Options;\nusing System.Text.RegularExpres"
},
{
"path": "seeddata/DataGenerator/Generators/ManualTocGenerator.cs",
"chars": 4292,
"preview": "using eShopSupport.DataGenerator.Model;\n\nnamespace eShopSupport.DataGenerator.Generators;\n\npublic class ManualTocGenera"
},
{
"path": "seeddata/DataGenerator/Generators/ProductGenerator.cs",
"chars": 2860,
"preview": "using eShopSupport.DataGenerator.Model;\n\nnamespace eShopSupport.DataGenerator.Generators;\n\npublic class ProductGenerato"
},
{
"path": "seeddata/DataGenerator/Generators/TicketGenerator.cs",
"chars": 5602,
"preview": "using eShopSupport.DataGenerator.Model;\n\nnamespace eShopSupport.DataGenerator.Generators;\n\npublic class TicketGenerator"
},
{
"path": "seeddata/DataGenerator/Generators/TicketSummaryGenerator.cs",
"chars": 6879,
"preview": "using eShopSupport.DataGenerator.Model;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace eShopS"
},
{
"path": "seeddata/DataGenerator/Generators/TicketThreadGenerator.cs",
"chars": 11672,
"preview": "using eShopSupport.DataGenerator.Model;\nusing System.Text;\nusing System.ComponentModel;\nusing System.Numerics.Tensors;\n"
},
{
"path": "seeddata/DataGenerator/Model/Category.cs",
"chars": 208,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class Category\n{\n public int CategoryId { get; set; }\n public"
},
{
"path": "seeddata/DataGenerator/Model/EvalQuestion.cs",
"chars": 323,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class EvalQuestion\n{\n public int QuestionId { get; set; }\n\n p"
},
{
"path": "seeddata/DataGenerator/Model/Manual.cs",
"chars": 163,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class Manual\n{\n public int ProductId { get; set; }\n public re"
},
{
"path": "seeddata/DataGenerator/Model/ManualPdf.cs",
"chars": 163,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class ManualPdf\n{\n public int ProductId { get; set; }\n public"
},
{
"path": "seeddata/DataGenerator/Model/ManualToc.cs",
"chars": 412,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class ManualToc\n{\n public int ProductId { get; set; }\n\n publi"
},
{
"path": "seeddata/DataGenerator/Model/Product.cs",
"chars": 333,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class Product\n{\n public int CategoryId { get; set; }\n\n public"
},
{
"path": "seeddata/DataGenerator/Model/Role.cs",
"chars": 88,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic enum Role { Customer, Assistant };\n"
},
{
"path": "seeddata/DataGenerator/Model/Ticket.cs",
"chars": 357,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class Ticket\n{\n public int TicketId { get; set; }\n\n public in"
},
{
"path": "seeddata/DataGenerator/Model/TicketThread.cs",
"chars": 807,
"preview": "using System.Text.Json.Serialization;\n\nnamespace eShopSupport.DataGenerator.Model;\n\npublic class TicketThread\n{\n pub"
},
{
"path": "seeddata/DataGenerator/Model/TicketThreadMessage.cs",
"chars": 220,
"preview": "namespace eShopSupport.DataGenerator.Model;\n\npublic class TicketThreadMessage\n{\n public int MessageId { get; set; }\n"
},
{
"path": "seeddata/DataGenerator/Program.cs",
"chars": 1816,
"preview": "using eShopSupport.DataGenerator;\nusing eShopSupport.DataGenerator.Generators;\nusing Microsoft.Extensions.Configuration"
},
{
"path": "seeddata/DataGenerator/appsettings.json",
"chars": 363,
"preview": "{\n // REMEMBER NOT TO COMMIT YOUR API KEYS TO SOURCE CONTROL\n // To reduce the risk, copy this file as appsettings.Loc"
},
{
"path": "seeddata/dev/categories.json",
"chars": 167401,
"preview": "[\n {\n \"CategoryId\": 1,\n \"Name\": \"Solar Power\",\n \"NameEmbeddingBase64\": \"SabWv7X47T8/yLw\\u002B9FtpP3Tzpj7DYZM/y"
},
{
"path": "seeddata/dev/customers.json",
"chars": 24340,
"preview": "[\n {\n \"CustomerId\": 71,\n \"FullName\": \"Sasha Patel\"\n },\n {\n \"CustomerId\": 338,\n \"FullName\": \"Elliot Lawson"
},
{
"path": "seeddata/dev/evalquestions.json",
"chars": 99707,
"preview": "[\n {\n \"QuestionId\": 1,\n \"ProductId\": 158,\n \"Question\": \"How to access essentials?\",\n \"Answer\": \"Unzip the m"
},
{
"path": "seeddata/dev/products.json",
"chars": 479790,
"preview": "[\n {\n \"ProductId\": 1,\n \"CategoryId\": 35,\n \"Brand\": \"Escapesafe\",\n \"Model\": \"Adventure GPS Tracker\",\n \"De"
},
{
"path": "seeddata/dev/tickets.json",
"chars": 993793,
"preview": "[\n {\n \"TicketId\": 1,\n \"ProductId\": 104,\n \"CreatedAt\": \"0001-01-01T00:00:00\",\n \"CustomerId\": 1,\n \"ShortSu"
},
{
"path": "seeddata/test/categories.json",
"chars": 7498,
"preview": "[\n {\n \"CategoryId\": 1,\n \"Name\": \"Bike Helmets\",\n \"NameEmbeddingBase64\": \"\\u002BZSwv7zpbD/2E5k\\u002B3lxgv7b/D8B"
},
{
"path": "seeddata/test/customers.json",
"chars": 189,
"preview": "[\n {\n \"CustomerId\": 2,\n \"FullName\": \"Eleanor Parker\"\n },\n {\n \"CustomerId\": 3,\n \"FullName\": \"Karen Johnson"
},
{
"path": "seeddata/test/evalquestions.json",
"chars": 762,
"preview": "[\n {\n \"QuestionId\": 1,\n \"ProductId\": 2,\n \"Question\": \"How to store Arctic Explorer Sleeping Bag?\",\n \"Answer"
},
{
"path": "seeddata/test/manual-chunks.json",
"chars": 325557,
"preview": "[\n {\n \"ChunkId\": 1,\n \"ProductId\": 1,\n \"PageNumber\": 1,\n \"Text\": \"(c) Rugged Riders 1\\n\\n\\nTrailblazer Bike "
},
{
"path": "seeddata/test/products.json",
"chars": 12197,
"preview": "[\n {\n \"ProductId\": 1,\n \"CategoryId\": 1,\n \"Brand\": \"Rugged Riders\",\n \"Model\": \"Trailblazer Bike Helmet\",\n "
},
{
"path": "seeddata/test/tickets.json",
"chars": 10291,
"preview": "[\n {\n \"TicketId\": 1,\n \"ProductId\": 1,\n \"CreatedAt\": \"0001-01-01T00:00:00\",\n \"CustomerId\": 1,\n \"ShortSumm"
},
{
"path": "src/AppHost/.gitignore",
"chars": 23,
"preview": "appsettings.Local.json\n"
},
{
"path": "src/AppHost/AppHost.csproj",
"chars": 982,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net8.0</Targ"
},
{
"path": "src/AppHost/Ollama/OllamaResource.cs",
"chars": 305,
"preview": "namespace Aspire.Hosting;\n\ninternal class OllamaResource(string name, string[] models, string defaultModel, bool enable"
},
{
"path": "src/AppHost/Ollama/OllamaResourceExtensions.cs",
"chars": 7018,
"preview": "using System.Net.Http.Json;\nusing System.Text.Json;\nusing Aspire.Hosting.Lifecycle;\nusing Microsoft.Extensions.Logging;"
},
{
"path": "src/AppHost/Program.cs",
"chars": 2748,
"preview": "using Microsoft.Extensions.Configuration.Json;\nusing Microsoft.Extensions.Hosting;\nusing Projects;\n\nvar builder = Distr"
},
{
"path": "src/AppHost/Properties/launchSettings.json",
"chars": 1003,
"preview": "{\n \"$schema\": \"https://json.schemastore.org/launchsettings.json\",\n \"profiles\": {\n \"https\": {\n \"commandName\": \""
},
{
"path": "src/AppHost/Python/PythonUvicornAppResourceBuilderExtensions.cs",
"chars": 742,
"preview": "namespace Aspire.Hosting;\n\npublic static class PythonUvicornAppResourceBuilderExtensions\n{\n public static IResourceB"
},
{
"path": "src/AppHost/appsettings.Development.json",
"chars": 639,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\",\n \"Microsoft.AspNetCore\": \"Warning\"\n }\n },\n\n "
},
{
"path": "src/AppHost/appsettings.json",
"chars": 211,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\",\n \"Microsoft.AspNetCore\": \"Warning\",\n \"Aspir"
},
{
"path": "src/Backend/Api/AssistantApi.cs",
"chars": 7028,
"preview": "using System.ComponentModel;\nusing System.Text;\nusing System.Text.Json;\nusing System.Text.RegularExpressions;\nusing eSh"
},
{
"path": "src/Backend/Api/CatalogApi.cs",
"chars": 3576,
"preview": "using System.Numerics.Tensors;\nusing System.Runtime.InteropServices;\nusing Azure.Storage.Blobs;\nusing eShopSupport.Back"
},
{
"path": "src/Backend/Api/TicketApi.cs",
"chars": 9573,
"preview": "using System.Text.RegularExpressions;\nusing CustomerWebUI;\nusing eShopSupport.Backend.Data;\nusing eShopSupport.Backend."
},
{
"path": "src/Backend/Api/TicketMessagingApi.cs",
"chars": 1997,
"preview": "using CustomerWebUI;\nusing eShopSupport.Backend.Data;\nusing eShopSupport.Backend.Services;\nusing eShopSupport.ServiceDe"
},
{
"path": "src/Backend/Backend.csproj",
"chars": 910,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n <PropertyGroup>\n <TargetFramework>net8.0</TargetFramework>\n <Nullable>en"
},
{
"path": "src/Backend/Data/AppDbContext.cs",
"chars": 3748,
"preview": "using System.Text.Json;\nusing Microsoft.EntityFrameworkCore;\nusing Polly;\nusing Polly.Retry;\n\nnamespace eShopSupport.Ba"
},
{
"path": "src/Backend/Data/AsyncEnumerableExtensions.cs",
"chars": 359,
"preview": "namespace eShopSupport.Backend.Data;\n\ninternal static class AsyncEnumerableExtensions\n{\n public static async Task<Li"
},
{
"path": "src/Backend/Data/Customer.cs",
"chars": 156,
"preview": "namespace eShopSupport.Backend.Data;\n\npublic class Customer\n{\n public int CustomerId { get; set; }\n\n public requi"
},
{
"path": "src/Backend/Data/ManualChunk.cs",
"chars": 281,
"preview": "namespace eShopSupport.Backend.Data;\n\npublic class ManualChunk\n{\n public int ChunkId { get; set; }\n public int Pr"
},
{
"path": "src/Backend/Data/Message.cs",
"chars": 283,
"preview": "namespace eShopSupport.Backend.Data;\n\npublic class Message\n{\n public int MessageId { get; set; }\n\n public DateTim"
},
{
"path": "src/Backend/Data/Product.cs",
"chars": 1608,
"preview": "using System.ComponentModel.DataAnnotations.Schema;\nusing System.Runtime.InteropServices;\nusing System.Text.Json;\nusing"
},
{
"path": "src/Backend/Data/ProductCategory.cs",
"chars": 277,
"preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace eShopSupport.Backend.Data;\n\npublic class ProductCategory\n{\n "
},
{
"path": "src/Backend/Data/Ticket.cs",
"chars": 873,
"preview": "using System.Text.Json.Serialization;\nusing eShopSupport.ServiceDefaults.Clients.Backend;\n\nnamespace eShopSupport.Backe"
},
{
"path": "src/Backend/HttpContextUserIdentityExtensions.cs",
"chars": 742,
"preview": "using System.Security.Claims;\n\nnamespace CustomerWebUI;\n\npublic static class HttpContextUserIdentityExtensions\n{\n pu"
},
{
"path": "src/Backend/Program.cs",
"chars": 2356,
"preview": "using eShopSupport.Backend.Api;\nusing eShopSupport.Backend.Data;\nusing eShopSupport.Backend.Services;\nusing eShopSuppor"
},
{
"path": "src/Backend/Properties/launchSettings.json",
"chars": 992,
"preview": "{\n \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n \"iisSettings\": {\n \"windowsAuthentication\": false"
},
{
"path": "src/Backend/Services/ProductManualSemanticSearch.cs",
"chars": 5561,
"preview": "using System.IO.Compression;\nusing System.Runtime.InteropServices;\nusing System.Text.Json;\nusing Azure.Storage.Blobs;\nu"
},
{
"path": "src/Backend/Services/ProductSemanticSearch.cs",
"chars": 2314,
"preview": "using System.Text.Json;\nusing eShopSupport.Backend.Data;\nusing eShopSupport.ServiceDefaults.Clients.Backend;\nusing Micr"
},
{
"path": "src/Backend/Services/TicketSummarizer.cs",
"chars": 6966,
"preview": "using System.Text;\nusing System.Threading.RateLimiting;\nusing eShopSupport.Backend.Data;\nusing Microsoft.EntityFramewor"
},
{
"path": "src/Backend/appsettings.Development.json",
"chars": 119,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\",\n \"Microsoft.AspNetCore\": \"Warning\"\n }\n }\n}\n"
},
{
"path": "src/Backend/appsettings.json",
"chars": 142,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\",\n \"Microsoft.AspNetCore\": \"Warning\"\n }\n },\n "
},
{
"path": "src/CustomerWebUI/Components/App.razor",
"chars": 523,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-w"
},
{
"path": "src/CustomerWebUI/Components/Layout/FooterBar.razor",
"chars": 250,
"preview": "<footer class='eshop-footer'>\n <div class='eshop-footer-content'>\n <div class='eshop-footer-row'>\n <img role=\""
},
{
"path": "src/CustomerWebUI/Components/Layout/FooterBar.razor.css",
"chars": 605,
"preview": ".eshop-footer {\n margin-top: 3.5rem;\n background-color: #000;\n width: 100%;\n}\n\n.eshop-footer-content {\n max-width: "
},
{
"path": "src/CustomerWebUI/Components/Layout/HeaderBar.razor",
"chars": 692,
"preview": "@using Microsoft.AspNetCore.Components.Endpoints\n\n<div class=\"eshop-header\">\n <div class=\"eshop-header-hero\">\n "
},
{
"path": "src/CustomerWebUI/Components/Layout/HeaderBar.razor.css",
"chars": 2663,
"preview": ".eshop-header {\n position: relative;\n max-width: 120rem;\n margin: auto;\n width: 100%;\n}\n\n.eshop-header.home"
},
{
"path": "src/CustomerWebUI/Components/Layout/MainLayout.razor",
"chars": 251,
"preview": "@inherits LayoutComponentBase\n\n<div class=\"container\">\n <HeaderBar />\n @Body\n <FooterBar />\n</div>\n\n<div id=\"b"
},
{
"path": "src/CustomerWebUI/Components/Layout/MainLayout.razor.css",
"chars": 473,
"preview": "#blazor-error-ui {\n background: lightyellow;\n bottom: 0;\n box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);\n displa"
},
{
"path": "src/CustomerWebUI/Components/Layout/UserMenu.razor",
"chars": 791,
"preview": "@using Microsoft.AspNetCore.Components.Authorization\n@inject NavigationManager Nav\n\n<AuthorizeView>\n <Authorized>\n "
},
{
"path": "src/CustomerWebUI/Components/Layout/UserMenu.razor.css",
"chars": 633,
"preview": ".dropdown-menu {\n position: relative;\n display: inline-block;\n}\n\n.dropdown-content {\n display: none;\n posit"
},
{
"path": "src/CustomerWebUI/Components/Pages/Error.razor",
"chars": 1177,
"preview": "@page \"/Error\"\n@using System.Diagnostics\n\n<PageTitle>Error</PageTitle>\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\""
},
{
"path": "src/CustomerWebUI/Components/Pages/Home.razor",
"chars": 142,
"preview": "@page \"/\"\n@inject NavigationManager Nav\n@code {\n protected override void OnInitialized()\n {\n Nav.NavigateT"
},
{
"path": "src/CustomerWebUI/Components/Pages/Support/Ticket.razor",
"chars": 3892,
"preview": "@page \"/support/tickets/{TicketId:int}\"\n@inject CustomerBackendClient Backend\n@inject NavigationManager Nav\n@implements"
},
{
"path": "src/CustomerWebUI/Components/Pages/Support/Ticket.razor.css",
"chars": 1489,
"preview": ".messages {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n align-items: flex-start;\n padding-bott"
},
{
"path": "src/CustomerWebUI/Components/Pages/Support/TicketCreate.razor",
"chars": 2656,
"preview": "@page \"/support/new\"\n@implements IValidatableObject\n@inject CustomerBackendClient Backend\n@inject NavigationManager Nav"
},
{
"path": "src/CustomerWebUI/Components/Pages/Support/TicketCreate.razor.css",
"chars": 1404,
"preview": ".answer {\n background-color: #eee;\n border-radius: 0.5rem;\n padding: 1rem 1.5rem;\n margin: 0.5rem 0;\n mi"
},
{
"path": "src/CustomerWebUI/Components/Pages/Support/TicketList.razor",
"chars": 2030,
"preview": "@page \"/support\"\n@attribute [StreamRendering]\n@inject CustomerBackendClient Backend\n@using Microsoft.AspNetCore.Authori"
},
{
"path": "src/CustomerWebUI/Components/Pages/Support/TicketList.razor.css",
"chars": 707,
"preview": "h2 {\n margin-top: 3rem;\n}\n\n.start-button, .action-button {\n text-decoration: none;\n background: black;\n col"
},
{
"path": "src/CustomerWebUI/Components/Routes.razor",
"chars": 190,
"preview": "<Router AppAssembly=\"typeof(Program).Assembly\">\n <Found Context=\"routeData\">\n <RouteView RouteData=\"routeData"
},
{
"path": "src/CustomerWebUI/Components/_Imports.razor",
"chars": 500,
"preview": "@using System.Net.Http\n@using System.Net.Http.Json\n@using Microsoft.AspNetCore.Authorization\n@using Microsoft.AspNetCor"
},
{
"path": "src/CustomerWebUI/CustomerWebUI.csproj",
"chars": 555,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n <PropertyGroup>\n <TargetFramework>net8.0</TargetFramework>\n <Nullable>ena"
},
{
"path": "src/CustomerWebUI/Program.cs",
"chars": 2944,
"preview": "using CustomerWebUI.Components;\nusing eShopSupport.ServiceDefaults;\nusing eShopSupport.ServiceDefaults.Clients.Backend;"
},
{
"path": "src/CustomerWebUI/Properties/launchSettings.json",
"chars": 365,
"preview": "{\n \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n \"profiles\": {\n \"https\": {\n \"commandNam"
},
{
"path": "src/CustomerWebUI/appsettings.Development.json",
"chars": 119,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\",\n \"Microsoft.AspNetCore\": \"Warning\"\n }\n }\n}\n"
},
{
"path": "src/CustomerWebUI/appsettings.json",
"chars": 142,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\",\n \"Microsoft.AspNetCore\": \"Warning\"\n }\n },\n "
},
{
"path": "src/CustomerWebUI/wwwroot/css/app.css",
"chars": 8823,
"preview": "/* plus-jakarta-sans-200 - latin */\n@font-face {\n font-display: swap;\n font-family: 'Plus Jakarta Sans';\n font-"
},
{
"path": "src/CustomerWebUI/wwwroot/css/normalize.css",
"chars": 6642,
"preview": "/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in i"
},
{
"path": "src/DataIngestor/DataIngestor.csproj",
"chars": 1036,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net8.0</Targ"
},
{
"path": "src/DataIngestor/EvalQuestionIngestor.cs",
"chars": 1044,
"preview": "using System.Text.Json;\nusing eShopSupport.Evaluator;\n\npublic class EvalQuestionIngestor\n{\n public async Task RunAsy"
},
{
"path": "src/DataIngestor/ManualIngestor.cs",
"chars": 2750,
"preview": "using System.Runtime.InteropServices;\nusing System.Text.Json;\nusing eShopSupport.Backend.Data;\nusing Microsoft.Semantic"
},
{
"path": "src/DataIngestor/ManualZipIngestor.cs",
"chars": 495,
"preview": "using System.IO.Compression;\n\npublic class ManualZipIngestor\n{\n public Task RunAsync(string generatedDataPath, strin"
},
{
"path": "src/DataIngestor/PathUtils.cs",
"chars": 522,
"preview": "public static class PathUtils\n{\n public static string FindAncestorDirectoryContaining(string pattern)\n {\n "
},
{
"path": "src/DataIngestor/ProductCategoryIngestor.cs",
"chars": 1684,
"preview": "using System.Runtime.InteropServices;\nusing System.Text.Json;\nusing eShopSupport.Backend.Data;\nusing Microsoft.Semantic"
},
{
"path": "src/DataIngestor/ProductIngestor.cs",
"chars": 1709,
"preview": "using System.Text.Json;\nusing eShopSupport.Backend.Data;\nusing Microsoft.SemanticKernel.Embeddings;\nusing SmartComponen"
},
{
"path": "src/DataIngestor/Program.cs",
"chars": 2303,
"preview": "// This data ingestion pipeline works with the output from the DataGenerator project.\n//\n// The reason for separating d"
},
{
"path": "src/DataIngestor/TicketIngestor.cs",
"chars": 2866,
"preview": "using System.Collections.Concurrent;\nusing System.Text.Json;\nusing eShopSupport.Backend.Data;\nusing eShopSupport.Servic"
},
{
"path": "src/Evaluator/.gitignore",
"chars": 23,
"preview": "appsettings.Local.json\n"
},
{
"path": "src/Evaluator/EvalQuestion.cs",
"chars": 247,
"preview": "namespace eShopSupport.Evaluator;\n\npublic class EvalQuestion\n{\n public int QuestionId { get; set; }\n\n public int?"
},
{
"path": "src/Evaluator/Evaluator.csproj",
"chars": 974,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net8.0</Targ"
},
{
"path": "src/Evaluator/Program.cs",
"chars": 9591,
"preview": "using System.ClientModel;\nusing System.Data.Common;\nusing System.Reflection;\nusing System.Text;\nusing System.Text.Json;"
},
{
"path": "src/Evaluator/appsettings.json",
"chars": 363,
"preview": "{\n // REMEMBER NOT TO COMMIT YOUR API KEYS TO SOURCE CONTROL\n // To reduce the risk, copy this file as appsettings.Loc"
},
{
"path": "src/IdentityServer/.gitignore",
"chars": 6,
"preview": "keys/\n"
},
{
"path": "src/IdentityServer/Config.cs",
"chars": 2227,
"preview": "using Duende.IdentityServer;\nusing Duende.IdentityServer.Models;\n\nnamespace IdentityServer;\n\npublic static class Config"
},
{
"path": "src/IdentityServer/HostingExtensions.cs",
"chars": 1262,
"preview": "using Serilog;\n\nnamespace IdentityServer;\n\ninternal static class HostingExtensions\n{\n public static WebApplication C"
},
{
"path": "src/IdentityServer/IdentityServer.csproj",
"chars": 458,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n <PropertyGroup>\n <TargetFramework>net8.0</TargetFramework>\n <ImplicitUsi"
},
{
"path": "src/IdentityServer/Pages/Account/AccessDenied.cshtml",
"chars": 220,
"preview": "@page\n@model IdentityServer.Pages.Account.AccessDeniedModel\n@{\n}\n<div class=\"row\">\n <div class=\"col\">\n <h1>Acc"
},
{
"path": "src/IdentityServer/Pages/Account/AccessDenied.cshtml.cs",
"chars": 284,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Account/Create/Index.cshtml",
"chars": 1556,
"preview": "@page\n@model IdentityServer.Pages.Create.Index\n\n<div class=\"login-page\">\n <div class=\"lead\">\n <h1>Create Accou"
},
{
"path": "src/IdentityServer/Pages/Account/Create/Index.cshtml.cs",
"chars": 4334,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Account/Create/InputModel.cs",
"chars": 507,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Account/Login/Index.cshtml",
"chars": 4030,
"preview": "@page\n@model IdentityServer.Pages.Login.Index\n\n<div class=\"login-page\">\n <div class=\"lead\">\n <h1>Login</h1>\n "
},
{
"path": "src/IdentityServer/Pages/Account/Login/Index.cshtml.cs",
"chars": 9265,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Account/Login/InputModel.cs",
"chars": 469,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Account/Login/LoginOptions.cs",
"chars": 491,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Account/Login/ViewModel.cs",
"chars": 1169,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Account/Logout/Index.cshtml",
"chars": 441,
"preview": "@page\n@model IdentityServer.Pages.Logout.Index\n\n<div class=\"logout-page\">\n <div class=\"lead\">\n <h1>Logout</h1>"
},
{
"path": "src/IdentityServer/Pages/Account/Logout/Index.cshtml.cs",
"chars": 3677,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Account/Logout/LoggedOut.cshtml",
"chars": 739,
"preview": "@page\n@model IdentityServer.Pages.Logout.LoggedOut\n\n<div class=\"logged-out-page\">\n <h1>\n Logout\n <small"
},
{
"path": "src/IdentityServer/Pages/Account/Logout/LoggedOut.cshtml.cs",
"chars": 1256,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Account/Logout/LoggedOutViewModel.cs",
"chars": 517,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\n// C"
},
{
"path": "src/IdentityServer/Pages/Account/Logout/LogoutOptions.cs",
"chars": 324,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\n\nna"
},
{
"path": "src/IdentityServer/Pages/Ciba/All.cshtml",
"chars": 1823,
"preview": "@page\n@model IdentityServer.Pages.Ciba.AllModel\n@{\n}\n\n<div class=\"ciba-page\">\n <div class=\"row\">\n <div class=\""
},
{
"path": "src/IdentityServer/Pages/Ciba/All.cshtml.cs",
"chars": 938,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Ciba/Consent.cshtml",
"chars": 3788,
"preview": "@page\n@model IdentityServer.Pages.Ciba.Consent\n@{\n}\n\n<div class=\"ciba-consent\">\n <div class=\"lead\">\n @if (Mode"
},
{
"path": "src/IdentityServer/Pages/Ciba/Consent.cshtml.cs",
"chars": 8502,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Ciba/ConsentOptions.cs",
"chars": 654,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Ciba/Index.cshtml",
"chars": 861,
"preview": "@page\n@model IdentityServer.Pages.Ciba.IndexModel\n@{\n}\n\n<div class=\"ciba-page\">\n <div class=\"lead\">\n @if (Mode"
},
{
"path": "src/IdentityServer/Pages/Ciba/Index.cshtml.cs",
"chars": 1351,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Ciba/InputModel.cs",
"chars": 385,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Ciba/ViewModel.cs",
"chars": 1122,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Ciba/_ScopeListItem.cshtml",
"chars": 1333,
"preview": "@using IdentityServer.Pages.Ciba\n@model ScopeViewModel\n\n<li class=\"list-group-item\">\n <label>\n <input class=\"c"
},
{
"path": "src/IdentityServer/Pages/Consent/ConsentOptions.cs",
"chars": 657,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Consent/Index.cshtml",
"chars": 4181,
"preview": "@page\n@model IdentityServer.Pages.Consent.Index\n@{\n}\n\n<div class=\"page-consent\">\n <div class=\"lead\">\n @if (Mod"
},
{
"path": "src/IdentityServer/Pages/Consent/Index.cshtml.cs",
"chars": 8928,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Consent/InputModel.cs",
"chars": 449,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Consent/ViewModel.cs",
"chars": 1119,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Consent/_ScopeListItem.cshtml",
"chars": 1336,
"preview": "@using IdentityServer.Pages.Consent\n@model ScopeViewModel\n\n<li class=\"list-group-item\">\n <label>\n <input class"
},
{
"path": "src/IdentityServer/Pages/Device/DeviceOptions.cs",
"chars": 728,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Device/Index.cshtml",
"chars": 5670,
"preview": "@page\n@model IdentityServer.Pages.Device.Index\n@{\n}\n\n@if (Model.Input.UserCode == null)\n{\n @*We need to collect the u"
},
{
"path": "src/IdentityServer/Pages/Device/Index.cshtml.cs",
"chars": 8127,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Device/InputModel.cs",
"chars": 491,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Device/Success.cshtml",
"chars": 220,
"preview": "@page\n@model IdentityServer.Pages.Device.SuccessModel\n@{\n}\n\n\n<div class=\"page-device-success\">\n <div class=\"lead\">\n "
},
{
"path": "src/IdentityServer/Pages/Device/Success.cshtml.cs",
"chars": 350,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Device/ViewModel.cs",
"chars": 855,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Device/_ScopeListItem.cshtml",
"chars": 988,
"preview": "@using IdentityServer.Pages.Device\n@model ScopeViewModel\n\n<li class=\"list-group-item\">\n <label>\n <input class="
},
{
"path": "src/IdentityServer/Pages/Diagnostics/Index.cshtml",
"chars": 2403,
"preview": "@page\n@model IdentityServer.Pages.Diagnostics.Index\n\n<div class=\"diagnostics-page\">\n <div class=\"lead\">\n <h1>A"
},
{
"path": "src/IdentityServer/Pages/Diagnostics/Index.cshtml.cs",
"chars": 976,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Diagnostics/ViewModel.cs",
"chars": 958,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Extensions.cs",
"chars": 1564,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/ExternalLogin/Callback.cshtml",
"chars": 182,
"preview": "@page\n@model IdentityServer.Pages.ExternalLogin.Callback\n\n@{\n Layout = null;\n}\n\n<!DOCTYPE html>\n\n<html>\n<head>\n <t"
},
{
"path": "src/IdentityServer/Pages/ExternalLogin/Callback.cshtml.cs",
"chars": 6749,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/ExternalLogin/Challenge.cshtml",
"chars": 183,
"preview": "@page\n@model IdentityServer.Pages.ExternalLogin.Challenge\n\n@{\n Layout = null;\n}\n\n<!DOCTYPE html>\n\n<html>\n<head>\n <"
},
{
"path": "src/IdentityServer/Pages/ExternalLogin/Challenge.cshtml.cs",
"chars": 1559,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Grants/Index.cshtml",
"chars": 3317,
"preview": "@page\n@model IdentityServer.Pages.Grants.Index\n@{\n}\n\n<div class=\"grants-page\">\n <div class=\"lead\">\n <h1>Client"
},
{
"path": "src/IdentityServer/Pages/Grants/Index.cshtml.cs",
"chars": 2649,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Grants/ViewModel.cs",
"chars": 803,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Home/Error/Index.cshtml",
"chars": 931,
"preview": "@page\n@model IdentityServer.Pages.Error.Index\n\n<div class=\"error-page\">\n <div class=\"lead\">\n <h1>Error</h1>\n "
},
{
"path": "src/IdentityServer/Pages/Home/Error/Index.cshtml.cs",
"chars": 1165,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Home/Error/ViewModel.cs",
"chars": 400,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusi"
},
{
"path": "src/IdentityServer/Pages/IdentityServerSuppressions.cs",
"chars": 2431,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\n// T"
},
{
"path": "src/IdentityServer/Pages/Index.cshtml",
"chars": 1515,
"preview": "@page\n@model IdentityServer.Pages.Home.Index\n\n<div class=\"welcome-page\">\n <h1>\n <img src=\"~/duende-logo.svg\" c"
},
{
"path": "src/IdentityServer/Pages/Index.cshtml.cs",
"chars": 775,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Log.cs",
"chars": 2778,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nname"
},
{
"path": "src/IdentityServer/Pages/Redirect/Index.cshtml",
"chars": 388,
"preview": "@page\n@model IdentityServer.Pages.Redirect.IndexModel\n@{\n}\n\n<div class=\"redirect-page\">\n <div class=\"lead\">\n <"
},
{
"path": "src/IdentityServer/Pages/Redirect/Index.cshtml.cs",
"chars": 620,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/SecurityHeadersAttribute.cs",
"chars": 2597,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/ServerSideSessions/Index.cshtml",
"chars": 8272,
"preview": "@page\n@model IdentityServer.Pages.ServerSideSessions.IndexModel\n\n <div class=\"users-page\">\n <div class=\"row\">\n"
},
{
"path": "src/IdentityServer/Pages/ServerSideSessions/Index.cshtml.cs",
"chars": 2220,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/Shared/_Layout.cshtml",
"chars": 972,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "src/IdentityServer/Pages/Shared/_Nav.cshtml",
"chars": 964,
"preview": "@using Duende.IdentityServer.Extensions\n@{\n #nullable enable\n string? name = null;\n if (!true.Equals(ViewData[\""
},
{
"path": "src/IdentityServer/Pages/Shared/_ValidationSummary.cshtml",
"chars": 193,
"preview": "@if (ViewContext.ModelState.IsValid == false)\n{\n <div class=\"alert alert-danger\">\n <strong>Error</strong>\n "
},
{
"path": "src/IdentityServer/Pages/Telemetry.cs",
"chars": 5713,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusin"
},
{
"path": "src/IdentityServer/Pages/TestUsers.cs",
"chars": 2486,
"preview": "// Copyright (c) Duende Software. All rights reserved.\n// See LICENSE in the project root for license information.\n\nusi"
},
{
"path": "src/IdentityServer/Pages/_ViewImports.cshtml",
"chars": 82,
"preview": "@using IdentityServer.Pages\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
},
{
"path": "src/IdentityServer/Pages/_ViewStart.cshtml",
"chars": 30,
"preview": "@{\n Layout = \"_Layout\";\n}\n"
},
{
"path": "src/IdentityServer/Program.cs",
"chars": 783,
"preview": "using IdentityServer;\nusing Serilog;\n\nLog.Logger = new LoggerConfiguration()\n .WriteTo.Console()\n .CreateBootstra"
},
{
"path": "src/IdentityServer/Properties/launchSettings.json",
"chars": 246,
"preview": "{\n \"profiles\": {\n \"SelfHost\": {\n \"commandName\": \"Project\",\n \"launchBrowser\": true,\n \"environmentVaria"
},
{
"path": "src/IdentityServer/appsettings.json",
"chars": 335,
"preview": "{\n \"Serilog\": {\n \"MinimumLevel\": {\n \"Default\": \"Debug\",\n \"Override\": {\n \""
},
{
"path": "src/IdentityServer/wwwroot/css/site.css",
"chars": 660,
"preview": ".welcome-page .logo {\n width: 64px;\n}\n\n.icon-banner {\n width: 32px;\n}\n\n.body-container {\n margin-top: 60px;\n paddin"
},
{
"path": "src/IdentityServer/wwwroot/css/site.scss",
"chars": 693,
"preview": ".welcome-page {\n .logo {\n width: 64px;\n }\n}\n\n.icon-banner {\n width: 32px;\n}\n\n.body-container {\n margin-top: 60px;"
},
{
"path": "src/IdentityServer/wwwroot/js/signin-redirect.js",
"chars": 100,
"preview": "window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
},
{
"path": "src/IdentityServer/wwwroot/js/signout-redirect.js",
"chars": 167,
"preview": "window.addEventListener(\"load\", function () {\n var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n if (a)"
},
{
"path": "src/IdentityServer/wwwroot/lib/bootstrap/LICENSE",
"chars": 1131,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2011-2020 Twitter, Inc.\nCopyright (c) 2011-2020 The Bootstrap Authors\n\nPermission i"
}
]
// ... and 102 more files (download for full content)
About this extraction
This page contains the full source code of the dotnet/eShopSupport GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 302 files (22.5 MB), approximately 2.1M tokens, and a symbol index with 6134 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.