diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 6b41cd91d..b14c768a9 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -255,6 +255,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GXAzureEventGrid", "src\dot EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCoreAttackMitigationTest", "test\DotNetCoreAttackMitigationTest\DotNetCoreAttackMitigationTest.csproj", "{2D615969-53E2-4B77-9A9A-75C33865CF76}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetPDFUnitTest", "test\DotNetPdfTest\DotNetPDFUnitTest.csproj", "{0FCFB078-5584-469F-92CC-61B0A6216D0D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -613,6 +615,10 @@ Global {2D615969-53E2-4B77-9A9A-75C33865CF76}.Debug|Any CPU.Build.0 = Debug|Any CPU {2D615969-53E2-4B77-9A9A-75C33865CF76}.Release|Any CPU.ActiveCfg = Release|Any CPU {2D615969-53E2-4B77-9A9A-75C33865CF76}.Release|Any CPU.Build.0 = Release|Any CPU + {0FCFB078-5584-469F-92CC-61B0A6216D0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0FCFB078-5584-469F-92CC-61B0A6216D0D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FCFB078-5584-469F-92CC-61B0A6216D0D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0FCFB078-5584-469F-92CC-61B0A6216D0D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -729,6 +735,7 @@ Global {5BBC75F0-E51A-4EBD-A628-92498D319B1D} = {4C43F2DA-59E5-46F5-B691-195449498555} {7250CDB1-95C4-4822-B01B-3CBD73324CC9} = {30159B0F-BE61-4DB7-AC02-02851426BE4B} {2D615969-53E2-4B77-9A9A-75C33865CF76} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} + {0FCFB078-5584-469F-92CC-61B0A6216D0D} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C} diff --git a/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportItext7.cs b/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportItext8.cs similarity index 97% rename from dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportItext7.cs rename to dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportItext8.cs index 0370498b4..2f9d64bea 100644 --- a/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportItext7.cs +++ b/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportItext8.cs @@ -26,22 +26,19 @@ using iText.Layout.Properties; using iText.Layout.Splitting; using log4net; -using NetTopologySuite.Utilities; -using static iText.Kernel.Pdf.Colorspace.PdfPattern; using Path = System.IO.Path; -using Text = iText.Layout.Element.Text; namespace GeneXus.Printer { - public class GxReportBuilderPdf7 : GxReportBuilderPdf + public class GxReportBuilderPdf8 : GxReportBuilderPdf { static ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - public GxReportBuilderPdf7() { } - public GxReportBuilderPdf7(string appPath, Stream outputStream) + public GxReportBuilderPdf8() { } + public GxReportBuilderPdf8(string appPath, Stream outputStream) { - _pdfReport = new com.genexus.reports.PDFReportItextSharp7(appPath); + _pdfReport = new com.genexus.reports.PDFReportItext8(appPath); if (outputStream != null) { _pdfReport.setOutputStream(outputStream); @@ -54,7 +51,7 @@ public GxReportBuilderPdf7(string appPath, Stream outputStream) namespace com.genexus.reports { - public class PDFReportItextSharp7 : PDFReportItextBase + public class PDFReportItext8 : PDFReportItextBase { static ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); @@ -78,7 +75,7 @@ public class PDFReportItextSharp7 : PDFReportItextBase private Boolean fontBold; private Boolean fontItalic; - public PDFReportItextSharp7(String appPath) : base(appPath) + public PDFReportItext8(String appPath) : base(appPath) { documentImages = new Dictionary(); } @@ -777,6 +774,28 @@ public override void GxDrawText(String sTxt, int left, int top, int right, int b { try { + ConverterProperties converterProperties = new ConverterProperties(); + FontProvider fontProvider = new DefaultFontProvider(); + if (IsTrueType(baseFont)) + { + Hashtable locations = GetFontLocations(); + foreach (string fontName in locations.Keys) + { + string fontPath = (string)locations[fontName]; + if (string.IsNullOrEmpty(fontPath)) + { + MSPDFFontDescriptor fontDescriptor = new MSPDFFontDescriptor(); + fontPath = fontDescriptor.getTrueTypeFontLocation(fontName); + } + if (!string.IsNullOrEmpty(fontPath)) + { + + fontProvider.AddFont(fontPath); + } + } + } + document.SetFontProvider(fontProvider); + converterProperties.SetFontProvider(fontProvider); bottomAux = (float)convertScale(bottom); topAux = (float)convertScale(top); float drawingPageHeight = this.pageSize.GetTop() - topMargin - bottomMargin; @@ -792,12 +811,11 @@ public override void GxDrawText(String sTxt, int left, int top, int right, int b PdfCanvas htmlPdfCanvas = new PdfCanvas(pdfPage); Canvas htmlCanvas = new Canvas(canvas, htmlRectangle); - ConverterProperties converterProperties = new ConverterProperties(); - converterProperties.SetFontProvider(new DefaultFontProvider()); + //Iterate over the elements (a.k.a the parsed HTML string) and handle each case accordingly - IList elements = HtmlConverter.ConvertToElements(sTxt, new ConverterProperties()); + IList elements = HtmlConverter.ConvertToElements(sTxt, converterProperties); foreach (IElement element in elements) - ProcessHTMLElement(htmlRectangle, yPosition, (IBlockElement)element); + ProcessHTMLElement(htmlRectangle, yPosition, (IBlockElement)element, fontProvider); } catch (Exception ex1) { @@ -939,14 +957,14 @@ public override void GxDrawText(String sTxt, int left, int top, int right, int b } } - private void ProcessHTMLElement(Rectangle htmlRectangle, YPosition currentYPosition, IBlockElement blockElement) + private void ProcessHTMLElement(Rectangle htmlRectangle, YPosition currentYPosition, IBlockElement blockElement, FontProvider fontProvider) { Div div = blockElement as Div; if (div != null) { // Iterate through the children of the Div and process each child element recursively foreach (IElement child in div.GetChildren()) if (child is IBlockElement) - ProcessHTMLElement(htmlRectangle, currentYPosition, (IBlockElement)child); + ProcessHTMLElement(htmlRectangle, currentYPosition, (IBlockElement)child, fontProvider); } diff --git a/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs b/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs index 34e50a139..244084e07 100644 --- a/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs +++ b/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs @@ -473,7 +473,7 @@ static public IReportHandler GetPrinter( int outputType, string path, Stream rep Type classType = assem.GetType( "GeneXus.Printer.GxReportBuilderPdf", false, true); reportHandler = (IReportHandler) Activator.CreateInstance(classType,new Object[]{path, reportOutputStream}); #else - string reportBuidler = Preferences.PdfReportLibrary().Equals(PDF_LIBRARY_ITEXT8, StringComparison.OrdinalIgnoreCase) ? "GxReportBuilderPdf7" : "GxReportBuilderPdf"; + string reportBuidler = Preferences.PdfReportLibrary().Equals(PDF_LIBRARY_ITEXT8, StringComparison.OrdinalIgnoreCase) ? "GxReportBuilderPdf8" : "GxReportBuilderPdf"; reportHandler = (IReportHandler)(ClassLoader.FindInstance("GxPdfReportsCS", "GeneXus.Printer", reportBuidler, new Object[] { path, reportOutputStream }, null)); #endif } diff --git a/dotnet/test/DotNetPdfTest/DotNetPDFUnitTest.csproj b/dotnet/test/DotNetPdfTest/DotNetPDFUnitTest.csproj new file mode 100644 index 000000000..4bf058341 --- /dev/null +++ b/dotnet/test/DotNetPdfTest/DotNetPDFUnitTest.csproj @@ -0,0 +1,50 @@ + + + net6.0 + CS8032;1701;1702;NU1701 + Major + + + TRACE;NETCORE + + + DEBUG;TRACE;NETCORE + + + + + + + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + PreserveNewest + + + + diff --git a/dotnet/test/DotNetPdfTest/PDFTests.cs b/dotnet/test/DotNetPdfTest/PDFTests.cs new file mode 100644 index 000000000..801d80c13 --- /dev/null +++ b/dotnet/test/DotNetPdfTest/PDFTests.cs @@ -0,0 +1,32 @@ +using System; +using System.IO; +using GeneXus.Configuration; +using GeneXus.Programs; +using GeneXus.Utils; +using Xunit; + +namespace UnitTesting +{ + public class PDFTests + { + [Fact] + public void TestITextFormat() + { + string report = "PDFFormat.pdf"; + if (File.Exists(report)) + File.Delete(report); + try + { + apdfformat test = new apdfformat(); + test.execute(); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + Console.WriteLine(ex.ToString()); + } + Assert.True(File.Exists(report)); + } + } +} diff --git a/dotnet/test/DotNetPdfTest/apdfformat.cs b/dotnet/test/DotNetPdfTest/apdfformat.cs new file mode 100644 index 000000000..0b1a29d24 --- /dev/null +++ b/dotnet/test/DotNetPdfTest/apdfformat.cs @@ -0,0 +1,232 @@ +using GeneXus.Application; +using GeneXus.Data.NTier; +using GeneXus.Procedure; +namespace GeneXus.Programs +{ + public class apdfformat : GXProcedure + { + public int executeCmdLine(string[] args) + { + return ExecuteCmdLine(args); ; + } + + protected override int ExecuteCmdLine(string[] args) + { + execute(); + return GX.GXRuntime.ExitCode; + } + + public apdfformat() + { + context = new GxContext(); + DataStoreUtil.LoadDataStores(context); + IsMain = true; + context.SetDefaultTheme("Carmine", false); + } + + public apdfformat(IGxContext context) + { + this.context = context; + IsMain = false; + } + + public void execute() + { + initialize(); + ExecutePrivate(); + } + + public void executeSubmit() + { + SubmitImpl(); + } + + protected override void ExecutePrivate() + { + /* GeneXus formulas */ + /* Output device settings */ + M_top = 0; + M_bot = 6; + P_lines = (int)(66 - M_bot); + getPrinter().GxClearAttris(); + add_metrics(); + lineHeight = 15; + gxXPage = 100; + gxYPage = 100; + getPrinter().GxSetDocName("PDFFormat"); + getPrinter().GxSetDocFormat("PDF"); + try + { + Gx_out = "FIL"; + if (!initPrinter(Gx_out, gxXPage, gxYPage, "GXPRN.INI", "", "", 2, 1, 256, 16834, 11909, 0, 1, 1, 0, 1, 1)) + { + cleanup(); + return; + } + getPrinter().setModal(false) ; + P_lines = (int)(gxYPage-(lineHeight*6)); + Gx_line = (int)(P_lines+1); + getPrinter().setPageLines(P_lines); + getPrinter().setLineHeight(lineHeight); + getPrinter().setM_top(M_top); + getPrinter().setM_bot(M_bot); + AV8FCKAux = "tabla basica"; + AV9FormatRawHTML = "" + "" + "" + "
Tabla basica
row 1 cell 1 bold rojorow1 cell 2 bold azul
row 2 cell 1row2 cell 2
row 3 cell 1row 3 cell 2

 

"; + H1T0( false, 410) ; + getPrinter().GxAttris("Microsoft Sans Serif", 8, false, false, false, false, 0, 0, 0, 0, 0, 255, 255, 255) ; + getPrinter().GxDrawText(AV9FormatRawHTML, 61, Gx_line+89, 769, Gx_line+356, 0, 1, 0, 0) ; + getPrinter().GxDrawRect(61, Gx_line+11, 769, Gx_line+78, 1, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0) ; + getPrinter().GxDrawText(AV8FCKAux, 67, Gx_line+22, 760, Gx_line+66, 3, 0, 0, 0) ; + Gx_line = (int)(Gx_line+410); + AV8FCKAux = "lista de elementos"; + AV9FormatRawHTML = "
  1. Coffee
  2. Milk
"; + H1T0( false, 410) ; + getPrinter().GxAttris("Microsoft Sans Serif", 8, false, false, false, false, 0, 0, 0, 0, 0, 255, 255, 255) ; + getPrinter().GxDrawText(AV9FormatRawHTML, 61, Gx_line+89, 769, Gx_line+356, 0, 1, 0, 0) ; + getPrinter().GxDrawRect(61, Gx_line+11, 769, Gx_line+78, 1, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0) ; + getPrinter().GxDrawText(AV8FCKAux, 67, Gx_line+22, 760, Gx_line+66, 3, 0, 0, 0) ; + Gx_line = (int)(Gx_line+410); + AV8FCKAux = "parrafos"; + AV9FormatRawHTML = "

This is a paragraph 1

This is a paragraph 2"; + H1T0( false, 410) ; + getPrinter().GxAttris("Microsoft Sans Serif", 8, false, false, false, false, 0, 0, 0, 0, 0, 255, 255, 255) ; + getPrinter().GxDrawText(AV9FormatRawHTML, 61, Gx_line+89, 769, Gx_line+356, 0, 1, 0, 0) ; + getPrinter().GxDrawRect(61, Gx_line+11, 769, Gx_line+78, 1, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0) ; + getPrinter().GxDrawText(AV8FCKAux, 67, Gx_line+22, 760, Gx_line+66, 3, 0, 0, 0) ; + Gx_line = (int)(Gx_line+410); + AV8FCKAux = "horizontal rule"; + AV9FormatRawHTML = "

The hr tag defines a horizontal rule:


This is a paragraph


This is a paragraph

" + "

This is a paragraph

"; + H1T0( false, 410) ; + getPrinter().GxAttris("Microsoft Sans Serif", 8, false, false, false, false, 0, 0, 0, 0, 0, 255, 255, 255) ; + getPrinter().GxDrawText(AV9FormatRawHTML, 61, Gx_line+89, 769, Gx_line+356, 0, 1, 0, 0) ; + getPrinter().GxDrawRect(61, Gx_line+11, 769, Gx_line+78, 1, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0) ; + getPrinter().GxDrawText(AV8FCKAux, 67, Gx_line+22, 760, Gx_line+66, 3, 0, 0, 0) ; + Gx_line = (int)(Gx_line+410); + AV8FCKAux = "fonts"; + AV9FormatRawHTML = "

A heading

A paragraph.

" + ""; + H1T0( false, 410) ; + getPrinter().GxAttris("Microsoft Sans Serif", 8, false, false, false, false, 0, 0, 0, 0, 0, 255, 255, 255) ; + getPrinter().GxDrawText(AV9FormatRawHTML, 61, Gx_line+89, 769, Gx_line+356, 0, 1, 0, 0) ; + getPrinter().GxDrawRect(61, Gx_line+11, 769, Gx_line+78, 1, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0) ; + getPrinter().GxDrawText(AV8FCKAux, 67, Gx_line+22, 760, Gx_line+66, 3, 0, 0, 0) ; + Gx_line = (int)(Gx_line+410); + AV8FCKAux = "nested lists"; + AV9FormatRawHTML = "

A nested List:

  • Coffee
  • Tea
    • Black tea
    • Green tea" + "
      • China
      • Africa
  • Milk
"; + H1T0( false, 410) ; + getPrinter().GxAttris("Microsoft Sans Serif", 8, false, false, false, false, 0, 0, 0, 0, 0, 255, 255, 255) ; + getPrinter().GxDrawText(AV9FormatRawHTML, 61, Gx_line+89, 769, Gx_line+356, 0, 1, 0, 0) ; + getPrinter().GxDrawRect(61, Gx_line+11, 769, Gx_line+78, 1, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0) ; + getPrinter().GxDrawText(AV8FCKAux, 67, Gx_line+22, 760, Gx_line+66, 3, 0, 0, 0) ; + Gx_line = (int)(Gx_line+410); + AV8FCKAux = "radio buttons"; + AV9FormatRawHTML = "
Male
Female" + " I have a bike
I have a car
" + ""; + H1T0( false, 410) ; + getPrinter().GxAttris("Microsoft Sans Serif", 8, false, false, false, false, 0, 0, 0, 0, 0, 255, 255, 255) ; + getPrinter().GxDrawText(AV9FormatRawHTML, 61, Gx_line+89, 769, Gx_line+356, 0, 1, 0, 0) ; + getPrinter().GxDrawRect(61, Gx_line+11, 769, Gx_line+78, 1, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0) ; + getPrinter().GxDrawText(AV8FCKAux, 67, Gx_line+22, 760, Gx_line+66, 3, 0, 0, 0) ; + Gx_line = (int)(Gx_line+410); + /* Print footer for last page */ + ToSkip = (int)(P_lines + 1); + H1T0(true, 0); + } + catch (GeneXus.Printer.ProcessInterruptedException) + { + } + finally + { + /* Close printer file */ + try + { + getPrinter().GxEndPage(); + getPrinter().GxEndDocument(); + } + catch (GeneXus.Printer.ProcessInterruptedException) + { + } + endPrinter(); + } + this.cleanup(); + } + + protected void H1T0(bool bFoot, + int Inc) + { + /* Skip the required number of lines */ + while ((ToSkip > 0) || (Gx_line + Inc > P_lines)) + { + if (Gx_line + Inc >= P_lines) + { + if (Gx_page > 0) + { + /* Print footers */ + Gx_line = P_lines; + getPrinter().GxEndPage(); + if (bFoot) + { + return; + } + } + ToSkip = 0; + Gx_line = 0; + Gx_page = (int)(Gx_page + 1); + /* Skip Margin Top Lines */ + Gx_line = (int)(Gx_line + (M_top * lineHeight)); + /* Print headers */ + getPrinter().GxStartPage(); + if (true) break; + } + else + { + Gx_line = (int)(Gx_line + 1); + } + ToSkip = (int)(ToSkip - 1); + } + getPrinter().setPage(Gx_page); + } + + protected void add_metrics() + { + add_metrics0(); + } + + protected void add_metrics0() + { + getPrinter().setMetrics("Microsoft Sans Serif", false, false, 58, 14, 72, 171, new int[] { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 18, 20, 23, 36, 36, 57, 43, 12, 21, 21, 25, 37, 18, 21, 18, 18, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 18, 18, 37, 37, 37, 36, 65, 43, 43, 46, 46, 43, 39, 50, 46, 18, 32, 43, 36, 53, 46, 50, 43, 50, 46, 43, 40, 46, 43, 64, 41, 42, 39, 18, 18, 18, 27, 36, 21, 36, 36, 32, 36, 36, 18, 36, 36, 14, 15, 33, 14, 55, 36, 36, 36, 36, 21, 32, 18, 36, 33, 47, 31, 31, 31, 21, 17, 21, 37, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 18, 20, 36, 36, 36, 36, 17, 36, 21, 47, 24, 36, 37, 21, 47, 35, 26, 35, 21, 21, 21, 37, 34, 21, 21, 21, 23, 36, 53, 53, 53, 39, 43, 43, 43, 43, 43, 43, 64, 46, 43, 43, 43, 43, 18, 18, 18, 18, 46, 46, 50, 50, 50, 50, 50, 37, 50, 46, 46, 46, 46, 43, 43, 39, 36, 36, 36, 36, 36, 36, 57, 32, 36, 36, 36, 36, 18, 18, 18, 18, 36, 36, 36, 36, 36, 36, 36, 35, 39, 36, 36, 36, 36, 32, 36, 32 }); + } + + public override int getOutputType() + { + return GxReportUtils.OUTPUT_PDF; + } + + public override void cleanup() + { + CloseCursors(); + if (IsMain) waitPrinterEnd(); + if (IsMain) + { + context.CloseConnections(); + } + ExitApp(); + } + + public override void initialize() + { + AV8FCKAux = ""; + AV9FormatRawHTML = ""; + /* GeneXus formulas. */ + Gx_line = 0; + } + + private int M_top; + private int M_bot; + + private int ToSkip; + + + private string AV8FCKAux; + private string AV9FormatRawHTML; + } + +} diff --git a/dotnet/test/DotNetPdfTest/appsettings.json b/dotnet/test/DotNetPdfTest/appsettings.json new file mode 100644 index 000000000..86074a69a --- /dev/null +++ b/dotnet/test/DotNetPdfTest/appsettings.json @@ -0,0 +1,66 @@ +{ + "appSettings": { + "AppMainNamespace": "GeneXus.Programs", + "DataStore1": "Default", + "DataStore-Count": "1", + "DataStore-Default": "Default", + "Connection-Default-DBMS": "sqlserver", + "Connection-Default-Port": "", + "Connection-Default-LockTimeout": "0", + "Connection-Default-LockRetryCount": "10", + "Connection-Default-IsolationLevel": "CR", + "Connection-Default-Datasource": "", + "Connection-Default-User": "", + "Connection-Default-Password": "", + "Connection-Default-DB": "", + "Connection-Default-Schema": "", + "Connection-Default-Opts": "", + "Connection-Default-TrnInt": "1", + "DateFormat": "MDY", + "YearLimit": "1940", + "TimeAmPmFormat": "12", + "VER_STAMP": "20210602.093942", + "CS_BLOB_PATH": "PublicTempStorage", + "TMPMEDIA_DIR": "PrivateTempStorage", + "PRINT_LAYOUT_METADATA_DIR": "LayoutMetadata", + "StorageTimeZone": "1", + "LOGIN_AS_USERID": "0", + "LANGUAGE": "eng", + "LANG_NAME": "English", + "DECIMAL_POINT": ".", + "DATE_FMT": "MDY", + "CTOD_DATE_FMT": "L", + "Culture": "en-US", + "Theme": "Carmine", + "UseNamedParameters": "1", + "EnableIntegratedSecurity": "0", + "MAX_CURSOR": "100", + "STATIC_CONTENT": "", + "GX_BUILD_NUMBER": "11103481", + "CACHE_CONTENT_EXPIRATION": "36", + "ENABLE_MANAGEMENT": "0", + "COMPRESS_HTML": "1", + "IE_COMPATIBILITY_VIEW": "EmulateIE7", + "DocumentType": "HTML5", + "EXPOSE_METADATA": "0", + "SMART_CACHING": "0", + "wcf:serviceHostingEnvironment:useClassicReadEntityBodyMode": "true", + "HTTP_PROTOCOL": "Unsecure", + "SAMESITE_COOKIE": "Lax", + "CACHE_INVALIDATION_TOKEN": "20216211291931", + "CORS_ALLOW_ORIGIN": "https://normal-website.com", + "MY_CUSTOM_PTY": "DEFAULT_VALUE", + "PDF_RPT_LIBRARY": "ITEXT8" + + }, + "languages": { + "English": { + "code": "eng", + "culture": "en-US", + "date_fmt": "MDY", + "decimal_point": ".", + "thousand_sep": ",", + "time_fmt": "12" + } + } +} \ No newline at end of file