Display Files in the Document Viewer - ASP.NET and TypeScript

This tutorial shows how to create an ASP.NET Web application with TypeScript that uses the LEADTOOLS SDK to load a document in the HTML5 JavaScript Document Viewer.

Overview  
Summary This tutorial covers how to use LEADTOOLS Document Viewer SDK technology in an ASP.NET Web Application with TypeScript.
Completion Time 45 minutes
Visual Studio Project Download tutorial project (995 KB)
Platform ASP.NET Web Application
IDE Visual Studio 2022
Runtime Target .NET 6 or higher
Runtime License Download LEADTOOLS
Try it in another language

Required Knowledge

Get familiar with the basic steps of creating a project by reviewing the Add References and Set a License - ASP.NET and TypeScript tutorial, before working on the Display Files in the Document Viewer - ASP.NET and TypeScript tutorial.

Create the Project and Add LEADTOOLS References

Start with a copy of the project created in the Add References and Set a License - ASP.NET and TypeScript tutorial. If that project is unavailable, follow the steps in that tutorial to create it.

The references needed depend upon the purpose of the project. References can be added by .js files located at <INSTALL_DIR>\LEADTOOLS23\Bin\JS.

For this project, the following references are needed:

Make sure to add these files to the project's wwwroot\lib\leadtools folder. When adding these files in Visual Studio, other dependent JS files might be added as well. These can be removed if not listed above.

For a complete list of which JS files are required for your application, refer to Files to be Included with your Application

In addition, the following type definition files are needed for use with TypeScript:

These can be found in the same folder as the .js files at <INSTALL_DIR>\LEADTOOLS23\Bin\JS

Make sure to copy these files to the project's scripts\leadtools folder.

Set the License File

The License unlocks the features needed for the project. It must be set before any toolkit function is called. For details including tutorials for different platforms, refer to Setting a Runtime License.

There are two types of runtime licenses:


Note

Adding LEADTOOLS references and setting a license are covered in more detail in the Add References and Set a License - ASP.NET and TypeScript tutorial.


Add the Document Viewer HTML Elements

With the project created, dependencies added, and the license set, coding can begin.

Open the Pages/index.chtml file located in the project folder. Add the following lines to import the JS files and attach the dependencies to the index.chtml page.

<!-- Leadtools .js files --> 
<script src="~/lib/leadtools/Leadtools.js"></script> 
<script src="~/lib/leadtools/Leadtools.Controls.js"></script> 
<script src="~/lib/leadtools/Leadtools.Annotations.Engine.js"></script> 
<script src="~/lib/leadtools/Leadtools.Annotations.Designers.js"></script> 
<script src="~/lib/leadtools/Leadtools.Annotations.Rendering.JavaScript.js"></script> 
<script src="~/lib/leadtools/Leadtools.Annotations.Automation.js"></script> 
<script src="~/lib/leadtools/Leadtools.Document.js"></script> 
<script src="~/lib/leadtools/Leadtools.Document.Viewer.js"></script> 
<!-- DocumentViewer .js fies --> 
<script src="~/js/app.js"></script> 

Add the HTML elements that will be used as containers for the following components of the document viewer:

In addition, add a navigationbar element that will contain buttons to toggle between the thumbnail and bookmark containers.

Replace the preexisting <div> element with the code below:

<div id="navigationbar" class="navigationbar"> 
    <button id="showThumbnails" class="navigationbarBtn"> 
        <span class="icon thumbnailsIcon"></span> 
    </button> 
    <button id="showBookmarks" class="navigationbarBtn"> 
        <span class="icon bookmarksIcon"></span> 
    </button> 
</div> 
 
<div id="thumbnailsControl" class="affectedContainers"> 
    <div class="controlHeader"> 
        <label>Pages</label> 
    </div> 
    <div id="thumbnails"> 
    </div> 
</div> 
 
<div id="bookmarksControl" class="affectedContainers"> 
    <div class="controlHeader"> 
        <label>Bookmarks</label> 
    </div> 
    <div id="bookmarks"> 
    </div> 
</div> 
 
<div id="imageViewerContainer" class="affectedContainers"> 
    <!-- The viewer will be dynamically created inside imageViewerDiv --> 
    <div id="imageViewerDiv"> 
    </div> 
</div> 

The affectedContainers class is used for selecting elements that will adjust their display according to the size of the browser window. The navigationbar class is used in a similar way to adjust the display of the imageViewerContainer when the bookmark or thumbnails controls are toggled.

Modify the StyleSheet file

Right-click on the wwwroot/cs folder from the project and choose Add -> New Item. Choose the Style Sheet File, type the name documentViewer.css for the filename, and click Add.

Use this file to specify the display styles for the HTML elements of the document viewer using the code below:

/* Document Viewer styles 
-------------------------------------------------- */ 
body { 
    height: 100%; 
    background: white; 
    overflow: hidden; 
    color: #4D5F82; 
    height: 100%; 
    margin: 0; 
    -webkit-text-size-adjust: none; 
    font-family: helvetica; 
    font-size: 10pt; 
    margin-bottom: 60px; 
    display: block; 
} 
 
.navigationbar { 
    overflow: hidden; 
    position: fixed; 
    background-color: #DFE1E5; 
    display: block; 
    width: 40px; 
    left: 0px; 
    bottom: 60px; 
    top: 57px; 
    border-right: 1px solid; 
    border-right-color: #D4D6DB; 
    -webkit-box-shadow: 2px 0px 7px rgba(0, 0, 0, 0.3); 
    box-shadow: 2px 0px 7px rgba(0, 0, 0, 0.3); 
    z-index: 1; 
} 
 
    .navigationbar .icon { 
        width: 34px; 
    } 
 
.navigationbarBtn { 
    padding: 7px 0px 8px 0px; 
    width: 100%; 
    background-color: transparent; 
    border: 1px solid transparent; 
    border-right: 0; 
    outline: none; 
    width: 39px; 
    height: 45px; 
    -webkit-box-sizing: border-box; 
    -moz-box-sizing: border-box; 
    box-sizing: border-box; 
} 
 
.activeNavigationbarBtn { 
    background-color: #D4D6DB; 
    border-color: darkgray; 
} 
 
.icon { 
    position: relative; 
    display: inline-block; 
    background-repeat: no-repeat; 
    background-position: center; 
    width: 35px; 
    height: 25px; 
    top: 3px; 
} 
 
.thumbnailsIcon { 
    background-image: url("../resources/images/icons/Thumbnails.png"); 
} 
 
.bookmarksIcon { 
    background-image: url("../resources/images/icons/Bookmarks.png"); 
} 
 
 
#imageViewerContainer { 
    overflow: hidden; 
    position: fixed; 
    display: block; 
    left: 0px; 
    right: 0px; 
} 
 
#imageViewerDiv { 
    position: relative; 
    width: 100%; 
    height: 100%; 
    background-color: #C2C2C2; 
} 
 
#thumbnailsControl, #bookmarksControl { 
    width: 195px; 
    background-color: #D4D6DB; 
    z-index: 1; 
    position: fixed; 
    left: 39px; 
    -webkit-box-shadow: 5px 4px 5px -5px #333; 
    box-shadow: 5px 4px 5px -5px #333; 
    border: 1px solid darkgray; 
    display: none; 
} 
 
    #thumbnailsControl > .controlHeader, #bookmarksControl > .controlHeader { 
        padding: inherit; 
        text-align: inherit; 
        padding-top: 13px; 
        padding-left: 5px; 
    } 
 
#thumbnails, #bookmarks { 
    overflow: hidden; 
    top: 43px; 
    left: 5px; 
    right: 5px; 
    bottom: 5px; 
    position: absolute !important; 
    border: 1px solid darkgray; 
} 
 
#thumbnails { 
    background-color: #fafdff; 
} 
 
#bookmarks { 
    background-color: white; 
    overflow: auto !important; 
    font: normal normal 12px/20px Helvetica, Arial, sans-serif; 
} 

Link this CSS file to be used in the Pages/index.chtml file:

<!-- DocumentViewer stylesheet --> 
<link rel="stylesheet" href="~/css/documentviewer.css" /> 

Configure Program.cs

In the Solution Explorer, open Program.cs and use the code below to configure the project entry point.

C#
using Microsoft.AspNetCore.Builder; 
using Microsoft.Extensions.DependencyInjection; 
using Microsoft.Extensions.Hosting; 
 
var builder = WebApplication.CreateBuilder(args); 
builder.Services.AddRazorPages(); 
 
var app = builder.Build(); 
if (app.Environment.IsDevelopment()) 
{ 
    app.UseDeveloperExceptionPage(); 
} 
else 
{ 
    app.UseExceptionHandler("/Error"); 
    app.UseHsts(); 
} 
app.UseHttpsRedirection(); 
app.UseStaticFiles(); 
app.UseRouting(); 
app.UseAuthorization(); 
app.UseEndpoints(endpoints => 
{ 
    endpoints.MapRazorPages(); 
}); 
app.Run(); 

Add the Icon Image Resources

The navigationbar element uses an icon image for each button contained for toggling the display of the thumbnail or bookmark containers.

Create a resources folder under the wwwroot node of the project then create the images\icons sub-folders.

Add the Bookmarks.png and Thumbnails.png icon images to this folder. These images can be found at <INSTALL_DIR>\LEADTOOLS23\Common\JS\Resources\Images\Icons

Add the Document Viewer App Code

In the script\app.ts file, start by declaring a DocumentViewer module which will contain the existing window.onLoad function that sets the license.

Declare and export a new DocumentViewerApp class which will contain the properties and functions used for the configuration and operation of the document viewer web app.

Use the code below to define the public and private properties of the DocumentViewerApp as well as configure the constructor.

module DocumentViewer { 
    export class DocumentViewerApp { 
        // Document viewer 
        private _documentViewer: lt.Document.Viewer.DocumentViewer = null; 
 
        // HTML Elements 
        public navigationbarContainer: HTMLElement = document.getElementById("navigationbar"); 
        public navigationbar = { 
            showThumbnailsBtn: <HTMLButtonElement>document.getElementById("showThumbnails"), 
            showBookmarksBtn: <HTMLButtonElement>document.getElementById("showBookmarks") 
        }; 
        public imageViewerContainerDiv: HTMLElement = document.getElementById("imageViewerContainer"); 
        public thumbnailsContainer: HTMLElement = document.getElementById("thumbnailsControl"); 
        public bookmarksContainer: HTMLElement = document.getElementById("bookmarksControl"); 
        public affectedContainers: NodeListOf<HTMLElement> = document.querySelectorAll(".affectedContainers"); 
 
        constructor() { 
            window.onunload = ((e: Event) => this.onUnload(e)); 
            window.onresize = ((e: Event) => this.onResize(e)); 
        } 
 
        private onUnload(e: Event): void { 
            if (this._documentViewer != null) { 
                this._documentViewer.dispose(); 
            } 
        } 

Add onResize() Code to Configure Container Display

Use the code below to dynamically update the display of the document viewer elements according to the browser window size in relation to the header and footer elements in the project.

This code also adjusts the display of the view container if the thumbnail or bookmark containers are visible.

private onResize(e: Event) { 
   this.updateContainers(); 
} 
 
public updateContainers(): void { 
   let headerToolbarContainerHeight: number = document.querySelector<HTMLElement>(".navbar").offsetHeight; 
   let footerToolbarContainerHeight: number = document.querySelector<HTMLElement>(".footer").offsetHeight; 
 
   // Check visibility 
   let visibleThumbnails: boolean = window.getComputedStyle(this.thumbnailsContainer).display !== "none"; 
   let visibleBookmarks: boolean = window.getComputedStyle(this.bookmarksContainer).display !== "none"; 
 
   // Update navigationbar container top/bottom 
   this.navigationbarContainer.style.top = headerToolbarContainerHeight.toString() + "px"; 
   this.navigationbarContainer.style.bottom = footerToolbarContainerHeight.toString() + "px"; 
 
   // Update affected containers top/bottom 
   this.affectedContainers.forEach(container => container.style.top = headerToolbarContainerHeight.toString() + "px"); 
   this.affectedContainers.forEach(container => container.style.bottom = footerToolbarContainerHeight.toString() + "px"); 
 
   let navigationbarContainerWidth: number = this.navigationbarContainer.offsetWidth; 
   // Thumbnails, bookmarks and attachments Containers has same width 
   // Use thumbnails container as common 
   let containerWidth: number = parseInt(window.getComputedStyle(this.thumbnailsContainer).width); 
 
   // Now update viewer container 
   let imageViewerContainerDivLeft: number = navigationbarContainerWidth; 
   if (visibleThumbnails || visibleBookmarks) 
         imageViewerContainerDivLeft += containerWidth; 
   this.imageViewerContainerDiv.style.left = imageViewerContainerDivLeft.toString() + "px"; 
 
   // The viewer container size might be changed; call onSizeChanged 
   this._documentViewer.view.imageViewer.onSizeChanged(); 
   if (this._documentViewer.thumbnails != null) { 
         this._documentViewer.thumbnails.imageViewer.onSizeChanged(); 
         this._documentViewer.thumbnails.imageViewer.invalidate(lt.LeadRectD.empty); 
   } 
} 

Add the run() Code to Initialize the DocumentViewer App

Use the code below for the DocumentViewer.run() which will initialize the viewer, verify the service connection, and load a PDF document.

The PDF document that will be loaded is a sample Leadtools.pdf file that is available at https://demo.leadtools.com/images/pdf/leadtools.pdf

public run(): void { 
   // Initialize the Navigation Bar Buttons 
   this.navigationbar.showThumbnailsBtn.addEventListener("click", () => this.showContainer(this.thumbnailsContainer, true)); 
   this.navigationbar.showBookmarksBtn.addEventListener("click", () => this.showContainer(this.bookmarksContainer, true)); 
 
   // Initialize the document viewer 
   this.initDocumentViewer(); 
 
   // Initialize the UI 
   this.updateAppUIState(); 
 
   // Verify Service Connection 
   lt.Document.DocumentFactory.serviceHost = "http://localhost:40000"; 
   lt.Document.DocumentFactory.servicePath = ""; 
   lt.Document.DocumentFactory.serviceApiPath = "api"; 
 
   lt.Document.DocumentFactory.verifyService() 
         .done(() => { 
            lt.LTHelper.log("Service connection verified!"); 
 
         }) 
         .fail(() => { 
            lt.LTHelper.log("Service connection unavailable."); 
         }); 
 
   // Load a Document 
   const url = "https://demo.leadtools.com/images/pdf/leadtools.pdf"; 
   lt.Document.DocumentFactory.loadFromUri(url, null) 
         .done((doc) => { 
            this.setDocument(doc); 
            this.updateAppUIState(); 
         }); 
} 

Add the showContainer() Code

Use the code below for the navigation bar buttons to use for controlling the visibility of the thumbnails and bookmarks containers.

// Toggle the visibility of the thumbnails/bookmarks containers 
public showContainer(container, flipState: boolean): void { 
   let visibleThumbnails: boolean = window.getComputedStyle(this.thumbnailsContainer).display !== "none"; 
   let visibleBookmarks: boolean = window.getComputedStyle(this.bookmarksContainer).display !== "none"; 
 
   // Show Thumbnails 
   if (container == this.thumbnailsContainer) { 
         if (!visibleThumbnails) { 
            if (visibleBookmarks) { 
               this.bookmarksContainer.style.display = "none"; 
               this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn"); 
            } 
            this.navigationbar.showThumbnailsBtn.classList.add("activeNavigationbarBtn"); 
            this.thumbnailsContainer.style.display = "block"; 
         } else { 
            if (flipState) { 
               this.navigationbar.showThumbnailsBtn.classList.remove("activeNavigationbarBtn"); 
               this.thumbnailsContainer.style.display = "none"; 
            } 
         } 
 
         this.updateContainers(); 
         return; 
   } 
 
   // Show Bookmarks 
   if (container == this.bookmarksContainer) { 
         if (!visibleBookmarks) { 
            // Hide others 
            if (visibleThumbnails) { 
               this.thumbnailsContainer.style.display = "none"; 
               this.navigationbar.showThumbnailsBtn.classList.remove("activeNavigationbarBtn"); 
            } 
            this.navigationbar.showBookmarksBtn.classList.add("activeNavigationbarBtn"); 
            this.bookmarksContainer.style.display = "block"; 
         } else { 
            if (flipState) { 
               this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn"); 
               this.bookmarksContainer.style.display = "none"; 
            } 
         } 
         this.updateContainers(); 
         return; 
   } 
} 

Initialize and Create the Document Viewer

Use the following code to configure the document viewer. The createOptions object configures the creation of the viewer and hooks the HTML elements.

After the document viewer is created by the DocumentViewerFactory object, the document viewer settings can also be configured. In this tutorial, the following settings are applied:

// Create the document viewer 
private initDocumentViewer(): void { 
    // Document Viewer Creation Options 
    let createOptions: lt.Document.Viewer.DocumentViewerCreateOptions = new lt.Document.Viewer.DocumentViewerCreateOptions(); 
    createOptions.viewCreateOptions.useElements = false; 
    createOptions.thumbnailsCreateOptions.useElements = false; 
 
    // Set the UI part where the main view is displayed 
    createOptions.viewContainer = document.getElementById("imageViewerDiv"); 
    // Set the UI part where the thumbnails are displayed 
    createOptions.thumbnailsContainer = document.getElementById("thumbnails"); 
    // Set the UI part where the bookmarks are displayed (Set bookmarks container will show them in simple list) 
    createOptions.bookmarksContainer = document.getElementById("bookmarks"); 
 
    createOptions.useAnnotations = false; 
 
    // Create the viewer 
    try { 
        this._documentViewer = lt.Document.Viewer.DocumentViewerFactory.createDocumentViewer(createOptions); 
 
        // Document viewer settings 
 
        // SVG Preference for Display 
        this._documentViewer.view.preferredItemType = lt.Document.Viewer.DocumentViewerItemType.svg 
 
        // Lazy Loading 
        this._documentViewer.view.lazyLoad = true; 
        if (this._documentViewer.thumbnails) 
            this._documentViewer.thumbnails.lazyLoad = true; 
 
        // Log Rendering Errors 
        let imageViewer: lt.Controls.ImageViewer = this._documentViewer.view.imageViewer; 
 
        let logRenderErrors: lt.Controls.ImageViewerRenderEventHandler = function (sender: any, e: lt.Controls.ImageViewerRenderEventArgs) { 
            let item: number = e.item != null ? e.item.imageViewer.items.indexOf(e.item) : -1; 
            let message: string = "Error during render item " + item + " part " + (e.part) + ": " + (e.error.message); 
            lt.LTHelper.logError({ message: message, error: e.error }); 
        } 
 
        imageViewer.renderError.add(logRenderErrors); 
        if (this._documentViewer.thumbnails && this._documentViewer.thumbnails.imageViewer) 
            this._documentViewer.thumbnails.imageViewer.renderError.add(logRenderErrors); 
    } 
    catch (e) { 
        alert("DocumentViewer creation failed"); 
        lt.LTHelper.logError(e); 
        return; 
    } 
} 

Initialize the Document Viewer App UI

Use the code below to initialize the display of the document viewer app's user interface.

// Update the UI state of the app 
private updateAppUIState(): void { 
    let hasDocument: boolean = this._documentViewer.hasDocument; 
    if (hasDocument) { 
        if (window.getComputedStyle(this.imageViewerContainerDiv).display === "none") { 
            this.imageViewerContainerDiv.style.display = "block"; 
            this._documentViewer.view.imageViewer.updateTransform(); 
        } 
 
        if (this.navigationbar.showThumbnailsBtn.matches(":disabled")) 
            this.navigationbar.showThumbnailsBtn.disabled = false; 
 
 
        if (this._documentViewer.document.isStructureSupported) { 
            if (this.navigationbar.showBookmarksBtn.matches(":disabled")) 
                this.navigationbar.showBookmarksBtn.disabled = false; 
        } else { 
            this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn"); 
            if (!(this.navigationbar.showBookmarksBtn.matches(":disabled"))) 
                this.navigationbar.showBookmarksBtn.disabled = true; 
            if (this.bookmarksContainer.style.display === "block") 
                this.bookmarksContainer.style.display = "none"; 
        } 
    } else { 
        if (window.getComputedStyle(this.imageViewerContainerDiv).display === "block") { 
            this.imageViewerContainerDiv.style.display = "none"; 
        } 
 
        this.navigationbar.showThumbnailsBtn.classList.remove("activeNavigationbarBtn"); 
        if (!(this.navigationbar.showThumbnailsBtn.matches(":disabled"))) 
            this.navigationbar.showThumbnailsBtn.disabled = true; 
        if (this.thumbnailsContainer.style.display === "block") 
            this.thumbnailsContainer.style.display = "none"; 
 
        this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn"); 
        if (!(this.navigationbar.showBookmarksBtn.matches(":disabled"))) 
            this.navigationbar.showBookmarksBtn.disabled = true; 
        if (this.bookmarksContainer.style.display === "block") 
            this.bookmarksContainer.style.display = "none"; 
    } 
    this.updateContainers(); 
} 

Add the setDocument() Code

The following code checks if the loaded document is parsed, parses the document if needed, and sets the loaded document into the document viewer.

public setDocument(document: lt.Document.LEADDocument): void { 
   // See if we need to parse the document structure 
   if (document.structure.isParsed) { 
         this.finishSetDocument(document); 
   } 
   else 
         this.parseStructure(document); 
} 
 
private parseStructure(document: lt.Document.LEADDocument): void { 
   document.structure.parse() 
         .done((document: lt.Document.LEADDocument): void => { 
            this.finishSetDocument(document); 
         }) 
         .fail((): void => { 
            lt.LTHelper.log("Error parsing the document structure."); 
         }); 
} 
 
public finishSetDocument(document: lt.Document.LEADDocument): void { 
   if (this._documentViewer.view != null) { 
         // Use SVG Back Image 
         this._documentViewer.view.useSvgBackImage = true; 
   } 
 
   // Set the loaded document in the document viewer 
   this._documentViewer.setDocument(document); 
 
   // Update the UI 
   this.updateAppUIState(); 
   // Call onResize so the DIV sizes get updated 
   this.onResize(null); 
 
   // Fit page to display 
   this._documentViewer.commands.run(lt.Document.Viewer.DocumentViewerCommands.viewFitPage, null); 
} 

Call run() from the window.onLoad()

Add a call to the run() method in the window.onLoad() function.

window.onload = () => { 
   // If you have a JS license (LEADTOOLS.LIC.TXT) and key file (LEADTOOLS.LIC.KEY.TXT), you can use the code below to set your license 
   var licenseUrl = "./lic/LEADTOOLS.lic.txt"; 
   var developerKey = "ADD THE CONTENTS OF YOUR LEADTOOLS.lic.key.txt FILE"; 
 
   // If you are evaluating and do not have a JS license or key file, you can use the code below to set your license: 
   //var licenseUrl = "https://demo.leadtools.com/licenses/js/LEADTOOLSEVAL.txt"; 
   //var developerKey = "EVAL"; 
 
   lt.RasterSupport.setLicenseUri(licenseUrl, developerKey, function (setLicenseResult) { 
      // Check the status of the license   
      if (setLicenseResult.result) { 
            console.log("LEADTOOLS client license set successfully"); 
      } else { 
            var msg = "LEADTOOLS License is missing, invalid or expired\nError:\n"; 
            console.log(msg); 
            alert(msg); 
      } 
   }); 
 
   // Run the Document Viewer App 
   let app: DocumentViewerApp = new DocumentViewerApp(); 
   app.run(); 
} 

Run the Project

Before running the front-end Document Viewer, run the Document Service. The LEADTOOLS SDK installation provides three examples of the Document Service for the following platforms:

For instructions on how to set up and configure the Document Service, in the three platforms previously listed, refer to the steps in the Get Started with the Document Viewer Demo - HTML5 JavaScript tutorial.

For the purposes of this tutorial, the .NET Framework Document Service is used and it can be found here: \LEADTOOLS23\Examples\Document\JS\DocumentServiceDotNet\fx.

Once you have the back-end Document Service running, build and run the project in Visual Studio to host the web application on IIS Express with the selected browser.

The document viewer web application will run and load the sample PDF file. The thumbnails and bookmarks controls can be used to navigate the loaded document.

Document Viewer Running in Browser

Wrap-up

This tutorial showed how to initialize, load, and display a document in an ASP.NET TypeScript Document Viewer Web application.

See Also

Help Version 23.0.2024.5.22
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2024 LEAD Technologies, Inc. All Rights Reserved.

Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.