diff --git a/strudel_ex/gbif-app/.eslintrc.cjs b/strudel_ex/gbif-app/.eslintrc.cjs
new file mode 100644
index 00000000..7dbd9d18
--- /dev/null
+++ b/strudel_ex/gbif-app/.eslintrc.cjs
@@ -0,0 +1,18 @@
+module.exports = {
+ root: true,
+ env: { browser: true, es2020: true },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:react-hooks/recommended',
+ ],
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
+ parser: '@typescript-eslint/parser',
+ plugins: ['react-refresh'],
+ rules: {
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+}
diff --git a/strudel_ex/gbif-app/.gitignore b/strudel_ex/gbif-app/.gitignore
new file mode 100644
index 00000000..590784c8
--- /dev/null
+++ b/strudel_ex/gbif-app/.gitignore
@@ -0,0 +1,4 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+node_modules/
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/README.md b/strudel_ex/gbif-app/README.md
new file mode 100644
index 00000000..95a2aa03
--- /dev/null
+++ b/strudel_ex/gbif-app/README.md
@@ -0,0 +1,37 @@
+:warning: ***This library is in early-stage development. Check back soon for more updates!***
+
+# STRUDEL Kit
+
+STRUDEL Kit is a React-based JavaScript library for building scientific UIs based on the STRUDEL Design System and Task Flows. Visit [strudel.science](https://strudel.science) for more information about the STRUDEL project.
+
+This library provides a suite of templates to implement UIs for various different task flows common to the scientific domain. The app is intended to be used as a starting point for building out a web app that includes one or more of the task flows provided.
+
+## Getting Started
+
+Clone the strudel-kit repository from github:
+
+```
+git clone git@github.com:strudel-science/strudel-kit.git
+```
+
+Install the dependencies:
+
+```
+npm install
+```
+
+Start up the app:
+
+```
+npm start
+```
+
+Open [http://localhost:3000](http://localhost:3000) to view the app in the browser.
+
+Begin modifying the templates in `src/app`.
+
+## Learn More
+
+STRUDEL Kit is built on top of the Material UI (MUI) component library. [Read more about how to use MUI](https://mui.com/material-ui/getting-started/).
+
+[strudel.science](https://strudel.science)
diff --git a/strudel_ex/gbif-app/index.html b/strudel_ex/gbif-app/index.html
new file mode 100644
index 00000000..63d3a80a
--- /dev/null
+++ b/strudel_ex/gbif-app/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+ API Authentication Required
+
+
+ Enter the name of your API token (e.g. X-ApiToken) and the value of your API token (e.g. abc123).
+
+ {
+ setName(event.target.value);
+ }}
+ />
+ {
+ setValue(event.target.value);
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+ What's Next?
+ Add Task Flows
+
+ strudel add-taskflow my-taskflow -t explore-data
+
+
+
+
+
+
+
+ )
+}
+
+export default HomePage;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/[id].tsx b/strudel_ex/gbif-app/src/pages/science-info/[id].tsx
new file mode 100644
index 00000000..fde5a312
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/[id].tsx
@@ -0,0 +1,66 @@
+import { Box, Container, Paper, Stack, Typography } from '@mui/material';
+import React from 'react';
+import { useParams } from 'react-router-dom';
+import { PageHeader } from '../../components/PageHeader';
+import { useExploreData } from './_context/ContextProvider';
+
+/**
+ * Work in Progress:
+ *
+ * Detail view for a selected row from the` ` in the explore-data Task Flow.
+ */
+const DataDetailPage: React.FC = () => {
+ const {state, dispatch} = useExploreData();
+ const params = useParams();
+ const entity = state.data?.find((d) => {
+ if (params.id) {
+ return d[state.dataIdField].toString() === params.id.toString();
+ }
+ });
+ console.log(state);
+ console.log(entity);
+ const entityTitle = entity ? entity[state.columns[0].field] : 'Not Found';
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+
+
+
+
+
+ {state.columns[1].field}
+
+
+ {entity && entity[state.columns[1].field]}
+
+
+
+
+ More coming soon!
+
+
+
+
+ )
+}
+
+export default DataDetailPage;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_components/DataTablePanel.tsx b/strudel_ex/gbif-app/src/pages/science-info/_components/DataTablePanel.tsx
new file mode 100644
index 00000000..997c4af5
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_components/DataTablePanel.tsx
@@ -0,0 +1,77 @@
+import FilterListIcon from '@mui/icons-material/FilterList';
+import { Button, Paper, Stack, TextField, Typography } from '@mui/material';
+import { GridEventListener } from '@mui/x-data-grid';
+import React from 'react';
+import { DataGrid } from '@mui/x-data-grid';
+import { useExploreData } from '../_context/ContextProvider';
+import { setPreviewItem, setSearch } from '../_context/actions';
+
+interface DataTablePanelProps {
+ onToggleFiltersPanel: () => any
+}
+
+/**
+ * Main data table and its header section in the explore-data Task Flow.
+ * Columns are configured based on definitions.columns.main.
+ * Data in this table is filtered by the inputs in the filters panel.
+ */
+export const DataTablePanel: React.FC = (props) => {
+ const {state, dispatch} = useExploreData();
+
+ const handleRowClick: GridEventListener<'rowClick'> = (rowData) => {
+ dispatch(setPreviewItem(rowData.row));
+ };
+
+ const handleSearch: React.ChangeEventHandler = (evt) => {
+ dispatch(setSearch(evt.target.value));
+ };
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+ Entity List
+ }
+ onClick={props.onToggleFiltersPanel}
+ >
+ Filters
+
+
+
+ row[state.dataIdField]}
+ columns={state.columns}
+ disableColumnSelector
+ initialState={{
+ pagination: { paginationModel: { page: state.tablePage, pageSize: state.tablePageSize } }
+ }}
+ {...props}
+ onRowClick={handleRowClick}
+ sx={{
+ '& .MuiDataGrid-cell:focus-within': {
+ outline: 'none'
+ },
+ '& .MuiDataGrid-overlayWrapper': {
+ minHeight: '4rem'
+ }
+ }}
+ />
+
+ )
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_components/FiltersPanel.tsx b/strudel_ex/gbif-app/src/pages/science-info/_components/FiltersPanel.tsx
new file mode 100644
index 00000000..0c8a5a43
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_components/FiltersPanel.tsx
@@ -0,0 +1,103 @@
+import React from 'react';
+import { Filters } from '../../../components/Filters';
+import { FilterField } from '../../../components/FilterField';
+import { CheckboxList, CheckboxOption } from '../../../components/CheckboxList';
+import { useExploreData } from '../_context/ContextProvider';
+import { StrudelSlider } from '../../../components/StrudelSlider';
+import { setFilter } from '../_context/actions';
+import { FilterConfig, FilterOperator } from '../../../types/filters.types';
+import { Stack } from '@mui/material';
+import { DatePicker } from '@mui/x-date-pickers';
+
+interface FiltersPanelProps {
+ onClose: () => any
+}
+
+/**
+ * Main filters panel in the explore-data Task Flow.
+ * Filters are generated based on the configurations in definitions.filters.main.
+ * The input values will filter data in the main table.
+ */
+export const FiltersPanel: React.FC = (props) => {
+ const {state, dispatch} = useExploreData();
+
+ /**
+ * Render filter component based on the `filterType` from the filter definition.
+ */
+ const getFilterComponent = (filter: FilterConfig) => {
+ switch (filter.filterType) {
+ case 'CheckboxList': {
+ return (
+ dispatch(setFilter({ field: filter.field, value: values, operator: FilterOperator.CONTAINS_ONE_OF }))}
+ />
+ );
+ }
+ case 'Slider': {
+ return (
+ filter.field}
+ valueLabelDisplay="auto"
+ min={filter.props.min}
+ max={filter.props.max}
+ onChangeCommitted={(event, values) => dispatch(setFilter({ field: filter.field, value: values, operator: FilterOperator.BETWEEN_INCLUSIVE }))}
+ />
+ );
+ }
+ case 'date range': {
+ const currentDateRange = state.activeFilters.find((filter) => filter.field === filter.field);
+ const hasValue = currentDateRange && Array.isArray(currentDateRange.value) && currentDateRange.value.length === 2;
+ const currentMin = hasValue && Array.isArray(currentDateRange.value) ? currentDateRange.value[0] : null;
+ const currentMax = hasValue && Array.isArray(currentDateRange.value) ? currentDateRange.value[1] : null;
+
+ return (
+
+ dispatch(setFilter({ field: filter.field, value: [value, currentMax], operator: FilterOperator.BETWEEN_DATES_INCLUSIVE }))}
+ />
+ dispatch(setFilter({ field: filter.field, value: [currentMin, value], operator: FilterOperator.BETWEEN_DATES_INCLUSIVE }))}
+ />
+
+ );
+ }
+ }
+ }
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+ {state.filters.map((f, i) => (
+
+ ))}
+
+ )
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_components/PreviewPanel.tsx b/strudel_ex/gbif-app/src/pages/science-info/_components/PreviewPanel.tsx
new file mode 100644
index 00000000..cebdc320
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_components/PreviewPanel.tsx
@@ -0,0 +1,120 @@
+import React from 'react';
+import { Box, Button, IconButton, Link, Paper, Stack, Typography } from '@mui/material';
+import CloseIcon from '@mui/icons-material/Close';
+import { Link as RouterLink } from 'react-router-dom';
+import { LabelValueTable } from '../../../components/LabelValueTable';
+import { DataGrid } from '@mui/x-data-grid';
+import { useExploreData } from '../_context/ContextProvider';
+
+interface PreviewPanelProps {
+ onClose: () => any
+}
+
+/**
+ * Panel to show extra information about a row in a separate panel
+ * next to the ``.
+ */
+export const PreviewPanel: React.FC = (props) => {
+ const {state, dispatch} = useExploreData();
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+
+
+
+
+ {state.previewItem[state.columns[0].field]}
+
+
+
+
+ Row description, subtitle, or helper text.
+
+
+ Property Group 1
+
+
+
+ Property Group 2
+
+
+
+ Related Data
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+/**
+ * Placeholder columns for related data table
+ */
+const relatedColumns = [
+ {
+ field: 'id',
+ headerName: 'ID',
+ width: 50
+ },
+ {
+ field: 'attr1',
+ headerName: 'Attribute 1',
+ width: 100
+ },
+ {
+ field: 'attr2',
+ headerName: 'Attribute 2',
+ width: 100
+ },
+ {
+ field: 'attr3',
+ headerName: 'Attribute 3',
+ width: 100
+ },
+];
+
+/**
+ * Placeholder rows for related data table
+ */
+const emptyRows = Array(25).fill(0);
+const relatedRows = emptyRows.map((d, i) => {
+ return { id: i, attr1: 'value', attr2: 'value', attr3: 'value'}
+});
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_config/fetchDataToCSV.js b/strudel_ex/gbif-app/src/pages/science-info/_config/fetchDataToCSV.js
new file mode 100644
index 00000000..fc61f670
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_config/fetchDataToCSV.js
@@ -0,0 +1,46 @@
+import fetch from 'node-fetch';
+import { Parser } from 'json2csv';
+import fs from 'fs';
+
+const fetchGBIFData = async () => {
+ const url = 'https://api.gbif.org/v1/occurrence/search?';
+
+ try {
+ const response = await fetch(url);
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ const data = await response.json();
+
+ // Define the fields for CSV
+ const fields = [
+ { label: 'Name', value: 'scientificName' },
+ { label: 'Latitude', value: 'decimalLatitude' },
+ { label: 'Longitude', value: 'decimalLongitude' },
+ { label: 'Year', value: 'year' },
+ { label: 'Basis of Record', value: 'basisOfRecord' }
+ ];
+
+ // Transform data to match the required format
+ const transformedData = data.results.map((item) => ({
+ key: item.key,
+ scientificName: item.scientificName,
+ decimalLatitude: item.decimalLatitude,
+ decimalLongitude: item.decimalLongitude,
+ year: item.year,
+ basisOfRecord: item.basisOfRecord
+ }));
+
+ // Convert JSON to CSV
+ const json2csvParser = new Parser({ fields });
+ const csv = json2csvParser.parse(transformedData);
+
+ // Write CSV to file
+ fs.writeFileSync('data.csv', csv);
+ console.log('CSV file saved successfully');
+ } catch (error) {
+ console.error('Error fetching GBIF data:', error);
+ }
+};
+
+fetchGBIFData();
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_config/taskflow.config.ts b/strudel_ex/gbif-app/src/pages/science-info/_config/taskflow.config.ts
new file mode 100644
index 00000000..43240bbf
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_config/taskflow.config.ts
@@ -0,0 +1,73 @@
+import { ExploreDataConfig } from "./taskflow.types";
+
+export const taskflow: ExploreDataConfig = {
+ data: {
+ items: {
+ /**
+ * Source of the data for the initial list of items on the main page.
+ */
+ source: "https://api.gbif.org/v1/occurrence/search?",
+ /**
+ * Name of the field in the data that represents a unique identifier for each record.
+ */
+ idField: "key"
+ }
+ },
+ pages: {
+ index: {
+ /**
+ * Title to appear at the top of the main page.
+ */
+ title: "Solar System Explorer",
+ /**
+ * Text to appear underneath the title at the top of the main page.
+ */
+ description: "Explore data about the planets that orbit the Sun.",
+ /**
+ * List of column definition objects for the columns in the table on the main page.
+ */
+ tableColumns: [
+ {
+ field: "scientificName",
+ headerName: "Name",
+ width: 200
+ },
+ {
+ field: "decimalLatitude",
+ headerName: "Latitude",
+ width: 150
+ },
+ {
+ field: "decimalLongitude",
+ headerName: "Longitude",
+ width: 150
+ },
+ {
+ field: "year",
+ headerName: "Year",
+ width: 150
+ },
+ {
+ field: "basisOfRecord",
+ headerName: "Basis of Record",
+ width: 150
+ }
+ ],
+ /**
+ * List of filters to display on the main page and use to filter the main table data.
+ * Each filter has a definition object to determine how it renders and functions.
+ */
+ tableFilters: [
+ {
+ field: "Diameter",
+ displayName: "Diameter (km)",
+ filterType: "Slider",
+ props: {
+ min: 4000,
+ max: 150000
+ }
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_config/taskflow.types.ts b/strudel_ex/gbif-app/src/pages/science-info/_config/taskflow.types.ts
new file mode 100644
index 00000000..9f97c999
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_config/taskflow.types.ts
@@ -0,0 +1,33 @@
+import { GridColDef } from "@mui/x-data-grid"
+
+/**
+ * Type definitions for the Compare Data Task Flow config object
+ */
+export interface ExploreDataConfig {
+ /** Attributes that are used across the Task Flow */
+ properties?: Record,
+ data: {
+ items: {
+ source: string,
+ idField: string
+ },
+ [key: string]: {
+ source: string,
+ idField: string
+ }
+ },
+ /** Cool pages */
+ pages: {
+ index: {
+ title: string,
+ description: string,
+ tableColumns: GridColDef[],
+ tableFilters: {
+ field: string,
+ displayName: string,
+ filterType: 'CheckboxList' | 'Slider' | 'date range',
+ props?: object
+ }[]
+ }
+ }
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_context/ContextProvider.tsx b/strudel_ex/gbif-app/src/pages/science-info/_context/ContextProvider.tsx
new file mode 100644
index 00000000..32bc3199
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_context/ContextProvider.tsx
@@ -0,0 +1,142 @@
+import React, { useContext, useEffect } from 'react';
+import { ExploreDataAction, ExploreDataActionType, setData, setFilteredData } from './actions';
+import { DataFilter, FilterConfig } from '../../../types/filters.types';
+import { filterData } from '../../../utils/filters.utils';
+
+export interface ExploreDataState {
+ columns: any[];
+ count?: number;
+ data?: any[];
+ dataIdField: string;
+ filters: FilterConfig[];
+ filteredData?: any[];
+ activeFilters: DataFilter[];
+ filterValues?: any;
+ previewItem?: any;
+ searchTerm?: string;
+ showFiltersPanel?: boolean;
+ tablePage: number,
+ tablePageSize: number
+}
+
+/**
+ * ExploreDataProvider props are the same as the State except
+ * some of the required props in the State are optional props.
+ * These props have default values set in the initialState object.
+ */
+// interface ExploreDataProviderProps extends Omit {
+interface ExploreDataProviderProps extends Partial {
+ activeFilters?: DataFilter[];
+ columns?: any[];
+ tablePage?: number;
+ tablePageSize?: number;
+ children: React.ReactNode;
+}
+
+const ExploreDataContext = React.createContext<{state: ExploreDataState; dispatch: React.Dispatch} | undefined>(undefined);
+
+const initialState: ExploreDataState = {
+ data: [],
+ columns: [],
+ filters: [],
+ filterValues: {},
+ activeFilters: [],
+ dataIdField: 'id',
+ tablePage: 0,
+ tablePageSize: 25
+}
+
+const initState = (initialState: ExploreDataState, props: ExploreDataProviderProps) => {
+ const {children, ...rest} = props;
+ return {
+ ...initialState,
+ ...rest
+ }
+};
+
+function exploreDataReducer(state: ExploreDataState, action: ExploreDataAction): ExploreDataState {
+ switch (action.type) {
+ case ExploreDataActionType.SET_DATA: {
+ return {
+ ...state,
+ data: action.payload
+ }
+ }
+ case ExploreDataActionType.SET_SEARCH: {
+ return {
+ ...state,
+ searchTerm: action.payload
+ }
+ }
+ case ExploreDataActionType.SET_FILTERED_DATA: {
+ return {
+ ...state,
+ filteredData: action.payload
+ }
+ }
+ case ExploreDataActionType.SET_FILTER: {
+ console.log(action);
+ const filter = action.payload;
+ const existingIndex = state.activeFilters.findIndex((f) => f.field === filter.field);
+ const activeFilters = [...state.activeFilters];
+ if (existingIndex > -1) {
+ if (filter.value) {
+ activeFilters[existingIndex] = filter;
+ } else {
+ activeFilters.splice(existingIndex, 1);
+ }
+ } else if (filter.value) {
+ activeFilters.push(filter);
+ }
+ return {
+ ...state,
+ activeFilters
+ }
+ }
+ case ExploreDataActionType.SET_PREVIEW_ITEM: {
+ return {
+ ...state,
+ previewItem: action.payload
+ }
+ }
+ default: {
+ throw new Error(`Unhandled action type: ${action.type}`)
+ }
+ }
+}
+
+export const ExploreDataProvider: React.FC = (props) => {
+ const [state, dispatch] = React.useReducer(exploreDataReducer, initState(initialState, props));
+ const value = { state, dispatch };
+
+ useEffect(() => {
+ console.log(props.data);
+ dispatch(setData(props.data));
+ }, [props.data]);
+
+ useEffect(() => {
+ if (state.data) {
+ const filteredData = filterData(state.data, state.activeFilters, state.searchTerm);
+ dispatch(setFilteredData(filteredData));
+ }
+ }, [state.data, state.searchTerm, JSON.stringify(state.activeFilters)]);
+
+ return (
+
+ {props.children}
+
+ )
+}
+
+export const useExploreData = () => {
+ const context = useContext(ExploreDataContext)
+ if (context === undefined) {
+ throw new Error('useExploreData must be used within an ExploreDataProvider')
+ }
+ return context
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_context/actions.ts b/strudel_ex/gbif-app/src/pages/science-info/_context/actions.ts
new file mode 100644
index 00000000..a467cb94
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_context/actions.ts
@@ -0,0 +1,40 @@
+import { DataFilter } from '../../../types/filters.types';
+import { ExploreDataState } from './ContextProvider';
+
+export enum ExploreDataActionType {
+ SET_DATA = 'SET_DATA',
+ SET_SEARCH = 'SET_SEARCH',
+ SET_FILTERED_DATA = 'SET_FILTERED_DATA',
+ SET_FILTER = 'SET_FILTER',
+ SET_PREVIEW_ITEM = 'SET_PREVIEW_ITEM'
+}
+
+export interface ExploreDataAction {
+ type: ExploreDataActionType;
+ payload?: any;
+}
+
+export const setData = (data: ExploreDataState['data']): ExploreDataAction => ({
+ type: ExploreDataActionType.SET_DATA,
+ payload: data,
+});
+
+export const setSearch = (searchTerm: ExploreDataState['searchTerm']): ExploreDataAction => ({
+ type: ExploreDataActionType.SET_SEARCH,
+ payload: searchTerm,
+});
+
+export const setFilteredData = (data: ExploreDataState['filteredData']): ExploreDataAction => ({
+ type: ExploreDataActionType.SET_FILTERED_DATA,
+ payload: data,
+});
+
+export const setFilter = (filter: DataFilter): ExploreDataAction => ({
+ type: ExploreDataActionType.SET_FILTER,
+ payload: filter,
+});
+
+export const setPreviewItem = (rowItem: ExploreDataState['previewItem']): ExploreDataAction => ({
+ type: ExploreDataActionType.SET_PREVIEW_ITEM,
+ payload: rowItem,
+});
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/_layout.tsx b/strudel_ex/gbif-app/src/pages/science-info/_layout.tsx
new file mode 100644
index 00000000..444e7250
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/_layout.tsx
@@ -0,0 +1,38 @@
+import React from 'react';
+import { Box } from '@mui/material';
+import { Outlet } from 'react-router';
+import { ExploreDataProvider } from './_context/ContextProvider';
+import { TopBar } from '../../components/TopBar';
+import { useDataFromSource } from '../../utils/useDataFromSource';
+import { taskflow } from './_config/taskflow.config';
+
+/**
+ * Top-level wrapper for the explore-data Task Flow templates.
+ * Inner pages are rendered inside the `` component
+ */
+const ExploreDataLayout: React.FC = () => {
+ const entities = useDataFromSource(taskflow.data.items.source);
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default ExploreDataLayout;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info/index.tsx b/strudel_ex/gbif-app/src/pages/science-info/index.tsx
new file mode 100644
index 00000000..be0c4719
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info/index.tsx
@@ -0,0 +1,76 @@
+import { Box, Grid } from '@mui/material';
+import React, { useState } from 'react';
+import { FiltersPanel } from './_components/FiltersPanel';
+import { PreviewPanel } from './_components/PreviewPanel';
+import { DataTablePanel } from './_components/DataTablePanel';
+import { PageHeader } from '../../components/PageHeader';
+import { useExploreData } from './_context/ContextProvider';
+import { setPreviewItem } from './_context/actions';
+import { taskflow } from './_config/taskflow.config';
+
+/**
+ * Main explorer page in the explore-data Task Flow.
+ * This page includes the page header, filters panel,
+ * main table, and the table row preview panel.
+ */
+const DataExplorer: React.FC = () => {
+ const {state, dispatch} = useExploreData();
+ const [showFiltersPanel, setShowFiltersPanel] = useState(true);
+
+ const handleCloseFilters = () => {
+ setShowFiltersPanel(false);
+ };
+
+ const handleToggleFilters = () => {
+ setShowFiltersPanel(!showFiltersPanel);
+ }
+
+ const handleClosePreview = () => {
+ dispatch(setPreviewItem(null));
+ }
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+
+ {showFiltersPanel && (
+
+
+
+ )}
+
+
+
+ {state.previewItem && (
+
+
+
+ )}
+
+
+ )
+}
+
+const getMainColumnSize = (showFiltersPanel: boolean, showPreviewPanel: boolean) => {
+ if (!showFiltersPanel && !showPreviewPanel) {
+ return 12;
+ } else if (showFiltersPanel && !showPreviewPanel) {
+ return 10;
+ } else if (!showFiltersPanel && showPreviewPanel) {
+ return 8;
+ } else if (showFiltersPanel && showPreviewPanel) {
+ return 6;
+ }
+}
+
+export default DataExplorer;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_components/DataFilesPanel.tsx b/strudel_ex/gbif-app/src/pages/science-info2/_components/DataFilesPanel.tsx
new file mode 100644
index 00000000..4813657b
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_components/DataFilesPanel.tsx
@@ -0,0 +1,169 @@
+import DeleteIcon from '@mui/icons-material/Delete';
+import EditIcon from '@mui/icons-material/Edit';
+import { Button, Paper, Stack, Typography } from '@mui/material';
+import { GridActionsCellItem, GridColDef, GridRowParams } from '@mui/x-data-grid';
+import React, { useRef } from 'react';
+import { DataGrid } from '@mui/x-data-grid';
+
+/**
+ * Panel to display on the `` page of the contribute-data Task Flow.
+ * Shows a table with files that have been uploaded as part of the dataset.
+ */
+export const DataFilesPanel: React.FC = () => {
+ const fileInputRef = useRef(null);
+
+ const handleButtonClick = () => {
+ fileInputRef.current?.click();
+ };
+
+ const handleFileChange = async (event: React.ChangeEvent) => {
+ const files = event.target.files;
+ if (files) {
+ const file = files[0];
+ const formData = new FormData();
+ formData.append('file', file);
+
+ try {
+ const response = await fetch('https://your-upload-endpoint', {
+ method: 'POST',
+ body: formData,
+ });
+
+ if (response.ok) {
+ console.log('File uploaded successfully');
+ // Handle any additional logic after successful upload
+ } else {
+ console.error('Failed to upload file');
+ // Handle error scenarios
+ }
+ } catch (error) {
+ console.error('Error uploading file:', error);
+ // Handle error scenarios
+ }
+ }
+ };
+
+ return (
+
+
+
+ Dataset Files
+
+
+
+
+ row.id}
+ columns={columns}
+ disableColumnSelector
+ disableRowSelectionOnClick
+ sx={{
+ height: 'auto',
+ }}
+ />
+
+ );
+}
+
+/**
+ * Define files table data in-file for prototyping
+ */
+export const files = [
+ {
+ id: 0,
+ filename: 'xx',
+ type: 'csv',
+ size: '213 MB',
+ status: 'Uploading'
+ },
+ {
+ id: 1,
+ filename: 'xy',
+ type: 'csv',
+ size: '213 MB',
+ status: 'Uploading'
+ },
+ {
+ id: 2,
+ filename: 'xs',
+ type: 'csv',
+ size: '213 MB',
+ status: 'Uploading'
+ },
+ {
+ id: 3,
+ filename: 'xe',
+ type: 'tsv',
+ size: '2 GB',
+ status: 'Uploaded'
+ },
+ {
+ id: 4,
+ filename: 'xz',
+ type: 'txt',
+ size: '15 MB',
+ status: 'Uploaded'
+ }
+]
+
+/**
+ * Define column definitions in-file for prototyping
+ */
+const columns: GridColDef[] = [
+ {
+ field: 'filename',
+ headerName: 'File Name',
+ width: 150
+ },
+ {
+ field: 'type',
+ headerName: 'Type',
+ width: 100
+ },
+ {
+ field: 'size',
+ headerName: 'Size',
+ width: 100
+ },
+ {
+ field: 'status',
+ headerName: 'Status',
+ width: 100
+ },
+ {
+ field: 'actions',
+ headerName: 'Actions',
+ type: 'actions',
+ getActions: (params: GridRowParams) => [
+ } label="Edit" />,
+ } label="Delete" />
+ ],
+ flex: 1,
+ },
+];
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_components/DatasetView.tsx b/strudel_ex/gbif-app/src/pages/science-info2/_components/DatasetView.tsx
new file mode 100644
index 00000000..e27240fa
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_components/DatasetView.tsx
@@ -0,0 +1,95 @@
+import { Box, Paper, Stack, Typography } from '@mui/material';
+import { GridColDef } from '@mui/x-data-grid';
+import React from 'react';
+import { DataGrid } from '@mui/x-data-grid';
+import { LabelValueTable } from '../../../components/LabelValueTable';
+import { files } from './DataFilesPanel';
+
+/**
+ * Panel to display data entered from the `` and the `` from
+ * the previous step in contribute-data (not currently hooked together).
+ * This component is rendered as part of the `` page.
+ */
+export const DatasetView: React.FC = () => {
+ return (
+
+
+
+ My Dataset
+
+
+
+
+
+
+
+ Dataset Files
+
+ row.id}
+ columns={columns}
+ disableColumnSelector
+ disableRowSelectionOnClick
+ />
+
+
+
+ );
+}
+
+/**
+ * Define column definitions in-file for prototyping
+ */
+const columns: GridColDef[] = [
+ {
+ field: 'filename',
+ headerName: 'File Name',
+ width: 150
+ },
+ {
+ field: 'type',
+ headerName: 'Type',
+ width: 100
+ },
+ {
+ field: 'size',
+ headerName: 'Size',
+ width: 100
+ },
+ {
+ field: 'status',
+ headerName: 'Status',
+ flex: 1,
+ },
+];
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_components/MetadataPanel.tsx b/strudel_ex/gbif-app/src/pages/science-info2/_components/MetadataPanel.tsx
new file mode 100644
index 00000000..c95fd57c
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_components/MetadataPanel.tsx
@@ -0,0 +1,171 @@
+import { Box, FormControl, FormHelperText, InputLabel, List, ListItem, MenuItem, Paper, Select, SelectChangeEvent, Stack, TextField, Typography } from '@mui/material';
+import { DatePicker } from '@mui/x-date-pickers';
+import dayjs from 'dayjs';
+import React, { useState } from 'react';
+
+/**
+ * Panel for entering metadata about the new dataset in the contribute-data Task Flow.
+ * Data from this panel would then display in the in the next step (not currently hooked together).
+ */
+export const MetadataPanel: React.FC = () => {
+ const [category, setCategory] = useState();
+ const [startDate, setStartDate] = useState(null);
+ const [endDate, setEndDate] = useState(null);
+
+ const handleCategoryChange = (event: SelectChangeEvent) => {
+ setCategory(event.target.value);
+ };
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+
+ Metadata
+
+
+
+
+
+ Overview
+ Dates
+ Locations
+ Methods
+
+
+
+
+
+ Overview
+
+
+
+ Category
+
+ Select the category most closely associeted with your dataset.
+
+
+
+
+ Dates
+
+ setStartDate(value)}
+ />
+ setEndDate(value)}
+ />
+
+
+
+ Contacts
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_components/ValidationChecks.tsx b/strudel_ex/gbif-app/src/pages/science-info2/_components/ValidationChecks.tsx
new file mode 100644
index 00000000..c74cb4a9
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_components/ValidationChecks.tsx
@@ -0,0 +1,132 @@
+import { Box, LinearProgress, Paper, Stack, Typography } from '@mui/material';
+import React from 'react';
+import { LinearMeter } from '../../../components/LinearMeter';
+import { useContributeData } from '../_context/ContextProvider';
+
+/**
+ * Panel to display information and status of validation checks in the contribute-data Task Flow.
+ * This component is rendered as part of the `` page.
+ */
+export const ValidationChecks: React.FC = () => {
+ const { state, dispatch } = useContributeData();
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+
+ Validation Checks
+
+
+ Running the dataset metadata and datafile against our standard set of metadata, data and congruency checks helps to validate the data and find potential issues with format or compatibility.
+
+
+ These checks help to improve discoverability and reusability of your research data, and also fastens the process of verifying the data for the public release.
+
+
+ We run checks to gauge the following aspects of uploaded dataset.
+
+ {state.runningChecks && (
+
+
+
+ Running validation checks
+
+
+ )}
+ {!state.runningChecks && state.checksComplete && (
+
+
+
+
+
+ Passed: 22 checks
+
+
+ Warning: 2 checks
+
+
+
+
+ )}
+
+
+
+ Findability
+
+ {!state.runningChecks && state.checksComplete && (
+
+
+
+ )}
+
+
+ Determine how easy it is for someone to find your dataset
+
+ {state.runningChecks && Test}
+
+
+
+
+ Accessibility
+
+ {!state.runningChecks && state.checksComplete && (
+
+
+
+ )}
+
+
+ Determine how easy it is for someone to access your dataset
+
+
+
+
+
+ Interoperability
+
+ {!state.runningChecks && state.checksComplete && (
+
+
+
+ )}
+
+
+ Determine how easy it is to make use of the information in your dataset
+
+
+
+
+
+ Reusability
+
+ {!state.runningChecks && state.checksComplete && (
+
+
+
+ )}
+
+
+ Determine how easy it is for someone to reuse your dataset
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_config/taskflow.config.ts b/strudel_ex/gbif-app/src/pages/science-info2/_config/taskflow.config.ts
new file mode 100644
index 00000000..f84b3e06
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_config/taskflow.config.ts
@@ -0,0 +1,81 @@
+import { ContributeDataConfig } from "./taskflow.types";
+
+export const taskflow: ContributeDataConfig = {
+ data: {
+ datasets: {
+ /**
+ * Source of the data for the initial list of datasets on the portal page.
+ */
+ source: "default/contribute-data/contributor_datasets.json",
+ /**
+ * Name of the field in the data that represents a unique identifier for each record.
+ */
+ idField: "id"
+ }
+ },
+ pages: {
+ index: {
+ /**
+ * Title to appear at the top of the register page.
+ */
+ title: "Register as a data contributor"
+ },
+ portal: {
+ /**
+ * Title to appear at the top of the portal page.
+ */
+ title: "Your Dataset Uploads",
+ /**
+ * List of column definition objects for the columns in the table on the portal page.
+ */
+ tableColumns: [
+ {
+ field: "title",
+ headerName: "Dataset Title",
+ width: 200
+ },
+ {
+ field: "category",
+ headerName: "Category",
+ width: 200
+ },
+ {
+ field: "summary",
+ headerName: "Summary",
+ width: 200
+ },
+ {
+ field: "doi",
+ headerName: "DOI",
+ width: 200
+ },
+ {
+ field: "publication_date",
+ headerName: "Created Date",
+ width: 200
+ },
+ {
+ field: "status",
+ headerName: "Status",
+ width: 200
+ }
+ ]
+ },
+ new: {
+ /**
+ * Title to appear at the top of the new dataset page.
+ */
+ title: "Upload a new dataset",
+ /**
+ * Text to appear underneath the title at the top of the new dataset page.
+ */
+ description: "Description of this app section"
+ },
+ review: {
+ /**
+ * Title to appear at the top of the review page.
+ */
+ title: "Review your new dataset"
+ }
+ }
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_config/taskflow.types.ts b/strudel_ex/gbif-app/src/pages/science-info2/_config/taskflow.types.ts
new file mode 100644
index 00000000..e6fdfd11
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_config/taskflow.types.ts
@@ -0,0 +1,36 @@
+import { GridColDef } from "@mui/x-data-grid"
+
+/**
+ * Type definitions for the Compare Data Task Flow config object
+ */
+export interface ContributeDataConfig {
+ /** Attributes that are used across the Task Flow */
+ properties?: Record,
+ data: {
+ datasets: {
+ source: string,
+ idField: string
+ },
+ [key: string]: {
+ source: string,
+ idField: string
+ }
+ },
+ /** Cool pages */
+ pages: {
+ index: {
+ title: string,
+ },
+ portal: {
+ title: string,
+ tableColumns: GridColDef[]
+ },
+ new: {
+ title: string,
+ description: string
+ },
+ review: {
+ title: string,
+ },
+ }
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_context/ContextProvider.tsx b/strudel_ex/gbif-app/src/pages/science-info2/_context/ContextProvider.tsx
new file mode 100644
index 00000000..348f8dd5
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_context/ContextProvider.tsx
@@ -0,0 +1,69 @@
+import React, { useContext } from 'react';
+import { ContributeDataAction, ContributeDataActionType } from './actions';
+
+export interface DataFilter {
+ field: string;
+ value: string | number | any[] | null;
+ operator: string;
+}
+
+export interface ContributeDataState {
+ runningChecks?: boolean;
+ checksComplete?: boolean;
+}
+
+/**
+ * ContributeDataProvider props are the same as the State except
+ * some of the required props in the State are optional props.
+ * These props have default values set in the initialState object.
+ */
+interface ContributeDataProviderProps extends Omit {
+ children: React.ReactNode;
+}
+
+const ContributeDataContext = React.createContext<{state: ContributeDataState; dispatch: React.Dispatch} | undefined>(undefined);
+
+const initialState: ContributeDataState = {
+ runningChecks: false,
+ checksComplete: false,
+}
+
+function contributingDataReducer(state: ContributeDataState, action: ContributeDataAction): ContributeDataState {
+ switch (action.type) {
+ case ContributeDataActionType.RUN_CHECKS: {
+ return {
+ ...state,
+ runningChecks: true
+ }
+ }
+ case ContributeDataActionType.FINISH_CHECKS: {
+ return {
+ ...state,
+ runningChecks: false,
+ checksComplete: true,
+ }
+ }
+ default: {
+ throw new Error(`Unhandled action type: ${action.type}`)
+ }
+ }
+}
+
+export const ContributeDataProvider: React.FC = (props) => {
+ const [state, dispatch] = React.useReducer(contributingDataReducer, initialState);
+ const value = { state, dispatch };
+
+ return (
+
+ {props.children}
+
+ )
+}
+
+export const useContributeData = () => {
+ const context = useContext(ContributeDataContext)
+ if (context === undefined) {
+ throw new Error('useContributeData must be used within an ContributeDataProvider')
+ }
+ return context
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_context/actions.ts b/strudel_ex/gbif-app/src/pages/science-info2/_context/actions.ts
new file mode 100644
index 00000000..8885a659
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_context/actions.ts
@@ -0,0 +1,17 @@
+export enum ContributeDataActionType {
+ RUN_CHECKS = 'RUN_CHECKS',
+ FINISH_CHECKS = 'FINISH_CHECKS',
+}
+
+export interface ContributeDataAction {
+ type: ContributeDataActionType;
+ payload?: any;
+}
+
+export const runChecks = (): ContributeDataAction => ({
+ type: ContributeDataActionType.RUN_CHECKS,
+});
+
+export const finishChecks = (): ContributeDataAction => ({
+ type: ContributeDataActionType.FINISH_CHECKS,
+});
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_context/utils.ts b/strudel_ex/gbif-app/src/pages/science-info2/_context/utils.ts
new file mode 100644
index 00000000..77b827b6
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_context/utils.ts
@@ -0,0 +1,113 @@
+import dayjs from "dayjs";
+import { DataFilter } from "./ContextProvider";
+
+export const filterBySearchText = (allData: any[], searchText?: string) => {
+ let filteredData = allData;
+ if (searchText) {
+ filteredData = allData.filter((d) => {
+ const rowString = JSON.stringify(d).toLowerCase();
+ return rowString.indexOf(searchText.toLowerCase()) > -1;
+ });
+ }
+ return filteredData;
+};
+
+export const filterByDataFilters = (allData: any[], filters: DataFilter[]) => {
+ let filteredData = allData;
+ if (filters.length > 0) {
+ filteredData = allData.filter((d) => {
+ let include = true;
+ /**
+ * All filters have to be matched for a row to be included in the filtered data
+ */
+ filters.forEach((f) => {
+ let match = false;
+ if (include === true) {
+ switch (f.operator) {
+ case 'contains': {
+ if (d[f.field].indexOf(f.value) > -1) {
+ match = true;
+ }
+ break;
+ }
+ case 'contains one of': {
+ if (Array.isArray(f.value)) {
+ f.value.forEach((v) => {
+ if (!match) {
+ if (d[f.field].indexOf(v) > -1) {
+ match = true;
+ }
+ }
+ });
+ }
+ break;
+ }
+ case 'equals one of': {
+ if (Array.isArray(f.value)) {
+ f.value.forEach((v) => {
+ if (!match) {
+ if (d[f.field] === v) {
+ match = true;
+ }
+ }
+ });
+ }
+ break;
+ }
+ case 'range': {
+ if (Array.isArray(f.value)) {
+ const min = f.value[0];
+ const max = f.value[1];
+ if (d[f.field] >= min && d[f.field] <= max) {
+ match = true;
+ }
+ }
+ break;
+ }
+ case 'date range': {
+ if (
+ typeof d[f.field] === 'string'
+ && Array.isArray(f.value)
+ && f.value[0]
+ && f.value[1]
+ ) {
+ console.log(d[f.field]);
+ console.log(f.value);
+ console.log(dayjs(d[f.field]));
+ const dateValue = dayjs(d[f.field]);
+ if (dateValue.isAfter(f.value[0]) && dateValue.isBefore(f.value[1])) {
+ console.log('match');
+ match = true;
+ }
+ } else {
+ match = true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (!match) include = false;
+ });
+ return include;
+ });
+ }
+ return filteredData;
+};
+
+export const filterData = (allData: any[], filters: DataFilter[], searchText?: string) => {
+ const filteredByText = filterBySearchText(allData, searchText);
+ const filteredByTextAndDataFilters = filterByDataFilters(filteredByText, filters);
+ return filteredByTextAndDataFilters;
+}
+
+export const initSliderTicks = (ticks: number | null, domain: number[], scale?: any) => {
+ if (ticks === 2) {
+ return domain;
+ } else if (ticks !== null) {
+ return scale.ticks(ticks);
+ } else {
+ return;
+ }
+};
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/_layout.tsx b/strudel_ex/gbif-app/src/pages/science-info2/_layout.tsx
new file mode 100644
index 00000000..50205b28
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/_layout.tsx
@@ -0,0 +1,26 @@
+import { Box } from '@mui/material';
+import React from 'react';
+import { Outlet } from 'react-router-dom';
+import { TopBar } from '../../components/TopBar';
+import { ContributeDataProvider } from './_context/ContextProvider';
+
+/**
+ * Top-level wrapper for the contribute-data Task Flow templates.
+ * Inner pages are rendered inside the `` component
+ */
+const ContributeDataLayout: React.FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default ContributeDataLayout;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/index.tsx b/strudel_ex/gbif-app/src/pages/science-info2/index.tsx
new file mode 100644
index 00000000..2d087afb
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/index.tsx
@@ -0,0 +1,86 @@
+import { Box, Button, Container, Link, Paper, Stack, TextField, Typography } from '@mui/material';
+import React from 'react';
+import { Link as RouterLink } from 'react-router-dom';
+import { LabelValueTable } from '../../components/LabelValueTable';
+import { taskflow } from './_config/taskflow.config';
+
+/**
+ * Initial page for registering as a contributor in the contribute-data Task Flow.
+ * After submitting, users are directed to the ``.
+ */
+const Register: React.FC = () => {
+ return (
+
+
+
+
+ {taskflow.pages.index.title}
+
+
+
+
+
+
+ Description
+
+ {/* TODO: Make it easier to render text as multiple paragraphs (maybe support markdown in certain components) */}
+
+
+ Explain data contribution process in brief, with links to proper documentation of steps, requirements and guidelines if any. Link to documentation
+
+
+
+
+
+ Registration Form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default Register;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/new.tsx b/strudel_ex/gbif-app/src/pages/science-info2/new.tsx
new file mode 100644
index 00000000..a9801c32
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/new.tsx
@@ -0,0 +1,63 @@
+import { Box, Button, Container, Grid, Link, Stack, Typography } from '@mui/material';
+import React from 'react';
+import { Link as RouterLink } from 'react-router-dom';
+import { DataFilesPanel } from './_components/DataFilesPanel';
+import { MetadataPanel } from './_components/MetadataPanel';
+import { taskflow } from './_config/taskflow.config';
+
+/**
+ * Page for entering information about a new dataset in the contribute-data Task Flow.
+ * Includes the `` and `` for adding input data.
+ */
+const NewDataset: React.FC = () => {
+ return (
+
+
+
+
+
+ {taskflow.pages.new.title}
+
+
+ {taskflow.pages.new.description}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default NewDataset;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/portal.tsx b/strudel_ex/gbif-app/src/pages/science-info2/portal.tsx
new file mode 100644
index 00000000..40158ba2
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/portal.tsx
@@ -0,0 +1,70 @@
+import DeleteIcon from '@mui/icons-material/Delete';
+import EditIcon from '@mui/icons-material/Edit';
+import { Button, Container, Link, Paper, Stack, Typography } from '@mui/material';
+import { GridActionsCellItem, GridColDef, GridRowParams } from '@mui/x-data-grid';
+import React from 'react';
+import { Link as RouterLink } from 'react-router-dom';
+import { DataGrid } from '@mui/x-data-grid';
+import { useDataFromSource } from '../../utils/useDataFromSource';
+import { taskflow } from './_config/taskflow.config';
+
+/**
+ * Page to show a contributor's uploads in the contribute-data Task Flow.
+ * Also allows users to start a new dataset which sends them to the `` component.
+ */
+const ContributorPortal: React.FC = () => {
+ const datasets = useDataFromSource(taskflow.data.datasets.source);
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+
+
+ {taskflow.pages.portal.title}
+
+
+
+
+
+
+ row[taskflow.data.datasets.idField]}
+ columns={columns}
+ disableColumnSelector
+ disableRowSelectionOnClick
+ />
+
+
+
+ );
+}
+
+/**
+ * Define column definitions in-file for prototyping
+ */
+const columns: GridColDef[] = [
+ ...taskflow.pages.portal.tableColumns,
+ {
+ field: 'actions',
+ headerName: 'Actions',
+ type: 'actions',
+ getActions: (params: GridRowParams) => [
+ } label="Edit" />,
+ } label="Delete" />
+ ],
+ flex: 1,
+ },
+];
+
+export default ContributorPortal;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/pages/science-info2/review.tsx b/strudel_ex/gbif-app/src/pages/science-info2/review.tsx
new file mode 100644
index 00000000..2812d0c6
--- /dev/null
+++ b/strudel_ex/gbif-app/src/pages/science-info2/review.tsx
@@ -0,0 +1,116 @@
+import CloseIcon from '@mui/icons-material/Close';
+import { Alert, Box, Button, Collapse, Container, Grid, IconButton, Link, Stack, Typography } from '@mui/material';
+import React, { useState } from 'react';
+import { Link as RouterLink } from 'react-router-dom';
+import { DatasetView } from './_components/DatasetView';
+import { ValidationChecks } from './_components/ValidationChecks';
+import { useContributeData } from './_context/ContextProvider';
+import { finishChecks, runChecks } from './_context/actions';
+import { taskflow } from './_config/taskflow.config';
+
+/**
+ * Page to review a new dataset before submitting it in the contribute-data Task Flow.
+ * Users can see read-only data in the ``, go back to editing, or run checks
+ * against their uploaded dataset and see validation in the `` component.
+ */
+const ReviewDataset: React.FC = () => {
+ const [alertOpen, setAlertOpen] = useState(true);
+ const { state, dispatch } = useContributeData();
+
+ /**
+ * Simulate the checks being run using an external service
+ */
+ const startRunChecks = () => {
+ dispatch(runChecks());
+ setTimeout(() => {
+ dispatch(finishChecks());
+ }, 5000)
+ }
+
+ /**
+ * Content to render on the page for this component
+ */
+ return (
+
+
+ {
+ setAlertOpen(false);
+ }}
+ >
+
+
+ }
+ sx={{
+ paddingLeft: 3,
+ paddingRight: 3,
+ }}
+ >
+ Your dataset edits have been saved.
+
+
+
+
+
+
+
+ {taskflow.pages.review.title}
+
+
+
+
+
+
+
+
+
+
+
+ {state.checksComplete && (
+
+
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ReviewDataset;
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/theme.tsx b/strudel_ex/gbif-app/src/theme.tsx
new file mode 100644
index 00000000..27401d8e
--- /dev/null
+++ b/strudel_ex/gbif-app/src/theme.tsx
@@ -0,0 +1,154 @@
+import { PaletteMode, createTheme } from "@mui/material";
+import type {} from '@mui/x-data-grid/themeAugmentation';
+import { config } from "../strudel.config";
+
+/**
+ * MUI Theme object for setting app-wide and component-wide styles.
+ * Specify colors, spacing, fonts, and more.
+ * Learn more about theme options: https://mui.com/material-ui/customization/theming/
+ */
+export const theme = createTheme({
+ /** Color palette to use throughout the app */
+ palette: {
+ mode: config.theme.mode as PaletteMode || 'light',
+ background: {
+ default: config.theme.backgroundColor || '#F5F5F6',
+ paper: config.theme.paperBackgroundColor || '#fff',
+ },
+ primary: {
+ main: config.theme.primaryColor || '#1976d2',
+ // light: '#42a5f5',
+ // dark: '#1565c0',
+ // contrastText: '#fff',
+ },
+ secondary: {
+ main: config.theme.secondaryColor || '#9c27b0',
+ // light: '#ba68c8',
+ // dark: '#7b1fa2',
+ // contrastText: '#fff',
+ },
+ info: {
+ main: '#0288d1',
+ light: '#03a9f4',
+ dark: '#01579b',
+ contrastText: '#fff',
+ },
+ success: {
+ main: '#2e7d32',
+ light: '#4caf50',
+ dark: '#1b5e20',
+ contrastText: '#fff',
+ },
+ warning: {
+ main: '#ed6c02',
+ light: '#ff9800',
+ dark: '#e65100',
+ contrastText: '#fff',
+ },
+ error: {
+ main: '#d32f2f',
+ light: '#ef5350',
+ dark: '#c62828',
+ contrastText: '#fff',
+ },
+ neutral: {
+ main: '#DADADA',
+ light: '#e0e0e0',
+ dark: '#828282'
+ },
+ common: {
+ black: '#000',
+ white: '#fff',
+ },
+ grey: {
+ 50: '#ddd',
+ 500: '#999',
+ 900: '#444'
+ }
+ },
+ /** Control the default border radius */
+ shape: {
+ borderRadius: 4,
+ },
+ /** Control the font, size, and font weights */
+ typography: {
+ htmlFontSize: 16,
+ fontFamily: `${config.theme.fontFamily}, "Helvetica", "Verdana", "Arial", sans-serif`,
+ fontSize: 14,
+ fontWeightLight: 300,
+ fontWeightRegular: 400,
+ fontWeightMedium: 500,
+ fontWeightBold: 700,
+ },
+ /** Default options for MUI components used throughout the app */
+ components: {
+ /**
+ * Example component customization.
+ * Learn more at https://mui.com/material-ui/customization/theme-components/
+ *
+ MuiComponentName: {
+ defaultProps: {
+ // Put prop names and values here
+ },
+ styleOverrides: {
+ root: {
+ // Put styles here
+ }
+ },
+ // Create new custom variants of certain components
+ variants: [
+ {
+ props: { variant: '' },
+ style: {
+ // Put styles here
+ },
+ },
+ ],
+ },
+ *
+ */
+ MuiButton: {
+ variants: [
+ {
+ props: { color: 'neutral' },
+ style: {
+ backgroundColor: 'white',
+ borderColor: '#bdbdbd',
+ color: '#757575'
+ },
+ },
+ ],
+ },
+ MuiLink: {
+ styleOverrides: {
+ root: {
+ textDecoration: 'none'
+ }
+ }
+ },
+ MuiStack: {
+ defaultProps: {
+ spacing: 2
+ },
+ },
+ MuiDataGrid: {
+ styleOverrides: {
+ root: {
+ border: 0,
+ '& .MuiDataGrid-cell:focus-within': {
+ outline: 'none'
+ },
+ '& .MuiDataGrid-overlayWrapper': {
+ minHeight: '4rem'
+ },
+ '& .MuiDataGrid-columnHeaderTitle': {
+ color: 'grey.900',
+ fontSize: '0.85rem',
+ fontWeight: 'bold',
+ textTransform: 'uppercase',
+ },
+ }
+ }
+ }
+ },
+});
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/types/filters.types.tsx b/strudel_ex/gbif-app/src/types/filters.types.tsx
new file mode 100644
index 00000000..b41d34c1
--- /dev/null
+++ b/strudel_ex/gbif-app/src/types/filters.types.tsx
@@ -0,0 +1,29 @@
+export interface DataFilter {
+ field: string;
+ value: string | number | any[] | null;
+ operator: string;
+}
+
+export interface FilterConfig {
+ field: string;
+ displayName: string;
+ filterType: string;
+ group?: string;
+ tooltip?: string;
+ props?: any;
+}
+
+export enum FilterOperator {
+ CONTAINS = 'CONTAINS',
+ CONTAINS_ONE_OF = 'CONTAINS_ONE_OF',
+ EQUALS = 'EQUALS',
+ EQUALS_ONE_OF = 'EQUALS_ONE_OF',
+ BETWEEN_INCLUSIVE = 'BETWEEN_INCLUSIVE',
+ BETWEEN_DATES_INCLUSIVE = 'BETWEEN_DATES_INCLUSIVE',
+}
+
+export interface DataCard {
+ title: string;
+ content?: string;
+ tags?: string;
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/utils/filters.utils.ts b/strudel_ex/gbif-app/src/utils/filters.utils.ts
new file mode 100644
index 00000000..413074ba
--- /dev/null
+++ b/strudel_ex/gbif-app/src/utils/filters.utils.ts
@@ -0,0 +1,119 @@
+import dayjs from "dayjs";
+import { DataFilter, FilterOperator } from "../types/filters.types";
+
+export const filterBySearchText = (allData: any[], searchText?: string) => {
+ let filteredData = allData;
+ if (searchText) {
+ filteredData = allData.filter((d) => {
+ const rowString = JSON.stringify(d).toLowerCase();
+ return rowString.indexOf(searchText.toLowerCase()) > -1;
+ });
+ }
+ return filteredData;
+};
+
+export const filterByDataFilters = (allData: any[], filters: DataFilter[]) => {
+ let filteredData = allData;
+ if (filters.length > 0) {
+ filteredData = allData.filter((d) => {
+ let include = true;
+ /**
+ * All filters have to be matched for a row to be included in the filtered data
+ */
+ filters.forEach((f) => {
+ let match = false;
+ if (include === true) {
+ switch (f.operator) {
+ case FilterOperator.CONTAINS: {
+ if (d[f.field].indexOf(f.value) > -1) {
+ match = true;
+ }
+ break;
+ }
+ case FilterOperator.CONTAINS_ONE_OF: {
+ if (Array.isArray(f.value)) {
+ f.value.forEach((v) => {
+ if (!match) {
+ if (Array.isArray(d[f.field])) {
+ if (d[f.field].indexOf(v) > -1) {
+ match = true;
+ }
+ } else {
+ if (d[f.field] === v) {
+ match = true;
+ }
+ }
+
+ }
+ });
+ }
+ break;
+ }
+ case FilterOperator.EQUALS_ONE_OF: {
+ console.log(f.value);
+ console.log(d[f.field]);
+ if (Array.isArray(f.value)) {
+ f.value.forEach((v) => {
+ if (!match) {
+ if (d[f.field] === v) {
+ match = true;
+ }
+ }
+ });
+ }
+ break;
+ }
+ case FilterOperator.BETWEEN_INCLUSIVE: {
+ if (Array.isArray(f.value)) {
+ const min = f.value[0];
+ const max = f.value[1];
+ if (d[f.field] >= min && d[f.field] <= max) {
+ match = true;
+ }
+ }
+ break;
+ }
+ case FilterOperator.BETWEEN_DATES_INCLUSIVE: {
+ if (
+ typeof d[f.field] === 'string'
+ && Array.isArray(f.value)
+ && f.value[0]
+ && f.value[1]
+ ) {
+ const dateValue = dayjs(d[f.field]);
+ if (dateValue.isAfter(f.value[0]) && dateValue.isBefore(f.value[1])) {
+ console.log('match');
+ match = true;
+ }
+ } else {
+ match = true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (!match) include = false;
+ });
+ return include;
+ });
+ }
+ return filteredData;
+};
+
+export const filterData = (allData: any[], filters: DataFilter[], searchText?: string) => {
+ const filteredByText = filterBySearchText(allData, searchText);
+ const filteredByTextAndDataFilters = filterByDataFilters(filteredByText, filters);
+ return filteredByTextAndDataFilters;
+}
+
+export const initSliderTicks = (ticks: number | null, domain: number[], scale?: any) => {
+ if (ticks === 2) {
+ return domain;
+ } else if (ticks !== null) {
+ return scale.ticks(ticks);
+ } else {
+ return;
+ }
+};
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/utils/string.utils.ts b/strudel_ex/gbif-app/src/utils/string.utils.ts
new file mode 100644
index 00000000..06517ddf
--- /dev/null
+++ b/strudel_ex/gbif-app/src/utils/string.utils.ts
@@ -0,0 +1,3 @@
+export const removeExtraSlashes = (str: string) => {
+ return str.replace(/([^:]\/)\/+/g, "$1")
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/utils/useDataFromSource.tsx b/strudel_ex/gbif-app/src/utils/useDataFromSource.tsx
new file mode 100644
index 00000000..83d9f126
--- /dev/null
+++ b/strudel_ex/gbif-app/src/utils/useDataFromSource.tsx
@@ -0,0 +1,58 @@
+import * as d3 from 'd3-fetch';
+import { useAppState } from '../context/ContextProvider';
+import { useEffect, useState } from 'react';
+import { openApiModal } from '../context/actions';
+
+/**
+ * Get data from a local source or REST API.
+ * Include the local basename if pulling from a local source.
+ */
+export const useDataFromSource = (dataSource: string): any => {
+ const { dispatch } = useAppState();
+ const [data, setData] = useState();
+ const basename = document.querySelector('base')?.getAttribute('href') ?? '';
+
+ useEffect(() => {
+ const fetchData = async () => {
+ const fileExtension = dataSource.split('.').pop();
+ const isExternal = dataSource.startsWith('http');
+ const dataSourcePath = isExternal ? dataSource : `${basename}/data/${dataSource}`;
+ let data: any = [];
+ if (fileExtension === 'csv') {
+ data = await d3.csv(dataSourcePath);
+ } else if (fileExtension === 'tsv') {
+ data = await d3.tsv(dataSourcePath);
+ } else if (fileExtension === 'json' || isExternal) {
+ let headers = new Headers();
+ const apiTokenName = localStorage.getItem('apiTokenName');
+ const apiTokenValue = localStorage.getItem('apiTokenValue');
+ if (apiTokenName && apiTokenValue) {
+ headers = new Headers({
+ [apiTokenName]: apiTokenValue,
+ });
+ }
+ try {
+ const response = await fetch(dataSourcePath, {
+ headers: headers,
+ method: 'GET',
+ redirect: 'follow',
+ });
+ if (!response.ok) {
+ console.log(response);
+ dispatch(openApiModal());
+ throw new Error("unable to fetch");
+ }
+ const res = await response.json();
+ data = res.results
+ console.log(data)
+ } catch (e) {
+ console.log(e);
+ }
+ }
+ setData(data);
+ }
+ fetchData();
+ }, []);
+
+ return data;
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/utils/useInterval.tsx b/strudel_ex/gbif-app/src/utils/useInterval.tsx
new file mode 100644
index 00000000..32dc0c2c
--- /dev/null
+++ b/strudel_ex/gbif-app/src/utils/useInterval.tsx
@@ -0,0 +1,25 @@
+import React, { useEffect, useRef } from 'react';
+
+type IntervalFunction = () => ( unknown | void )
+
+export const useInterval = (callback: IntervalFunction, delay: number) => {
+
+ const savedCallback = useRef( null )
+
+ // Remember the latest callback.
+ useEffect( () => {
+ savedCallback.current = callback
+ } )
+
+ // Set up the interval.
+ useEffect( () => {
+ function tick() {
+ if ( savedCallback.current !== null ) {
+ savedCallback.current()
+ }
+ }
+ const id = setInterval( tick, delay )
+ return () => clearInterval( id )
+
+ }, [ delay ] )
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/src/vite-env.d.ts b/strudel_ex/gbif-app/src/vite-env.d.ts
new file mode 100644
index 00000000..7d0ff9ef
--- /dev/null
+++ b/strudel_ex/gbif-app/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/strudel_ex/gbif-app/strudel.config.ts b/strudel_ex/gbif-app/strudel.config.ts
new file mode 100644
index 00000000..9c14b259
--- /dev/null
+++ b/strudel_ex/gbif-app/strudel.config.ts
@@ -0,0 +1,34 @@
+/**
+ * Configure global options and content for your app.
+ */
+export const config = {
+ title: 'STRUDEL + React + MUI',
+ navbar: {
+ title: 'My Project',
+ logo: 'strudel-logo-icon.png',
+ items: [
+ {
+ label: 'Playground',
+ path: '/playground'
+ }
+ ]
+ },
+ footer: {
+ info: 'Describe your project, place a copyright statement, or credit your funding organizations.',
+ image: 'strudel-logo-header.png',
+ links: [
+ {
+ label: 'Playground',
+ path: '/playground'
+ },
+ ]
+ },
+ theme: {
+ mode: 'light',
+ primaryColor: '#1976d2',
+ secondaryColor: '#9c27b0',
+ backgroundColor: '#F5F5F6',
+ paperBackgroundColor: '#FFFFFF',
+ fontFamily: '"Helvetica", "Verdana", "Arial", sans-serif'
+ }
+}
\ No newline at end of file
diff --git a/strudel_ex/gbif-app/tsconfig.json b/strudel_ex/gbif-app/tsconfig.json
new file mode 100644
index 00000000..25fb62ad
--- /dev/null
+++ b/strudel_ex/gbif-app/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src", "strudel.config.ts"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/strudel_ex/gbif-app/tsconfig.node.json b/strudel_ex/gbif-app/tsconfig.node.json
new file mode 100644
index 00000000..b8505820
--- /dev/null
+++ b/strudel_ex/gbif-app/tsconfig.node.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "strict": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/strudel_ex/gbif-app/vite.config.ts b/strudel_ex/gbif-app/vite.config.ts
new file mode 100644
index 00000000..2bf8137b
--- /dev/null
+++ b/strudel_ex/gbif-app/vite.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+import generouted from '@generouted/react-router/plugin';
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react(), generouted()],
+})
diff --git a/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst
new file mode 100644
index 00000000..c4700f97
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst
@@ -0,0 +1,28 @@
+Copyright 2010 Pallets
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/METADATA b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/METADATA
new file mode 100644
index 00000000..7354b5a5
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/METADATA
@@ -0,0 +1,93 @@
+Metadata-Version: 2.1
+Name: MarkupSafe
+Version: 2.1.5
+Summary: Safely add untrusted strings to HTML/XML markup.
+Home-page: https://palletsprojects.com/p/markupsafe/
+Maintainer: Pallets
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
+Project-URL: Donate, https://palletsprojects.com/donate
+Project-URL: Documentation, https://markupsafe.palletsprojects.com/
+Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/
+Project-URL: Source Code, https://github.com/pallets/markupsafe/
+Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/
+Project-URL: Chat, https://discord.gg/pallets
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Text Processing :: Markup :: HTML
+Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
+License-File: LICENSE.rst
+
+MarkupSafe
+==========
+
+MarkupSafe implements a text object that escapes characters so it is
+safe to use in HTML and XML. Characters that have special meanings are
+replaced so that they display as the actual characters. This mitigates
+injection attacks, meaning untrusted user input can safely be displayed
+on a page.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+ pip install -U MarkupSafe
+
+.. _pip: https://pip.pypa.io/en/stable/getting-started/
+
+
+Examples
+--------
+
+.. code-block:: pycon
+
+ >>> from markupsafe import Markup, escape
+
+ >>> # escape replaces special characters and wraps in Markup
+ >>> escape("")
+ Markup('<script>alert(document.cookie);</script>')
+
+ >>> # wrap in Markup to mark text "safe" and prevent escaping
+ >>> Markup("Hello")
+ Markup('hello')
+
+ >>> escape(Markup("Hello"))
+ Markup('hello')
+
+ >>> # Markup is a str subclass
+ >>> # methods and operators escape their arguments
+ >>> template = Markup("Hello {name}")
+ >>> template.format(name='"World"')
+ Markup('Hello "World"')
+
+
+Donate
+------
+
+The Pallets organization develops and supports MarkupSafe and other
+popular packages. In order to grow the community of contributors and
+users, and allow the maintainers to devote more time to the projects,
+`please donate today`_.
+
+.. _please donate today: https://palletsprojects.com/donate
+
+
+Links
+-----
+
+- Documentation: https://markupsafe.palletsprojects.com/
+- Changes: https://markupsafe.palletsprojects.com/changes/
+- PyPI Releases: https://pypi.org/project/MarkupSafe/
+- Source Code: https://github.com/pallets/markupsafe/
+- Issue Tracker: https://github.com/pallets/markupsafe/issues/
+- Chat: https://discord.gg/pallets
diff --git a/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/RECORD b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/RECORD
new file mode 100644
index 00000000..0211f2ab
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/RECORD
@@ -0,0 +1,14 @@
+MarkupSafe-2.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+MarkupSafe-2.1.5.dist-info/LICENSE.rst,sha256=RjHsDbX9kKVH4zaBcmTGeYIUM4FG-KyUtKV_lu6MnsQ,1503
+MarkupSafe-2.1.5.dist-info/METADATA,sha256=icNlaniV7YIQZ1BScCVqNaRtm7MAgfw8d3OBmoSVyAY,3096
+MarkupSafe-2.1.5.dist-info/RECORD,,
+MarkupSafe-2.1.5.dist-info/WHEEL,sha256=j9Aissza3750LQHFAQyYerNjmkEON1-8w_RaZNFtKSs,102
+MarkupSafe-2.1.5.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
+markupsafe/__init__.py,sha256=m1ysNeqf55zbEoJtaovca40ivrkEFolPlw5bGoC5Gi4,11290
+markupsafe/__pycache__/__init__.cpython-312.pyc,,
+markupsafe/__pycache__/_native.cpython-312.pyc,,
+markupsafe/_native.py,sha256=_Q7UsXCOvgdonCgqG3l5asANI6eo50EKnDM-mlwEC5M,1776
+markupsafe/_speedups.c,sha256=n3jzzaJwXcoN8nTFyA53f3vSqsWK2vujI-v6QYifjhQ,7403
+markupsafe/_speedups.cp312-win_amd64.pyd,sha256=CLz8k0mpvM-dgLP0eSHpGYHm8shlGxXoCinA12zgHsY,15872
+markupsafe/_speedups.pyi,sha256=f5QtwIOP0eLrxh2v5p6SmaYmlcHIGIfmz0DovaqL0OU,238
+markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
diff --git a/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/WHEEL b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/WHEEL
new file mode 100644
index 00000000..1c1a93de
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/WHEEL
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.42.0)
+Root-Is-Purelib: false
+Tag: cp312-cp312-win_amd64
+
diff --git a/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt
new file mode 100644
index 00000000..75bf7292
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt
@@ -0,0 +1 @@
+markupsafe
diff --git a/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/INSTALLER b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/LICENSE b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/LICENSE
new file mode 100644
index 00000000..2f1b8e15
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2017-2021 Ingy döt Net
+Copyright (c) 2006-2016 Kirill Simonov
+
+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.
diff --git a/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/METADATA b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/METADATA
new file mode 100644
index 00000000..6523240c
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/METADATA
@@ -0,0 +1,46 @@
+Metadata-Version: 2.1
+Name: PyYAML
+Version: 6.0.1
+Summary: YAML parser and emitter for Python
+Home-page: https://pyyaml.org/
+Download-URL: https://pypi.org/project/PyYAML/
+Author: Kirill Simonov
+Author-email: xi@resolvent.net
+License: MIT
+Project-URL: Bug Tracker, https://github.com/yaml/pyyaml/issues
+Project-URL: CI, https://github.com/yaml/pyyaml/actions
+Project-URL: Documentation, https://pyyaml.org/wiki/PyYAMLDocumentation
+Project-URL: Mailing lists, http://lists.sourceforge.net/lists/listinfo/yaml-core
+Project-URL: Source Code, https://github.com/yaml/pyyaml
+Platform: Any
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Cython
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Text Processing :: Markup
+Requires-Python: >=3.6
+License-File: LICENSE
+
+YAML is a data serialization format designed for human readability
+and interaction with scripting languages. PyYAML is a YAML parser
+and emitter for Python.
+
+PyYAML features a complete YAML 1.1 parser, Unicode support, pickle
+support, capable extension API, and sensible error messages. PyYAML
+supports standard YAML tags and provides Python-specific tags that
+allow to represent an arbitrary Python object.
+
+PyYAML is applicable for a broad range of tasks from complex
+configuration files to object serialization and persistence.
diff --git a/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/RECORD b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/RECORD
new file mode 100644
index 00000000..dda3dd57
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/RECORD
@@ -0,0 +1,43 @@
+PyYAML-6.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+PyYAML-6.0.1.dist-info/LICENSE,sha256=jTko-dxEkP1jVwfLiOsmvXZBAqcoKVQwfT5RZ6V36KQ,1101
+PyYAML-6.0.1.dist-info/METADATA,sha256=i3GoINVJ0RnmgIBLEFUIA75PtRGAhQAZGeWJNZFKogc,2104
+PyYAML-6.0.1.dist-info/RECORD,,
+PyYAML-6.0.1.dist-info/WHEEL,sha256=aDrgWfEd5Ac7WJzHsr90rcMGiH4MHbAXoCWpyP5CEBc,102
+PyYAML-6.0.1.dist-info/top_level.txt,sha256=rpj0IVMTisAjh_1vG3Ccf9v5jpCQwAz6cD1IVU5ZdhQ,11
+_yaml/__init__.py,sha256=04Ae_5osxahpJHa3XBZUAf4wi6XX32gR8D6X6p64GEA,1402
+_yaml/__pycache__/__init__.cpython-312.pyc,,
+yaml/__init__.py,sha256=bhl05qSeO-1ZxlSRjGrvl2m9nrXb1n9-GQatTN0Mrqc,12311
+yaml/__pycache__/__init__.cpython-312.pyc,,
+yaml/__pycache__/composer.cpython-312.pyc,,
+yaml/__pycache__/constructor.cpython-312.pyc,,
+yaml/__pycache__/cyaml.cpython-312.pyc,,
+yaml/__pycache__/dumper.cpython-312.pyc,,
+yaml/__pycache__/emitter.cpython-312.pyc,,
+yaml/__pycache__/error.cpython-312.pyc,,
+yaml/__pycache__/events.cpython-312.pyc,,
+yaml/__pycache__/loader.cpython-312.pyc,,
+yaml/__pycache__/nodes.cpython-312.pyc,,
+yaml/__pycache__/parser.cpython-312.pyc,,
+yaml/__pycache__/reader.cpython-312.pyc,,
+yaml/__pycache__/representer.cpython-312.pyc,,
+yaml/__pycache__/resolver.cpython-312.pyc,,
+yaml/__pycache__/scanner.cpython-312.pyc,,
+yaml/__pycache__/serializer.cpython-312.pyc,,
+yaml/__pycache__/tokens.cpython-312.pyc,,
+yaml/_yaml.cp312-win_amd64.pyd,sha256=CHiB31W5_h2QvRH4m2yVFt_SCsMw5A-X28wYiwywNOY,222720
+yaml/composer.py,sha256=_Ko30Wr6eDWUeUpauUGT3Lcg9QPBnOPVlTnIMRGJ9FM,4883
+yaml/constructor.py,sha256=kNgkfaeLUkwQYY_Q6Ff1Tz2XVw_pG1xVE9Ak7z-viLA,28639
+yaml/cyaml.py,sha256=6ZrAG9fAYvdVe2FK_w0hmXoG7ZYsoYUwapG8CiC72H0,3851
+yaml/dumper.py,sha256=PLctZlYwZLp7XmeUdwRuv4nYOZ2UBnDIUy8-lKfLF-o,2837
+yaml/emitter.py,sha256=jghtaU7eFwg31bG0B7RZea_29Adi9CKmXq_QjgQpCkQ,43006
+yaml/error.py,sha256=Ah9z-toHJUbE9j-M8YpxgSRM5CgLCcwVzJgLLRF2Fxo,2533
+yaml/events.py,sha256=50_TksgQiE4up-lKo_V-nBy-tAIxkIPQxY5qDhKCeHw,2445
+yaml/loader.py,sha256=UVa-zIqmkFSCIYq_PgSGm4NSJttHY2Rf_zQ4_b1fHN0,2061
+yaml/nodes.py,sha256=gPKNj8pKCdh2d4gr3gIYINnPOaOxGhJAUiYhGRnPE84,1440
+yaml/parser.py,sha256=ilWp5vvgoHFGzvOZDItFoGjD6D42nhlZrZyjAwa0oJo,25495
+yaml/reader.py,sha256=0dmzirOiDG4Xo41RnuQS7K9rkY3xjHiVasfDMNTqCNw,6794
+yaml/representer.py,sha256=IuWP-cAW9sHKEnS0gCqSa894k1Bg4cgTxaDwIcbRQ-Y,14190
+yaml/resolver.py,sha256=9L-VYfm4mWHxUD1Vg4X7rjDRK_7VZd6b92wzq7Y2IKY,9004
+yaml/scanner.py,sha256=YEM3iLZSaQwXcQRg2l2R4MdT0zGP2F9eHkKGKnHyWQY,51279
+yaml/serializer.py,sha256=ChuFgmhU01hj4xgI8GaKv6vfM2Bujwa9i7d2FAHj7cA,4165
+yaml/tokens.py,sha256=lTQIzSVw8Mg9wv459-TjiOQe6wVziqaRlqX2_89rp54,2573
diff --git a/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/WHEEL b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/WHEEL
new file mode 100644
index 00000000..8fbbd53b
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/WHEEL
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.41.2)
+Root-Is-Purelib: false
+Tag: cp312-cp312-win_amd64
+
diff --git a/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/top_level.txt b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/top_level.txt
new file mode 100644
index 00000000..e6475e91
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/PyYAML-6.0.1.dist-info/top_level.txt
@@ -0,0 +1,2 @@
+_yaml
+yaml
diff --git a/strudel_ex/virt/Lib/site-packages/_yaml/__init__.py b/strudel_ex/virt/Lib/site-packages/_yaml/__init__.py
new file mode 100644
index 00000000..7baa8c4b
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/_yaml/__init__.py
@@ -0,0 +1,33 @@
+# This is a stub package designed to roughly emulate the _yaml
+# extension module, which previously existed as a standalone module
+# and has been moved into the `yaml` package namespace.
+# It does not perfectly mimic its old counterpart, but should get
+# close enough for anyone who's relying on it even when they shouldn't.
+import yaml
+
+# in some circumstances, the yaml module we imoprted may be from a different version, so we need
+# to tread carefully when poking at it here (it may not have the attributes we expect)
+if not getattr(yaml, '__with_libyaml__', False):
+ from sys import version_info
+
+ exc = ModuleNotFoundError if version_info >= (3, 6) else ImportError
+ raise exc("No module named '_yaml'")
+else:
+ from yaml._yaml import *
+ import warnings
+ warnings.warn(
+ 'The _yaml extension module is now located at yaml._yaml'
+ ' and its location is subject to change. To use the'
+ ' LibYAML-based parser and emitter, import from `yaml`:'
+ ' `from yaml import CLoader as Loader, CDumper as Dumper`.',
+ DeprecationWarning
+ )
+ del warnings
+ # Don't `del yaml` here because yaml is actually an existing
+ # namespace member of _yaml.
+
+__name__ = '_yaml'
+# If the module is top-level (i.e. not a part of any specific package)
+# then the attribute should be set to ''.
+# https://docs.python.org/3.8/library/types.html
+__package__ = ''
diff --git a/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/INSTALLER b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/LICENSE b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/LICENSE
new file mode 100644
index 00000000..ff864f3b
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2023 Chris Smith
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/METADATA b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/METADATA
new file mode 100644
index 00000000..94b7642b
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/METADATA
@@ -0,0 +1,176 @@
+Metadata-Version: 2.1
+Name: arrow
+Version: 1.3.0
+Summary: Better dates & times for Python
+Keywords: arrow,date,time,datetime,timestamp,timezone,humanize
+Author-email: Chris Smith
+Requires-Python: >=3.8
+Description-Content-Type: text/x-rst
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Information Technology
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Operating System :: OS Independent
+Requires-Dist: python-dateutil>=2.7.0
+Requires-Dist: types-python-dateutil>=2.8.10
+Requires-Dist: doc8 ; extra == "doc"
+Requires-Dist: sphinx>=7.0.0 ; extra == "doc"
+Requires-Dist: sphinx-autobuild ; extra == "doc"
+Requires-Dist: sphinx-autodoc-typehints ; extra == "doc"
+Requires-Dist: sphinx_rtd_theme>=1.3.0 ; extra == "doc"
+Requires-Dist: dateparser==1.* ; extra == "test"
+Requires-Dist: pre-commit ; extra == "test"
+Requires-Dist: pytest ; extra == "test"
+Requires-Dist: pytest-cov ; extra == "test"
+Requires-Dist: pytest-mock ; extra == "test"
+Requires-Dist: pytz==2021.1 ; extra == "test"
+Requires-Dist: simplejson==3.* ; extra == "test"
+Project-URL: Documentation, https://arrow.readthedocs.io
+Project-URL: Issues, https://github.com/arrow-py/arrow/issues
+Project-URL: Source, https://github.com/arrow-py/arrow
+Provides-Extra: doc
+Provides-Extra: test
+
+Arrow: Better dates & times for Python
+======================================
+
+.. start-inclusion-marker-do-not-remove
+
+.. image:: https://github.com/arrow-py/arrow/workflows/tests/badge.svg?branch=master
+ :alt: Build Status
+ :target: https://github.com/arrow-py/arrow/actions?query=workflow%3Atests+branch%3Amaster
+
+.. image:: https://codecov.io/gh/arrow-py/arrow/branch/master/graph/badge.svg
+ :alt: Coverage
+ :target: https://codecov.io/gh/arrow-py/arrow
+
+.. image:: https://img.shields.io/pypi/v/arrow.svg
+ :alt: PyPI Version
+ :target: https://pypi.python.org/pypi/arrow
+
+.. image:: https://img.shields.io/pypi/pyversions/arrow.svg
+ :alt: Supported Python Versions
+ :target: https://pypi.python.org/pypi/arrow
+
+.. image:: https://img.shields.io/pypi/l/arrow.svg
+ :alt: License
+ :target: https://pypi.python.org/pypi/arrow
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
+ :alt: Code Style: Black
+ :target: https://github.com/psf/black
+
+
+**Arrow** is a Python library that offers a sensible and human-friendly approach to creating, manipulating, formatting and converting dates, times and timestamps. It implements and updates the datetime type, plugging gaps in functionality and providing an intelligent module API that supports many common creation scenarios. Simply put, it helps you work with dates and times with fewer imports and a lot less code.
+
+Arrow is named after the `arrow of time `_ and is heavily inspired by `moment.js `_ and `requests `_.
+
+Why use Arrow over built-in modules?
+------------------------------------
+
+Python's standard library and some other low-level modules have near-complete date, time and timezone functionality, but don't work very well from a usability perspective:
+
+- Too many modules: datetime, time, calendar, dateutil, pytz and more
+- Too many types: date, time, datetime, tzinfo, timedelta, relativedelta, etc.
+- Timezones and timestamp conversions are verbose and unpleasant
+- Timezone naivety is the norm
+- Gaps in functionality: ISO 8601 parsing, timespans, humanization
+
+Features
+--------
+
+- Fully-implemented, drop-in replacement for datetime
+- Support for Python 3.6+
+- Timezone-aware and UTC by default
+- Super-simple creation options for many common input scenarios
+- ``shift`` method with support for relative offsets, including weeks
+- Format and parse strings automatically
+- Wide support for the `ISO 8601 `_ standard
+- Timezone conversion
+- Support for ``dateutil``, ``pytz``, and ``ZoneInfo`` tzinfo objects
+- Generates time spans, ranges, floors and ceilings for time frames ranging from microsecond to year
+- Humanize dates and times with a growing list of contributed locales
+- Extensible for your own Arrow-derived types
+- Full support for PEP 484-style type hints
+
+Quick Start
+-----------
+
+Installation
+~~~~~~~~~~~~
+
+To install Arrow, use `pip `_ or `pipenv `_:
+
+.. code-block:: console
+
+ $ pip install -U arrow
+
+Example Usage
+~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ >>> import arrow
+ >>> arrow.get('2013-05-11T21:23:58.970460+07:00')
+
+
+ >>> utc = arrow.utcnow()
+ >>> utc
+
+
+ >>> utc = utc.shift(hours=-1)
+ >>> utc
+
+
+ >>> local = utc.to('US/Pacific')
+ >>> local
+
+
+ >>> local.timestamp()
+ 1368303838.970460
+
+ >>> local.format()
+ '2013-05-11 13:23:58 -07:00'
+
+ >>> local.format('YYYY-MM-DD HH:mm:ss ZZ')
+ '2013-05-11 13:23:58 -07:00'
+
+ >>> local.humanize()
+ 'an hour ago'
+
+ >>> local.humanize(locale='ko-kr')
+ '한시간 전'
+
+.. end-inclusion-marker-do-not-remove
+
+Documentation
+-------------
+
+For full documentation, please visit `arrow.readthedocs.io `_.
+
+Contributing
+------------
+
+Contributions are welcome for both code and localizations (adding and updating locales). Begin by gaining familiarity with the Arrow library and its features. Then, jump into contributing:
+
+#. Find an issue or feature to tackle on the `issue tracker `_. Issues marked with the `"good first issue" label `_ may be a great place to start!
+#. Fork `this repository `_ on GitHub and begin making changes in a branch.
+#. Add a few tests to ensure that the bug was fixed or the feature works as expected.
+#. Run the entire test suite and linting checks by running one of the following commands: ``tox && tox -e lint,docs`` (if you have `tox `_ installed) **OR** ``make build39 && make test && make lint`` (if you do not have Python 3.9 installed, replace ``build39`` with the latest Python version on your system).
+#. Submit a pull request and await feedback 😃.
+
+If you have any questions along the way, feel free to ask them `here `_.
+
+Support Arrow
+-------------
+
+`Open Collective `_ is an online funding platform that provides tools to raise money and share your finances with full transparency. It is the platform of choice for individuals and companies to make one-time or recurring donations directly to the project. If you are interested in making a financial contribution, please visit the `Arrow collective `_.
+
diff --git a/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/RECORD b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/RECORD
new file mode 100644
index 00000000..29356e98
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/RECORD
@@ -0,0 +1,26 @@
+arrow-1.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+arrow-1.3.0.dist-info/LICENSE,sha256=tIH4cpbLCr2xP9jLuUsUwyi-iA7J5oVHphuE2s_9Bno,11341
+arrow-1.3.0.dist-info/METADATA,sha256=P7gh6Gt6pIqBLBP577OoTZWFhRmAOpMyiwpuNEeklac,7534
+arrow-1.3.0.dist-info/RECORD,,
+arrow-1.3.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
+arrow/__init__.py,sha256=HxsSJGl56GoeHB__No-kdGmC_Wes_Ttf0ohOy7OoFig,872
+arrow/__pycache__/__init__.cpython-312.pyc,,
+arrow/__pycache__/_version.cpython-312.pyc,,
+arrow/__pycache__/api.cpython-312.pyc,,
+arrow/__pycache__/arrow.cpython-312.pyc,,
+arrow/__pycache__/constants.cpython-312.pyc,,
+arrow/__pycache__/factory.cpython-312.pyc,,
+arrow/__pycache__/formatter.cpython-312.pyc,,
+arrow/__pycache__/locales.cpython-312.pyc,,
+arrow/__pycache__/parser.cpython-312.pyc,,
+arrow/__pycache__/util.cpython-312.pyc,,
+arrow/_version.py,sha256=F5mW07pSyGrqDNY2Ehr-UpDzpBtN-FsYU0QGZWf6PJE,22
+arrow/api.py,sha256=6tdqrG0NjrKO22_eWHU4a5xerfR6IrZPY-yynGpnvTM,2755
+arrow/arrow.py,sha256=m9XvNnpQ1aTHZWXPud3W2-QMfilgWXnUCnuZInwf27g,63517
+arrow/constants.py,sha256=y3scgWgxiFuQg4DeFlhmexy1BA7K8LFNZyqK-VWPQJs,3238
+arrow/factory.py,sha256=qiDSokfcVWJhiJbIkOcU1Ohh4N0PdKxghsJzBnI8AUo,11432
+arrow/formatter.py,sha256=0D0-AjBZwuay9312KvY0UnaVBfAZj-vEIqWcG0_3ZDQ,5267
+arrow/locales.py,sha256=6g5xHq5UkIAZPF8N2PvzN_xoUvsfNcPhNfJw0TUi8tw,156894
+arrow/parser.py,sha256=FO6NWpzjvZcsMhIck6pd7hKe1ijlKUZE9l_OFlyskyw,25790
+arrow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+arrow/util.py,sha256=xnDevqRyNeYWbl3x-n_Tyo4cOgHcdgbxFECFsJ1XoEc,3679
diff --git a/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/WHEEL b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/WHEEL
new file mode 100644
index 00000000..3b5e64b5
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow-1.3.0.dist-info/WHEEL
@@ -0,0 +1,4 @@
+Wheel-Version: 1.0
+Generator: flit 3.9.0
+Root-Is-Purelib: true
+Tag: py3-none-any
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/__init__.py b/strudel_ex/virt/Lib/site-packages/arrow/__init__.py
new file mode 100644
index 00000000..bc597097
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/__init__.py
@@ -0,0 +1,39 @@
+from ._version import __version__
+from .api import get, now, utcnow
+from .arrow import Arrow
+from .factory import ArrowFactory
+from .formatter import (
+ FORMAT_ATOM,
+ FORMAT_COOKIE,
+ FORMAT_RFC822,
+ FORMAT_RFC850,
+ FORMAT_RFC1036,
+ FORMAT_RFC1123,
+ FORMAT_RFC2822,
+ FORMAT_RFC3339,
+ FORMAT_RSS,
+ FORMAT_W3C,
+)
+from .parser import ParserError
+
+# https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-no-implicit-reexport
+# Mypy with --strict or --no-implicit-reexport requires an explicit reexport.
+__all__ = [
+ "__version__",
+ "get",
+ "now",
+ "utcnow",
+ "Arrow",
+ "ArrowFactory",
+ "FORMAT_ATOM",
+ "FORMAT_COOKIE",
+ "FORMAT_RFC822",
+ "FORMAT_RFC850",
+ "FORMAT_RFC1036",
+ "FORMAT_RFC1123",
+ "FORMAT_RFC2822",
+ "FORMAT_RFC3339",
+ "FORMAT_RSS",
+ "FORMAT_W3C",
+ "ParserError",
+]
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/_version.py b/strudel_ex/virt/Lib/site-packages/arrow/_version.py
new file mode 100644
index 00000000..67bc602a
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/_version.py
@@ -0,0 +1 @@
+__version__ = "1.3.0"
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/api.py b/strudel_ex/virt/Lib/site-packages/arrow/api.py
new file mode 100644
index 00000000..d8ed24b9
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/api.py
@@ -0,0 +1,126 @@
+"""
+Provides the default implementation of :class:`ArrowFactory `
+methods for use as a module API.
+
+"""
+
+from datetime import date, datetime
+from datetime import tzinfo as dt_tzinfo
+from time import struct_time
+from typing import Any, List, Optional, Tuple, Type, Union, overload
+
+from arrow.arrow import TZ_EXPR, Arrow
+from arrow.constants import DEFAULT_LOCALE
+from arrow.factory import ArrowFactory
+
+# internal default factory.
+_factory = ArrowFactory()
+
+# TODO: Use Positional Only Argument (https://www.python.org/dev/peps/pep-0570/)
+# after Python 3.7 deprecation
+
+
+@overload
+def get(
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+) -> Arrow:
+ ... # pragma: no cover
+
+
+@overload
+def get(
+ *args: int,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+) -> Arrow:
+ ... # pragma: no cover
+
+
+@overload
+def get(
+ __obj: Union[
+ Arrow,
+ datetime,
+ date,
+ struct_time,
+ dt_tzinfo,
+ int,
+ float,
+ str,
+ Tuple[int, int, int],
+ ],
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+) -> Arrow:
+ ... # pragma: no cover
+
+
+@overload
+def get(
+ __arg1: Union[datetime, date],
+ __arg2: TZ_EXPR,
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+) -> Arrow:
+ ... # pragma: no cover
+
+
+@overload
+def get(
+ __arg1: str,
+ __arg2: Union[str, List[str]],
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+) -> Arrow:
+ ... # pragma: no cover
+
+
+def get(*args: Any, **kwargs: Any) -> Arrow:
+ """Calls the default :class:`ArrowFactory ` ``get`` method."""
+
+ return _factory.get(*args, **kwargs)
+
+
+get.__doc__ = _factory.get.__doc__
+
+
+def utcnow() -> Arrow:
+ """Calls the default :class:`ArrowFactory ` ``utcnow`` method."""
+
+ return _factory.utcnow()
+
+
+utcnow.__doc__ = _factory.utcnow.__doc__
+
+
+def now(tz: Optional[TZ_EXPR] = None) -> Arrow:
+ """Calls the default :class:`ArrowFactory ` ``now`` method."""
+
+ return _factory.now(tz)
+
+
+now.__doc__ = _factory.now.__doc__
+
+
+def factory(type: Type[Arrow]) -> ArrowFactory:
+ """Returns an :class:`.ArrowFactory` for the specified :class:`Arrow `
+ or derived type.
+
+ :param type: the type, :class:`Arrow ` or derived.
+
+ """
+
+ return ArrowFactory(type)
+
+
+__all__ = ["get", "utcnow", "now", "factory"]
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/arrow.py b/strudel_ex/virt/Lib/site-packages/arrow/arrow.py
new file mode 100644
index 00000000..8d329efd
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/arrow.py
@@ -0,0 +1,1869 @@
+"""
+Provides the :class:`Arrow ` class, an enhanced ``datetime``
+replacement.
+
+"""
+
+
+import calendar
+import re
+import sys
+from datetime import date
+from datetime import datetime as dt_datetime
+from datetime import time as dt_time
+from datetime import timedelta
+from datetime import tzinfo as dt_tzinfo
+from math import trunc
+from time import struct_time
+from typing import (
+ Any,
+ ClassVar,
+ Generator,
+ Iterable,
+ List,
+ Mapping,
+ Optional,
+ Tuple,
+ Union,
+ cast,
+ overload,
+)
+
+from dateutil import tz as dateutil_tz
+from dateutil.relativedelta import relativedelta
+
+from arrow import formatter, locales, parser, util
+from arrow.constants import DEFAULT_LOCALE, DEHUMANIZE_LOCALES
+from arrow.locales import TimeFrameLiteral
+
+if sys.version_info < (3, 8): # pragma: no cover
+ from typing_extensions import Final, Literal
+else:
+ from typing import Final, Literal # pragma: no cover
+
+
+TZ_EXPR = Union[dt_tzinfo, str]
+
+_T_FRAMES = Literal[
+ "year",
+ "years",
+ "month",
+ "months",
+ "day",
+ "days",
+ "hour",
+ "hours",
+ "minute",
+ "minutes",
+ "second",
+ "seconds",
+ "microsecond",
+ "microseconds",
+ "week",
+ "weeks",
+ "quarter",
+ "quarters",
+]
+
+_BOUNDS = Literal["[)", "()", "(]", "[]"]
+
+_GRANULARITY = Literal[
+ "auto",
+ "second",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+]
+
+
+class Arrow:
+ """An :class:`Arrow ` object.
+
+ Implements the ``datetime`` interface, behaving as an aware ``datetime`` while implementing
+ additional functionality.
+
+ :param year: the calendar year.
+ :param month: the calendar month.
+ :param day: the calendar day.
+ :param hour: (optional) the hour. Defaults to 0.
+ :param minute: (optional) the minute, Defaults to 0.
+ :param second: (optional) the second, Defaults to 0.
+ :param microsecond: (optional) the microsecond. Defaults to 0.
+ :param tzinfo: (optional) A timezone expression. Defaults to UTC.
+ :param fold: (optional) 0 or 1, used to disambiguate repeated wall times. Defaults to 0.
+
+ .. _tz-expr:
+
+ Recognized timezone expressions:
+
+ - A ``tzinfo`` object.
+ - A ``str`` describing a timezone, similar to 'US/Pacific', or 'Europe/Berlin'.
+ - A ``str`` in ISO 8601 style, as in '+07:00'.
+ - A ``str``, one of the following: 'local', 'utc', 'UTC'.
+
+ Usage::
+
+ >>> import arrow
+ >>> arrow.Arrow(2013, 5, 5, 12, 30, 45)
+
+
+ """
+
+ resolution: ClassVar[timedelta] = dt_datetime.resolution
+ min: ClassVar["Arrow"]
+ max: ClassVar["Arrow"]
+
+ _ATTRS: Final[List[str]] = [
+ "year",
+ "month",
+ "day",
+ "hour",
+ "minute",
+ "second",
+ "microsecond",
+ ]
+ _ATTRS_PLURAL: Final[List[str]] = [f"{a}s" for a in _ATTRS]
+ _MONTHS_PER_QUARTER: Final[int] = 3
+ _SECS_PER_MINUTE: Final[int] = 60
+ _SECS_PER_HOUR: Final[int] = 60 * 60
+ _SECS_PER_DAY: Final[int] = 60 * 60 * 24
+ _SECS_PER_WEEK: Final[int] = 60 * 60 * 24 * 7
+ _SECS_PER_MONTH: Final[float] = 60 * 60 * 24 * 30.5
+ _SECS_PER_QUARTER: Final[float] = 60 * 60 * 24 * 30.5 * 3
+ _SECS_PER_YEAR: Final[int] = 60 * 60 * 24 * 365
+
+ _SECS_MAP: Final[Mapping[TimeFrameLiteral, float]] = {
+ "second": 1.0,
+ "minute": _SECS_PER_MINUTE,
+ "hour": _SECS_PER_HOUR,
+ "day": _SECS_PER_DAY,
+ "week": _SECS_PER_WEEK,
+ "month": _SECS_PER_MONTH,
+ "quarter": _SECS_PER_QUARTER,
+ "year": _SECS_PER_YEAR,
+ }
+
+ _datetime: dt_datetime
+
+ def __init__(
+ self,
+ year: int,
+ month: int,
+ day: int,
+ hour: int = 0,
+ minute: int = 0,
+ second: int = 0,
+ microsecond: int = 0,
+ tzinfo: Optional[TZ_EXPR] = None,
+ **kwargs: Any,
+ ) -> None:
+ if tzinfo is None:
+ tzinfo = dateutil_tz.tzutc()
+ # detect that tzinfo is a pytz object (issue #626)
+ elif (
+ isinstance(tzinfo, dt_tzinfo)
+ and hasattr(tzinfo, "localize")
+ and hasattr(tzinfo, "zone")
+ and tzinfo.zone
+ ):
+ tzinfo = parser.TzinfoParser.parse(tzinfo.zone)
+ elif isinstance(tzinfo, str):
+ tzinfo = parser.TzinfoParser.parse(tzinfo)
+
+ fold = kwargs.get("fold", 0)
+
+ self._datetime = dt_datetime(
+ year, month, day, hour, minute, second, microsecond, tzinfo, fold=fold
+ )
+
+ # factories: single object, both original and from datetime.
+
+ @classmethod
+ def now(cls, tzinfo: Optional[dt_tzinfo] = None) -> "Arrow":
+ """Constructs an :class:`Arrow ` object, representing "now" in the given
+ timezone.
+
+ :param tzinfo: (optional) a ``tzinfo`` object. Defaults to local time.
+
+ Usage::
+
+ >>> arrow.now('Asia/Baku')
+
+
+ """
+
+ if tzinfo is None:
+ tzinfo = dateutil_tz.tzlocal()
+
+ dt = dt_datetime.now(tzinfo)
+
+ return cls(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ dt.tzinfo,
+ fold=getattr(dt, "fold", 0),
+ )
+
+ @classmethod
+ def utcnow(cls) -> "Arrow":
+ """Constructs an :class:`Arrow ` object, representing "now" in UTC
+ time.
+
+ Usage::
+
+ >>> arrow.utcnow()
+
+
+ """
+
+ dt = dt_datetime.now(dateutil_tz.tzutc())
+
+ return cls(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ dt.tzinfo,
+ fold=getattr(dt, "fold", 0),
+ )
+
+ @classmethod
+ def fromtimestamp(
+ cls,
+ timestamp: Union[int, float, str],
+ tzinfo: Optional[TZ_EXPR] = None,
+ ) -> "Arrow":
+ """Constructs an :class:`Arrow ` object from a timestamp, converted to
+ the given timezone.
+
+ :param timestamp: an ``int`` or ``float`` timestamp, or a ``str`` that converts to either.
+ :param tzinfo: (optional) a ``tzinfo`` object. Defaults to local time.
+
+ """
+
+ if tzinfo is None:
+ tzinfo = dateutil_tz.tzlocal()
+ elif isinstance(tzinfo, str):
+ tzinfo = parser.TzinfoParser.parse(tzinfo)
+
+ if not util.is_timestamp(timestamp):
+ raise ValueError(f"The provided timestamp {timestamp!r} is invalid.")
+
+ timestamp = util.normalize_timestamp(float(timestamp))
+ dt = dt_datetime.fromtimestamp(timestamp, tzinfo)
+
+ return cls(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ dt.tzinfo,
+ fold=getattr(dt, "fold", 0),
+ )
+
+ @classmethod
+ def utcfromtimestamp(cls, timestamp: Union[int, float, str]) -> "Arrow":
+ """Constructs an :class:`Arrow ` object from a timestamp, in UTC time.
+
+ :param timestamp: an ``int`` or ``float`` timestamp, or a ``str`` that converts to either.
+
+ """
+
+ if not util.is_timestamp(timestamp):
+ raise ValueError(f"The provided timestamp {timestamp!r} is invalid.")
+
+ timestamp = util.normalize_timestamp(float(timestamp))
+ dt = dt_datetime.utcfromtimestamp(timestamp)
+
+ return cls(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ dateutil_tz.tzutc(),
+ fold=getattr(dt, "fold", 0),
+ )
+
+ @classmethod
+ def fromdatetime(cls, dt: dt_datetime, tzinfo: Optional[TZ_EXPR] = None) -> "Arrow":
+ """Constructs an :class:`Arrow ` object from a ``datetime`` and
+ optional replacement timezone.
+
+ :param dt: the ``datetime``
+ :param tzinfo: (optional) A :ref:`timezone expression `. Defaults to ``dt``'s
+ timezone, or UTC if naive.
+
+ Usage::
+
+ >>> dt
+ datetime.datetime(2021, 4, 7, 13, 48, tzinfo=tzfile('/usr/share/zoneinfo/US/Pacific'))
+ >>> arrow.Arrow.fromdatetime(dt)
+
+
+ """
+
+ if tzinfo is None:
+ if dt.tzinfo is None:
+ tzinfo = dateutil_tz.tzutc()
+ else:
+ tzinfo = dt.tzinfo
+
+ return cls(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ tzinfo,
+ fold=getattr(dt, "fold", 0),
+ )
+
+ @classmethod
+ def fromdate(cls, date: date, tzinfo: Optional[TZ_EXPR] = None) -> "Arrow":
+ """Constructs an :class:`Arrow ` object from a ``date`` and optional
+ replacement timezone. All time values are set to 0.
+
+ :param date: the ``date``
+ :param tzinfo: (optional) A :ref:`timezone expression `. Defaults to UTC.
+
+ """
+
+ if tzinfo is None:
+ tzinfo = dateutil_tz.tzutc()
+
+ return cls(date.year, date.month, date.day, tzinfo=tzinfo)
+
+ @classmethod
+ def strptime(
+ cls, date_str: str, fmt: str, tzinfo: Optional[TZ_EXPR] = None
+ ) -> "Arrow":
+ """Constructs an :class:`Arrow ` object from a date string and format,
+ in the style of ``datetime.strptime``. Optionally replaces the parsed timezone.
+
+ :param date_str: the date string.
+ :param fmt: the format string using datetime format codes.
+ :param tzinfo: (optional) A :ref:`timezone expression `. Defaults to the parsed
+ timezone if ``fmt`` contains a timezone directive, otherwise UTC.
+
+ Usage::
+
+ >>> arrow.Arrow.strptime('20-01-2019 15:49:10', '%d-%m-%Y %H:%M:%S')
+
+
+ """
+
+ dt = dt_datetime.strptime(date_str, fmt)
+ if tzinfo is None:
+ tzinfo = dt.tzinfo
+
+ return cls(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ tzinfo,
+ fold=getattr(dt, "fold", 0),
+ )
+
+ @classmethod
+ def fromordinal(cls, ordinal: int) -> "Arrow":
+ """Constructs an :class:`Arrow ` object corresponding
+ to the Gregorian Ordinal.
+
+ :param ordinal: an ``int`` corresponding to a Gregorian Ordinal.
+
+ Usage::
+
+ >>> arrow.fromordinal(737741)
+
+
+ """
+
+ util.validate_ordinal(ordinal)
+ dt = dt_datetime.fromordinal(ordinal)
+ return cls(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ dt.tzinfo,
+ fold=getattr(dt, "fold", 0),
+ )
+
+ # factories: ranges and spans
+
+ @classmethod
+ def range(
+ cls,
+ frame: _T_FRAMES,
+ start: Union["Arrow", dt_datetime],
+ end: Union["Arrow", dt_datetime, None] = None,
+ tz: Optional[TZ_EXPR] = None,
+ limit: Optional[int] = None,
+ ) -> Generator["Arrow", None, None]:
+ """Returns an iterator of :class:`Arrow ` objects, representing
+ points in time between two inputs.
+
+ :param frame: The timeframe. Can be any ``datetime`` property (day, hour, minute...).
+ :param start: A datetime expression, the start of the range.
+ :param end: (optional) A datetime expression, the end of the range.
+ :param tz: (optional) A :ref:`timezone expression `. Defaults to
+ ``start``'s timezone, or UTC if ``start`` is naive.
+ :param limit: (optional) A maximum number of tuples to return.
+
+ **NOTE**: The ``end`` or ``limit`` must be provided. Call with ``end`` alone to
+ return the entire range. Call with ``limit`` alone to return a maximum # of results from
+ the start. Call with both to cap a range at a maximum # of results.
+
+ **NOTE**: ``tz`` internally **replaces** the timezones of both ``start`` and ``end`` before
+ iterating. As such, either call with naive objects and ``tz``, or aware objects from the
+ same timezone and no ``tz``.
+
+ Supported frame values: year, quarter, month, week, day, hour, minute, second, microsecond.
+
+ Recognized datetime expressions:
+
+ - An :class:`Arrow ` object.
+ - A ``datetime`` object.
+
+ Usage::
+
+ >>> start = datetime(2013, 5, 5, 12, 30)
+ >>> end = datetime(2013, 5, 5, 17, 15)
+ >>> for r in arrow.Arrow.range('hour', start, end):
+ ... print(repr(r))
+ ...
+
+
+
+
+
+
+ **NOTE**: Unlike Python's ``range``, ``end`` *may* be included in the returned iterator::
+
+ >>> start = datetime(2013, 5, 5, 12, 30)
+ >>> end = datetime(2013, 5, 5, 13, 30)
+ >>> for r in arrow.Arrow.range('hour', start, end):
+ ... print(repr(r))
+ ...
+
+
+
+ """
+
+ _, frame_relative, relative_steps = cls._get_frames(frame)
+
+ tzinfo = cls._get_tzinfo(start.tzinfo if tz is None else tz)
+
+ start = cls._get_datetime(start).replace(tzinfo=tzinfo)
+ end, limit = cls._get_iteration_params(end, limit)
+ end = cls._get_datetime(end).replace(tzinfo=tzinfo)
+
+ current = cls.fromdatetime(start)
+ original_day = start.day
+ day_is_clipped = False
+ i = 0
+
+ while current <= end and i < limit:
+ i += 1
+ yield current
+
+ values = [getattr(current, f) for f in cls._ATTRS]
+ current = cls(*values, tzinfo=tzinfo).shift( # type: ignore[misc]
+ **{frame_relative: relative_steps}
+ )
+
+ if frame in ["month", "quarter", "year"] and current.day < original_day:
+ day_is_clipped = True
+
+ if day_is_clipped and not cls._is_last_day_of_month(current):
+ current = current.replace(day=original_day)
+
+ def span(
+ self,
+ frame: _T_FRAMES,
+ count: int = 1,
+ bounds: _BOUNDS = "[)",
+ exact: bool = False,
+ week_start: int = 1,
+ ) -> Tuple["Arrow", "Arrow"]:
+ """Returns a tuple of two new :class:`Arrow ` objects, representing the timespan
+ of the :class:`Arrow ` object in a given timeframe.
+
+ :param frame: the timeframe. Can be any ``datetime`` property (day, hour, minute...).
+ :param count: (optional) the number of frames to span.
+ :param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
+ whether to include or exclude the start and end values in the span. '(' excludes
+ the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
+ If the bounds are not specified, the default bound '[)' is used.
+ :param exact: (optional) whether to have the start of the timespan begin exactly
+ at the time specified by ``start`` and the end of the timespan truncated
+ so as not to extend beyond ``end``.
+ :param week_start: (optional) only used in combination with the week timeframe. Follows isoweekday() where
+ Monday is 1 and Sunday is 7.
+
+ Supported frame values: year, quarter, month, week, day, hour, minute, second.
+
+ Usage::
+
+ >>> arrow.utcnow()
+
+
+ >>> arrow.utcnow().span('hour')
+ (, )
+
+ >>> arrow.utcnow().span('day')
+ (, )
+
+ >>> arrow.utcnow().span('day', count=2)
+ (, )
+
+ >>> arrow.utcnow().span('day', bounds='[]')
+ (, )
+
+ >>> arrow.utcnow().span('week')
+ (, )
+
+ >>> arrow.utcnow().span('week', week_start=6)
+ (, )
+
+ """
+ if not 1 <= week_start <= 7:
+ raise ValueError("week_start argument must be between 1 and 7.")
+
+ util.validate_bounds(bounds)
+
+ frame_absolute, frame_relative, relative_steps = self._get_frames(frame)
+
+ if frame_absolute == "week":
+ attr = "day"
+ elif frame_absolute == "quarter":
+ attr = "month"
+ else:
+ attr = frame_absolute
+
+ floor = self
+ if not exact:
+ index = self._ATTRS.index(attr)
+ frames = self._ATTRS[: index + 1]
+
+ values = [getattr(self, f) for f in frames]
+
+ for _ in range(3 - len(values)):
+ values.append(1)
+
+ floor = self.__class__(*values, tzinfo=self.tzinfo) # type: ignore[misc]
+
+ if frame_absolute == "week":
+ # if week_start is greater than self.isoweekday() go back one week by setting delta = 7
+ delta = 7 if week_start > self.isoweekday() else 0
+ floor = floor.shift(days=-(self.isoweekday() - week_start) - delta)
+ elif frame_absolute == "quarter":
+ floor = floor.shift(months=-((self.month - 1) % 3))
+
+ ceil = floor.shift(**{frame_relative: count * relative_steps})
+
+ if bounds[0] == "(":
+ floor = floor.shift(microseconds=+1)
+
+ if bounds[1] == ")":
+ ceil = ceil.shift(microseconds=-1)
+
+ return floor, ceil
+
+ def floor(self, frame: _T_FRAMES) -> "Arrow":
+ """Returns a new :class:`Arrow ` object, representing the "floor"
+ of the timespan of the :class:`Arrow ` object in a given timeframe.
+ Equivalent to the first element in the 2-tuple returned by
+ :func:`span `.
+
+ :param frame: the timeframe. Can be any ``datetime`` property (day, hour, minute...).
+
+ Usage::
+
+ >>> arrow.utcnow().floor('hour')
+
+
+ """
+
+ return self.span(frame)[0]
+
+ def ceil(self, frame: _T_FRAMES) -> "Arrow":
+ """Returns a new :class:`Arrow ` object, representing the "ceiling"
+ of the timespan of the :class:`Arrow ` object in a given timeframe.
+ Equivalent to the second element in the 2-tuple returned by
+ :func:`span `.
+
+ :param frame: the timeframe. Can be any ``datetime`` property (day, hour, minute...).
+
+ Usage::
+
+ >>> arrow.utcnow().ceil('hour')
+
+
+ """
+
+ return self.span(frame)[1]
+
+ @classmethod
+ def span_range(
+ cls,
+ frame: _T_FRAMES,
+ start: dt_datetime,
+ end: dt_datetime,
+ tz: Optional[TZ_EXPR] = None,
+ limit: Optional[int] = None,
+ bounds: _BOUNDS = "[)",
+ exact: bool = False,
+ ) -> Iterable[Tuple["Arrow", "Arrow"]]:
+ """Returns an iterator of tuples, each :class:`Arrow ` objects,
+ representing a series of timespans between two inputs.
+
+ :param frame: The timeframe. Can be any ``datetime`` property (day, hour, minute...).
+ :param start: A datetime expression, the start of the range.
+ :param end: (optional) A datetime expression, the end of the range.
+ :param tz: (optional) A :ref:`timezone expression `. Defaults to
+ ``start``'s timezone, or UTC if ``start`` is naive.
+ :param limit: (optional) A maximum number of tuples to return.
+ :param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
+ whether to include or exclude the start and end values in each span in the range. '(' excludes
+ the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
+ If the bounds are not specified, the default bound '[)' is used.
+ :param exact: (optional) whether to have the first timespan start exactly
+ at the time specified by ``start`` and the final span truncated
+ so as not to extend beyond ``end``.
+
+ **NOTE**: The ``end`` or ``limit`` must be provided. Call with ``end`` alone to
+ return the entire range. Call with ``limit`` alone to return a maximum # of results from
+ the start. Call with both to cap a range at a maximum # of results.
+
+ **NOTE**: ``tz`` internally **replaces** the timezones of both ``start`` and ``end`` before
+ iterating. As such, either call with naive objects and ``tz``, or aware objects from the
+ same timezone and no ``tz``.
+
+ Supported frame values: year, quarter, month, week, day, hour, minute, second, microsecond.
+
+ Recognized datetime expressions:
+
+ - An :class:`Arrow ` object.
+ - A ``datetime`` object.
+
+ **NOTE**: Unlike Python's ``range``, ``end`` will *always* be included in the returned
+ iterator of timespans.
+
+ Usage:
+
+ >>> start = datetime(2013, 5, 5, 12, 30)
+ >>> end = datetime(2013, 5, 5, 17, 15)
+ >>> for r in arrow.Arrow.span_range('hour', start, end):
+ ... print(r)
+ ...
+ (, )
+ (, )
+ (, )
+ (, )
+ (, )
+ (, )
+
+ """
+
+ tzinfo = cls._get_tzinfo(start.tzinfo if tz is None else tz)
+ start = cls.fromdatetime(start, tzinfo).span(frame, exact=exact)[0]
+ end = cls.fromdatetime(end, tzinfo)
+ _range = cls.range(frame, start, end, tz, limit)
+ if not exact:
+ for r in _range:
+ yield r.span(frame, bounds=bounds, exact=exact)
+
+ for r in _range:
+ floor, ceil = r.span(frame, bounds=bounds, exact=exact)
+ if ceil > end:
+ ceil = end
+ if bounds[1] == ")":
+ ceil += relativedelta(microseconds=-1)
+ if floor == end:
+ break
+ elif floor + relativedelta(microseconds=-1) == end:
+ break
+ yield floor, ceil
+
+ @classmethod
+ def interval(
+ cls,
+ frame: _T_FRAMES,
+ start: dt_datetime,
+ end: dt_datetime,
+ interval: int = 1,
+ tz: Optional[TZ_EXPR] = None,
+ bounds: _BOUNDS = "[)",
+ exact: bool = False,
+ ) -> Iterable[Tuple["Arrow", "Arrow"]]:
+ """Returns an iterator of tuples, each :class:`Arrow ` objects,
+ representing a series of intervals between two inputs.
+
+ :param frame: The timeframe. Can be any ``datetime`` property (day, hour, minute...).
+ :param start: A datetime expression, the start of the range.
+ :param end: (optional) A datetime expression, the end of the range.
+ :param interval: (optional) Time interval for the given time frame.
+ :param tz: (optional) A timezone expression. Defaults to UTC.
+ :param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
+ whether to include or exclude the start and end values in the intervals. '(' excludes
+ the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
+ If the bounds are not specified, the default bound '[)' is used.
+ :param exact: (optional) whether to have the first timespan start exactly
+ at the time specified by ``start`` and the final interval truncated
+ so as not to extend beyond ``end``.
+
+ Supported frame values: year, quarter, month, week, day, hour, minute, second
+
+ Recognized datetime expressions:
+
+ - An :class:`Arrow ` object.
+ - A ``datetime`` object.
+
+ Recognized timezone expressions:
+
+ - A ``tzinfo`` object.
+ - A ``str`` describing a timezone, similar to 'US/Pacific', or 'Europe/Berlin'.
+ - A ``str`` in ISO 8601 style, as in '+07:00'.
+ - A ``str``, one of the following: 'local', 'utc', 'UTC'.
+
+ Usage:
+
+ >>> start = datetime(2013, 5, 5, 12, 30)
+ >>> end = datetime(2013, 5, 5, 17, 15)
+ >>> for r in arrow.Arrow.interval('hour', start, end, 2):
+ ... print(r)
+ ...
+ (, )
+ (, )
+ (, )
+ """
+ if interval < 1:
+ raise ValueError("interval has to be a positive integer")
+
+ spanRange = iter(
+ cls.span_range(frame, start, end, tz, bounds=bounds, exact=exact)
+ )
+ while True:
+ try:
+ intvlStart, intvlEnd = next(spanRange)
+ for _ in range(interval - 1):
+ try:
+ _, intvlEnd = next(spanRange)
+ except StopIteration:
+ continue
+ yield intvlStart, intvlEnd
+ except StopIteration:
+ return
+
+ # representations
+
+ def __repr__(self) -> str:
+ return f"<{self.__class__.__name__} [{self.__str__()}]>"
+
+ def __str__(self) -> str:
+ return self._datetime.isoformat()
+
+ def __format__(self, formatstr: str) -> str:
+ if len(formatstr) > 0:
+ return self.format(formatstr)
+
+ return str(self)
+
+ def __hash__(self) -> int:
+ return self._datetime.__hash__()
+
+ # attributes and properties
+
+ def __getattr__(self, name: str) -> int:
+ if name == "week":
+ return self.isocalendar()[1]
+
+ if name == "quarter":
+ return int((self.month - 1) / self._MONTHS_PER_QUARTER) + 1
+
+ if not name.startswith("_"):
+ value: Optional[int] = getattr(self._datetime, name, None)
+
+ if value is not None:
+ return value
+
+ return cast(int, object.__getattribute__(self, name))
+
+ @property
+ def tzinfo(self) -> dt_tzinfo:
+ """Gets the ``tzinfo`` of the :class:`Arrow ` object.
+
+ Usage::
+
+ >>> arw=arrow.utcnow()
+ >>> arw.tzinfo
+ tzutc()
+
+ """
+
+ # In Arrow, `_datetime` cannot be naive.
+ return cast(dt_tzinfo, self._datetime.tzinfo)
+
+ @property
+ def datetime(self) -> dt_datetime:
+ """Returns a datetime representation of the :class:`Arrow ` object.
+
+ Usage::
+
+ >>> arw=arrow.utcnow()
+ >>> arw.datetime
+ datetime.datetime(2019, 1, 24, 16, 35, 27, 276649, tzinfo=tzutc())
+
+ """
+
+ return self._datetime
+
+ @property
+ def naive(self) -> dt_datetime:
+ """Returns a naive datetime representation of the :class:`Arrow `
+ object.
+
+ Usage::
+
+ >>> nairobi = arrow.now('Africa/Nairobi')
+ >>> nairobi
+
+ >>> nairobi.naive
+ datetime.datetime(2019, 1, 23, 19, 27, 12, 297999)
+
+ """
+
+ return self._datetime.replace(tzinfo=None)
+
+ def timestamp(self) -> float:
+ """Returns a timestamp representation of the :class:`Arrow ` object, in
+ UTC time.
+
+ Usage::
+
+ >>> arrow.utcnow().timestamp()
+ 1616882340.256501
+
+ """
+
+ return self._datetime.timestamp()
+
+ @property
+ def int_timestamp(self) -> int:
+ """Returns an integer timestamp representation of the :class:`Arrow ` object, in
+ UTC time.
+
+ Usage::
+
+ >>> arrow.utcnow().int_timestamp
+ 1548260567
+
+ """
+
+ return int(self.timestamp())
+
+ @property
+ def float_timestamp(self) -> float:
+ """Returns a floating-point timestamp representation of the :class:`Arrow `
+ object, in UTC time.
+
+ Usage::
+
+ >>> arrow.utcnow().float_timestamp
+ 1548260516.830896
+
+ """
+
+ return self.timestamp()
+
+ @property
+ def fold(self) -> int:
+ """Returns the ``fold`` value of the :class:`Arrow ` object."""
+
+ return self._datetime.fold
+
+ @property
+ def ambiguous(self) -> bool:
+ """Indicates whether the :class:`Arrow ` object is a repeated wall time in the current
+ timezone.
+
+ """
+
+ return dateutil_tz.datetime_ambiguous(self._datetime)
+
+ @property
+ def imaginary(self) -> bool:
+ """Indicates whether the :class: `Arrow ` object exists in the current timezone."""
+
+ return not dateutil_tz.datetime_exists(self._datetime)
+
+ # mutation and duplication.
+
+ def clone(self) -> "Arrow":
+ """Returns a new :class:`Arrow ` object, cloned from the current one.
+
+ Usage:
+
+ >>> arw = arrow.utcnow()
+ >>> cloned = arw.clone()
+
+ """
+
+ return self.fromdatetime(self._datetime)
+
+ def replace(self, **kwargs: Any) -> "Arrow":
+ """Returns a new :class:`Arrow ` object with attributes updated
+ according to inputs.
+
+ Use property names to set their value absolutely::
+
+ >>> import arrow
+ >>> arw = arrow.utcnow()
+ >>> arw
+
+ >>> arw.replace(year=2014, month=6)
+
+
+ You can also replace the timezone without conversion, using a
+ :ref:`timezone expression `::
+
+ >>> arw.replace(tzinfo=tz.tzlocal())
+
+
+ """
+
+ absolute_kwargs = {}
+
+ for key, value in kwargs.items():
+ if key in self._ATTRS:
+ absolute_kwargs[key] = value
+ elif key in ["week", "quarter"]:
+ raise ValueError(f"Setting absolute {key} is not supported.")
+ elif key not in ["tzinfo", "fold"]:
+ raise ValueError(f"Unknown attribute: {key!r}.")
+
+ current = self._datetime.replace(**absolute_kwargs)
+
+ tzinfo = kwargs.get("tzinfo")
+
+ if tzinfo is not None:
+ tzinfo = self._get_tzinfo(tzinfo)
+ current = current.replace(tzinfo=tzinfo)
+
+ fold = kwargs.get("fold")
+
+ if fold is not None:
+ current = current.replace(fold=fold)
+
+ return self.fromdatetime(current)
+
+ def shift(self, **kwargs: Any) -> "Arrow":
+ """Returns a new :class:`Arrow ` object with attributes updated
+ according to inputs.
+
+ Use pluralized property names to relatively shift their current value:
+
+ >>> import arrow
+ >>> arw = arrow.utcnow()
+ >>> arw
+
+ >>> arw.shift(years=1, months=-1)
+
+
+ Day-of-the-week relative shifting can use either Python's weekday numbers
+ (Monday = 0, Tuesday = 1 .. Sunday = 6) or using dateutil.relativedelta's
+ day instances (MO, TU .. SU). When using weekday numbers, the returned
+ date will always be greater than or equal to the starting date.
+
+ Using the above code (which is a Saturday) and asking it to shift to Saturday:
+
+ >>> arw.shift(weekday=5)
+
+
+ While asking for a Monday:
+
+ >>> arw.shift(weekday=0)
+
+
+ """
+
+ relative_kwargs = {}
+ additional_attrs = ["weeks", "quarters", "weekday"]
+
+ for key, value in kwargs.items():
+ if key in self._ATTRS_PLURAL or key in additional_attrs:
+ relative_kwargs[key] = value
+ else:
+ supported_attr = ", ".join(self._ATTRS_PLURAL + additional_attrs)
+ raise ValueError(
+ f"Invalid shift time frame. Please select one of the following: {supported_attr}."
+ )
+
+ # core datetime does not support quarters, translate to months.
+ relative_kwargs.setdefault("months", 0)
+ relative_kwargs["months"] += (
+ relative_kwargs.pop("quarters", 0) * self._MONTHS_PER_QUARTER
+ )
+
+ current = self._datetime + relativedelta(**relative_kwargs)
+
+ if not dateutil_tz.datetime_exists(current):
+ current = dateutil_tz.resolve_imaginary(current)
+
+ return self.fromdatetime(current)
+
+ def to(self, tz: TZ_EXPR) -> "Arrow":
+ """Returns a new :class:`Arrow ` object, converted
+ to the target timezone.
+
+ :param tz: A :ref:`timezone expression `.
+
+ Usage::
+
+ >>> utc = arrow.utcnow()
+ >>> utc
+
+
+ >>> utc.to('US/Pacific')
+
+
+ >>> utc.to(tz.tzlocal())
+
+
+ >>> utc.to('-07:00')
+
+
+ >>> utc.to('local')
+
+
+ >>> utc.to('local').to('utc')
+
+
+ """
+
+ if not isinstance(tz, dt_tzinfo):
+ tz = parser.TzinfoParser.parse(tz)
+
+ dt = self._datetime.astimezone(tz)
+
+ return self.__class__(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ dt.tzinfo,
+ fold=getattr(dt, "fold", 0),
+ )
+
+ # string output and formatting
+
+ def format(
+ self, fmt: str = "YYYY-MM-DD HH:mm:ssZZ", locale: str = DEFAULT_LOCALE
+ ) -> str:
+ """Returns a string representation of the :class:`Arrow ` object,
+ formatted according to the provided format string.
+
+ :param fmt: the format string.
+ :param locale: the locale to format.
+
+ Usage::
+
+ >>> arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ')
+ '2013-05-09 03:56:47 -00:00'
+
+ >>> arrow.utcnow().format('X')
+ '1368071882'
+
+ >>> arrow.utcnow().format('MMMM DD, YYYY')
+ 'May 09, 2013'
+
+ >>> arrow.utcnow().format()
+ '2013-05-09 03:56:47 -00:00'
+
+ """
+
+ return formatter.DateTimeFormatter(locale).format(self._datetime, fmt)
+
+ def humanize(
+ self,
+ other: Union["Arrow", dt_datetime, None] = None,
+ locale: str = DEFAULT_LOCALE,
+ only_distance: bool = False,
+ granularity: Union[_GRANULARITY, List[_GRANULARITY]] = "auto",
+ ) -> str:
+ """Returns a localized, humanized representation of a relative difference in time.
+
+ :param other: (optional) an :class:`Arrow ` or ``datetime`` object.
+ Defaults to now in the current :class:`Arrow ` object's timezone.
+ :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en-us'.
+ :param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part.
+ :param granularity: (optional) defines the precision of the output. Set it to strings 'second', 'minute',
+ 'hour', 'day', 'week', 'month' or 'year' or a list of any combination of these strings
+
+ Usage::
+
+ >>> earlier = arrow.utcnow().shift(hours=-2)
+ >>> earlier.humanize()
+ '2 hours ago'
+
+ >>> later = earlier.shift(hours=4)
+ >>> later.humanize(earlier)
+ 'in 4 hours'
+
+ """
+
+ locale_name = locale
+ locale = locales.get_locale(locale)
+
+ if other is None:
+ utc = dt_datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc())
+ dt = utc.astimezone(self._datetime.tzinfo)
+
+ elif isinstance(other, Arrow):
+ dt = other._datetime
+
+ elif isinstance(other, dt_datetime):
+ if other.tzinfo is None:
+ dt = other.replace(tzinfo=self._datetime.tzinfo)
+ else:
+ dt = other.astimezone(self._datetime.tzinfo)
+
+ else:
+ raise TypeError(
+ f"Invalid 'other' argument of type {type(other).__name__!r}. "
+ "Argument must be of type None, Arrow, or datetime."
+ )
+
+ if isinstance(granularity, list) and len(granularity) == 1:
+ granularity = granularity[0]
+
+ _delta = int(round((self._datetime - dt).total_seconds()))
+ sign = -1 if _delta < 0 else 1
+ delta_second = diff = abs(_delta)
+
+ try:
+ if granularity == "auto":
+ if diff < 10:
+ return locale.describe("now", only_distance=only_distance)
+
+ if diff < self._SECS_PER_MINUTE:
+ seconds = sign * delta_second
+ return locale.describe(
+ "seconds", seconds, only_distance=only_distance
+ )
+
+ elif diff < self._SECS_PER_MINUTE * 2:
+ return locale.describe("minute", sign, only_distance=only_distance)
+ elif diff < self._SECS_PER_HOUR:
+ minutes = sign * max(delta_second // self._SECS_PER_MINUTE, 2)
+ return locale.describe(
+ "minutes", minutes, only_distance=only_distance
+ )
+
+ elif diff < self._SECS_PER_HOUR * 2:
+ return locale.describe("hour", sign, only_distance=only_distance)
+ elif diff < self._SECS_PER_DAY:
+ hours = sign * max(delta_second // self._SECS_PER_HOUR, 2)
+ return locale.describe("hours", hours, only_distance=only_distance)
+ elif diff < self._SECS_PER_DAY * 2:
+ return locale.describe("day", sign, only_distance=only_distance)
+ elif diff < self._SECS_PER_WEEK:
+ days = sign * max(delta_second // self._SECS_PER_DAY, 2)
+ return locale.describe("days", days, only_distance=only_distance)
+
+ elif diff < self._SECS_PER_WEEK * 2:
+ return locale.describe("week", sign, only_distance=only_distance)
+ elif diff < self._SECS_PER_MONTH:
+ weeks = sign * max(delta_second // self._SECS_PER_WEEK, 2)
+ return locale.describe("weeks", weeks, only_distance=only_distance)
+
+ elif diff < self._SECS_PER_MONTH * 2:
+ return locale.describe("month", sign, only_distance=only_distance)
+ elif diff < self._SECS_PER_YEAR:
+ # TODO revisit for humanization during leap years
+ self_months = self._datetime.year * 12 + self._datetime.month
+ other_months = dt.year * 12 + dt.month
+
+ months = sign * max(abs(other_months - self_months), 2)
+
+ return locale.describe(
+ "months", months, only_distance=only_distance
+ )
+
+ elif diff < self._SECS_PER_YEAR * 2:
+ return locale.describe("year", sign, only_distance=only_distance)
+ else:
+ years = sign * max(delta_second // self._SECS_PER_YEAR, 2)
+ return locale.describe("years", years, only_distance=only_distance)
+
+ elif isinstance(granularity, str):
+ granularity = cast(TimeFrameLiteral, granularity) # type: ignore[assignment]
+
+ if granularity == "second":
+ delta = sign * float(delta_second)
+ if abs(delta) < 2:
+ return locale.describe("now", only_distance=only_distance)
+ elif granularity == "minute":
+ delta = sign * delta_second / self._SECS_PER_MINUTE
+ elif granularity == "hour":
+ delta = sign * delta_second / self._SECS_PER_HOUR
+ elif granularity == "day":
+ delta = sign * delta_second / self._SECS_PER_DAY
+ elif granularity == "week":
+ delta = sign * delta_second / self._SECS_PER_WEEK
+ elif granularity == "month":
+ delta = sign * delta_second / self._SECS_PER_MONTH
+ elif granularity == "quarter":
+ delta = sign * delta_second / self._SECS_PER_QUARTER
+ elif granularity == "year":
+ delta = sign * delta_second / self._SECS_PER_YEAR
+ else:
+ raise ValueError(
+ "Invalid level of granularity. "
+ "Please select between 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter' or 'year'."
+ )
+
+ if trunc(abs(delta)) != 1:
+ granularity += "s" # type: ignore[assignment]
+ return locale.describe(granularity, delta, only_distance=only_distance)
+
+ else:
+ if not granularity:
+ raise ValueError(
+ "Empty granularity list provided. "
+ "Please select one or more from 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'."
+ )
+
+ timeframes: List[Tuple[TimeFrameLiteral, float]] = []
+
+ def gather_timeframes(_delta: float, _frame: TimeFrameLiteral) -> float:
+ if _frame in granularity:
+ value = sign * _delta / self._SECS_MAP[_frame]
+ _delta %= self._SECS_MAP[_frame]
+ if trunc(abs(value)) != 1:
+ timeframes.append(
+ (cast(TimeFrameLiteral, _frame + "s"), value)
+ )
+ else:
+ timeframes.append((_frame, value))
+ return _delta
+
+ delta = float(delta_second)
+ frames: Tuple[TimeFrameLiteral, ...] = (
+ "year",
+ "quarter",
+ "month",
+ "week",
+ "day",
+ "hour",
+ "minute",
+ "second",
+ )
+ for frame in frames:
+ delta = gather_timeframes(delta, frame)
+
+ if len(timeframes) < len(granularity):
+ raise ValueError(
+ "Invalid level of granularity. "
+ "Please select between 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter' or 'year'."
+ )
+
+ return locale.describe_multi(timeframes, only_distance=only_distance)
+
+ except KeyError as e:
+ raise ValueError(
+ f"Humanization of the {e} granularity is not currently translated in the {locale_name!r} locale. "
+ "Please consider making a contribution to this locale."
+ )
+
+ def dehumanize(self, input_string: str, locale: str = "en_us") -> "Arrow":
+ """Returns a new :class:`Arrow ` object, that represents
+ the time difference relative to the attributes of the
+ :class:`Arrow ` object.
+
+ :param timestring: a ``str`` representing a humanized relative time.
+ :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en-us'.
+
+ Usage::
+
+ >>> arw = arrow.utcnow()
+ >>> arw
+
+ >>> earlier = arw.dehumanize("2 days ago")
+ >>> earlier
+
+
+ >>> arw = arrow.utcnow()
+ >>> arw
+
+ >>> later = arw.dehumanize("in a month")
+ >>> later
+
+
+ """
+
+ # Create a locale object based off given local
+ locale_obj = locales.get_locale(locale)
+
+ # Check to see if locale is supported
+ normalized_locale_name = locale.lower().replace("_", "-")
+
+ if normalized_locale_name not in DEHUMANIZE_LOCALES:
+ raise ValueError(
+ f"Dehumanize does not currently support the {locale} locale, please consider making a contribution to add support for this locale."
+ )
+
+ current_time = self.fromdatetime(self._datetime)
+
+ # Create an object containing the relative time info
+ time_object_info = dict.fromkeys(
+ ["seconds", "minutes", "hours", "days", "weeks", "months", "years"], 0
+ )
+
+ # Create an object representing if unit has been seen
+ unit_visited = dict.fromkeys(
+ ["now", "seconds", "minutes", "hours", "days", "weeks", "months", "years"],
+ False,
+ )
+
+ # Create a regex pattern object for numbers
+ num_pattern = re.compile(r"\d+")
+
+ # Search input string for each time unit within locale
+ for unit, unit_object in locale_obj.timeframes.items():
+ # Need to check the type of unit_object to create the correct dictionary
+ if isinstance(unit_object, Mapping):
+ strings_to_search = unit_object
+ else:
+ strings_to_search = {unit: str(unit_object)}
+
+ # Search for any matches that exist for that locale's unit.
+ # Needs to cycle all through strings as some locales have strings that
+ # could overlap in a regex match, since input validation isn't being performed.
+ for time_delta, time_string in strings_to_search.items():
+ # Replace {0} with regex \d representing digits
+ search_string = str(time_string)
+ search_string = search_string.format(r"\d+")
+
+ # Create search pattern and find within string
+ pattern = re.compile(rf"(^|\b|\d){search_string}")
+ match = pattern.search(input_string)
+
+ # If there is no match continue to next iteration
+ if not match:
+ continue
+
+ match_string = match.group()
+ num_match = num_pattern.search(match_string)
+
+ # If no number matches
+ # Need for absolute value as some locales have signs included in their objects
+ if not num_match:
+ change_value = (
+ 1 if not time_delta.isnumeric() else abs(int(time_delta))
+ )
+ else:
+ change_value = int(num_match.group())
+
+ # No time to update if now is the unit
+ if unit == "now":
+ unit_visited[unit] = True
+ continue
+
+ # Add change value to the correct unit (incorporates the plurality that exists within timeframe i.e second v.s seconds)
+ time_unit_to_change = str(unit)
+ time_unit_to_change += (
+ "s" if (str(time_unit_to_change)[-1] != "s") else ""
+ )
+ time_object_info[time_unit_to_change] = change_value
+ unit_visited[time_unit_to_change] = True
+
+ # Assert error if string does not modify any units
+ if not any([True for k, v in unit_visited.items() if v]):
+ raise ValueError(
+ "Input string not valid. Note: Some locales do not support the week granularity in Arrow. "
+ "If you are attempting to use the week granularity on an unsupported locale, this could be the cause of this error."
+ )
+
+ # Sign logic
+ future_string = locale_obj.future
+ future_string = future_string.format(".*")
+ future_pattern = re.compile(rf"^{future_string}$")
+ future_pattern_match = future_pattern.findall(input_string)
+
+ past_string = locale_obj.past
+ past_string = past_string.format(".*")
+ past_pattern = re.compile(rf"^{past_string}$")
+ past_pattern_match = past_pattern.findall(input_string)
+
+ # If a string contains the now unit, there will be no relative units, hence the need to check if the now unit
+ # was visited before raising a ValueError
+ if past_pattern_match:
+ sign_val = -1
+ elif future_pattern_match:
+ sign_val = 1
+ elif unit_visited["now"]:
+ sign_val = 0
+ else:
+ raise ValueError(
+ "Invalid input String. String does not contain any relative time information. "
+ "String should either represent a time in the future or a time in the past. "
+ "Ex: 'in 5 seconds' or '5 seconds ago'."
+ )
+
+ time_changes = {k: sign_val * v for k, v in time_object_info.items()}
+
+ return current_time.shift(**time_changes)
+
+ # query functions
+
+ def is_between(
+ self,
+ start: "Arrow",
+ end: "Arrow",
+ bounds: _BOUNDS = "()",
+ ) -> bool:
+ """Returns a boolean denoting whether the :class:`Arrow ` object is between
+ the start and end limits.
+
+ :param start: an :class:`Arrow ` object.
+ :param end: an :class:`Arrow ` object.
+ :param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
+ whether to include or exclude the start and end values in the range. '(' excludes
+ the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
+ If the bounds are not specified, the default bound '()' is used.
+
+ Usage::
+
+ >>> start = arrow.get(datetime(2013, 5, 5, 12, 30, 10))
+ >>> end = arrow.get(datetime(2013, 5, 5, 12, 30, 36))
+ >>> arrow.get(datetime(2013, 5, 5, 12, 30, 27)).is_between(start, end)
+ True
+
+ >>> start = arrow.get(datetime(2013, 5, 5))
+ >>> end = arrow.get(datetime(2013, 5, 8))
+ >>> arrow.get(datetime(2013, 5, 8)).is_between(start, end, '[]')
+ True
+
+ >>> start = arrow.get(datetime(2013, 5, 5))
+ >>> end = arrow.get(datetime(2013, 5, 8))
+ >>> arrow.get(datetime(2013, 5, 8)).is_between(start, end, '[)')
+ False
+
+ """
+
+ util.validate_bounds(bounds)
+
+ if not isinstance(start, Arrow):
+ raise TypeError(
+ f"Cannot parse start date argument type of {type(start)!r}."
+ )
+
+ if not isinstance(end, Arrow):
+ raise TypeError(f"Cannot parse end date argument type of {type(start)!r}.")
+
+ include_start = bounds[0] == "["
+ include_end = bounds[1] == "]"
+
+ target_ts = self.float_timestamp
+ start_ts = start.float_timestamp
+ end_ts = end.float_timestamp
+
+ return (
+ (start_ts <= target_ts <= end_ts)
+ and (include_start or start_ts < target_ts)
+ and (include_end or target_ts < end_ts)
+ )
+
+ # datetime methods
+
+ def date(self) -> date:
+ """Returns a ``date`` object with the same year, month and day.
+
+ Usage::
+
+ >>> arrow.utcnow().date()
+ datetime.date(2019, 1, 23)
+
+ """
+
+ return self._datetime.date()
+
+ def time(self) -> dt_time:
+ """Returns a ``time`` object with the same hour, minute, second, microsecond.
+
+ Usage::
+
+ >>> arrow.utcnow().time()
+ datetime.time(12, 15, 34, 68352)
+
+ """
+
+ return self._datetime.time()
+
+ def timetz(self) -> dt_time:
+ """Returns a ``time`` object with the same hour, minute, second, microsecond and
+ tzinfo.
+
+ Usage::
+
+ >>> arrow.utcnow().timetz()
+ datetime.time(12, 5, 18, 298893, tzinfo=tzutc())
+
+ """
+
+ return self._datetime.timetz()
+
+ def astimezone(self, tz: Optional[dt_tzinfo]) -> dt_datetime:
+ """Returns a ``datetime`` object, converted to the specified timezone.
+
+ :param tz: a ``tzinfo`` object.
+
+ Usage::
+
+ >>> pacific=arrow.now('US/Pacific')
+ >>> nyc=arrow.now('America/New_York').tzinfo
+ >>> pacific.astimezone(nyc)
+ datetime.datetime(2019, 1, 20, 10, 24, 22, 328172, tzinfo=tzfile('/usr/share/zoneinfo/America/New_York'))
+
+ """
+
+ return self._datetime.astimezone(tz)
+
+ def utcoffset(self) -> Optional[timedelta]:
+ """Returns a ``timedelta`` object representing the whole number of minutes difference from
+ UTC time.
+
+ Usage::
+
+ >>> arrow.now('US/Pacific').utcoffset()
+ datetime.timedelta(-1, 57600)
+
+ """
+
+ return self._datetime.utcoffset()
+
+ def dst(self) -> Optional[timedelta]:
+ """Returns the daylight savings time adjustment.
+
+ Usage::
+
+ >>> arrow.utcnow().dst()
+ datetime.timedelta(0)
+
+ """
+
+ return self._datetime.dst()
+
+ def timetuple(self) -> struct_time:
+ """Returns a ``time.struct_time``, in the current timezone.
+
+ Usage::
+
+ >>> arrow.utcnow().timetuple()
+ time.struct_time(tm_year=2019, tm_mon=1, tm_mday=20, tm_hour=15, tm_min=17, tm_sec=8, tm_wday=6, tm_yday=20, tm_isdst=0)
+
+ """
+
+ return self._datetime.timetuple()
+
+ def utctimetuple(self) -> struct_time:
+ """Returns a ``time.struct_time``, in UTC time.
+
+ Usage::
+
+ >>> arrow.utcnow().utctimetuple()
+ time.struct_time(tm_year=2019, tm_mon=1, tm_mday=19, tm_hour=21, tm_min=41, tm_sec=7, tm_wday=5, tm_yday=19, tm_isdst=0)
+
+ """
+
+ return self._datetime.utctimetuple()
+
+ def toordinal(self) -> int:
+ """Returns the proleptic Gregorian ordinal of the date.
+
+ Usage::
+
+ >>> arrow.utcnow().toordinal()
+ 737078
+
+ """
+
+ return self._datetime.toordinal()
+
+ def weekday(self) -> int:
+ """Returns the day of the week as an integer (0-6).
+
+ Usage::
+
+ >>> arrow.utcnow().weekday()
+ 5
+
+ """
+
+ return self._datetime.weekday()
+
+ def isoweekday(self) -> int:
+ """Returns the ISO day of the week as an integer (1-7).
+
+ Usage::
+
+ >>> arrow.utcnow().isoweekday()
+ 6
+
+ """
+
+ return self._datetime.isoweekday()
+
+ def isocalendar(self) -> Tuple[int, int, int]:
+ """Returns a 3-tuple, (ISO year, ISO week number, ISO weekday).
+
+ Usage::
+
+ >>> arrow.utcnow().isocalendar()
+ (2019, 3, 6)
+
+ """
+
+ return self._datetime.isocalendar()
+
+ def isoformat(self, sep: str = "T", timespec: str = "auto") -> str:
+ """Returns an ISO 8601 formatted representation of the date and time.
+
+ Usage::
+
+ >>> arrow.utcnow().isoformat()
+ '2019-01-19T18:30:52.442118+00:00'
+
+ """
+
+ return self._datetime.isoformat(sep, timespec)
+
+ def ctime(self) -> str:
+ """Returns a ctime formatted representation of the date and time.
+
+ Usage::
+
+ >>> arrow.utcnow().ctime()
+ 'Sat Jan 19 18:26:50 2019'
+
+ """
+
+ return self._datetime.ctime()
+
+ def strftime(self, format: str) -> str:
+ """Formats in the style of ``datetime.strftime``.
+
+ :param format: the format string.
+
+ Usage::
+
+ >>> arrow.utcnow().strftime('%d-%m-%Y %H:%M:%S')
+ '23-01-2019 12:28:17'
+
+ """
+
+ return self._datetime.strftime(format)
+
+ def for_json(self) -> str:
+ """Serializes for the ``for_json`` protocol of simplejson.
+
+ Usage::
+
+ >>> arrow.utcnow().for_json()
+ '2019-01-19T18:25:36.760079+00:00'
+
+ """
+
+ return self.isoformat()
+
+ # math
+
+ def __add__(self, other: Any) -> "Arrow":
+ if isinstance(other, (timedelta, relativedelta)):
+ return self.fromdatetime(self._datetime + other, self._datetime.tzinfo)
+
+ return NotImplemented
+
+ def __radd__(self, other: Union[timedelta, relativedelta]) -> "Arrow":
+ return self.__add__(other)
+
+ @overload
+ def __sub__(self, other: Union[timedelta, relativedelta]) -> "Arrow":
+ pass # pragma: no cover
+
+ @overload
+ def __sub__(self, other: Union[dt_datetime, "Arrow"]) -> timedelta:
+ pass # pragma: no cover
+
+ def __sub__(self, other: Any) -> Union[timedelta, "Arrow"]:
+ if isinstance(other, (timedelta, relativedelta)):
+ return self.fromdatetime(self._datetime - other, self._datetime.tzinfo)
+
+ elif isinstance(other, dt_datetime):
+ return self._datetime - other
+
+ elif isinstance(other, Arrow):
+ return self._datetime - other._datetime
+
+ return NotImplemented
+
+ def __rsub__(self, other: Any) -> timedelta:
+ if isinstance(other, dt_datetime):
+ return other - self._datetime
+
+ return NotImplemented
+
+ # comparisons
+
+ def __eq__(self, other: Any) -> bool:
+ if not isinstance(other, (Arrow, dt_datetime)):
+ return False
+
+ return self._datetime == self._get_datetime(other)
+
+ def __ne__(self, other: Any) -> bool:
+ if not isinstance(other, (Arrow, dt_datetime)):
+ return True
+
+ return not self.__eq__(other)
+
+ def __gt__(self, other: Any) -> bool:
+ if not isinstance(other, (Arrow, dt_datetime)):
+ return NotImplemented
+
+ return self._datetime > self._get_datetime(other)
+
+ def __ge__(self, other: Any) -> bool:
+ if not isinstance(other, (Arrow, dt_datetime)):
+ return NotImplemented
+
+ return self._datetime >= self._get_datetime(other)
+
+ def __lt__(self, other: Any) -> bool:
+ if not isinstance(other, (Arrow, dt_datetime)):
+ return NotImplemented
+
+ return self._datetime < self._get_datetime(other)
+
+ def __le__(self, other: Any) -> bool:
+ if not isinstance(other, (Arrow, dt_datetime)):
+ return NotImplemented
+
+ return self._datetime <= self._get_datetime(other)
+
+ # internal methods
+ @staticmethod
+ def _get_tzinfo(tz_expr: Optional[TZ_EXPR]) -> dt_tzinfo:
+ """Get normalized tzinfo object from various inputs."""
+ if tz_expr is None:
+ return dateutil_tz.tzutc()
+ if isinstance(tz_expr, dt_tzinfo):
+ return tz_expr
+ else:
+ try:
+ return parser.TzinfoParser.parse(tz_expr)
+ except parser.ParserError:
+ raise ValueError(f"{tz_expr!r} not recognized as a timezone.")
+
+ @classmethod
+ def _get_datetime(
+ cls, expr: Union["Arrow", dt_datetime, int, float, str]
+ ) -> dt_datetime:
+ """Get datetime object from a specified expression."""
+ if isinstance(expr, Arrow):
+ return expr.datetime
+ elif isinstance(expr, dt_datetime):
+ return expr
+ elif util.is_timestamp(expr):
+ timestamp = float(expr)
+ return cls.utcfromtimestamp(timestamp).datetime
+ else:
+ raise ValueError(f"{expr!r} not recognized as a datetime or timestamp.")
+
+ @classmethod
+ def _get_frames(cls, name: _T_FRAMES) -> Tuple[str, str, int]:
+ """Finds relevant timeframe and steps for use in range and span methods.
+
+ Returns a 3 element tuple in the form (frame, plural frame, step), for example ("day", "days", 1)
+
+ """
+ if name in cls._ATTRS:
+ return name, f"{name}s", 1
+ elif name[-1] == "s" and name[:-1] in cls._ATTRS:
+ return name[:-1], name, 1
+ elif name in ["week", "weeks"]:
+ return "week", "weeks", 1
+ elif name in ["quarter", "quarters"]:
+ return "quarter", "months", 3
+ else:
+ supported = ", ".join(
+ [
+ "year(s)",
+ "month(s)",
+ "day(s)",
+ "hour(s)",
+ "minute(s)",
+ "second(s)",
+ "microsecond(s)",
+ "week(s)",
+ "quarter(s)",
+ ]
+ )
+ raise ValueError(
+ f"Range or span over frame {name} not supported. Supported frames: {supported}."
+ )
+
+ @classmethod
+ def _get_iteration_params(cls, end: Any, limit: Optional[int]) -> Tuple[Any, int]:
+ """Sets default end and limit values for range method."""
+ if end is None:
+ if limit is None:
+ raise ValueError("One of 'end' or 'limit' is required.")
+
+ return cls.max, limit
+
+ else:
+ if limit is None:
+ return end, sys.maxsize
+ return end, limit
+
+ @staticmethod
+ def _is_last_day_of_month(date: "Arrow") -> bool:
+ """Returns a boolean indicating whether the datetime is the last day of the month."""
+ return date.day == calendar.monthrange(date.year, date.month)[1]
+
+
+Arrow.min = Arrow.fromdatetime(dt_datetime.min)
+Arrow.max = Arrow.fromdatetime(dt_datetime.max)
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/constants.py b/strudel_ex/virt/Lib/site-packages/arrow/constants.py
new file mode 100644
index 00000000..53d163b9
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/constants.py
@@ -0,0 +1,177 @@
+"""Constants used internally in arrow."""
+
+import sys
+from datetime import datetime
+
+if sys.version_info < (3, 8): # pragma: no cover
+ from typing_extensions import Final
+else:
+ from typing import Final # pragma: no cover
+
+# datetime.max.timestamp() errors on Windows, so we must hardcode
+# the highest possible datetime value that can output a timestamp.
+# tl;dr platform-independent max timestamps are hard to form
+# See: https://stackoverflow.com/q/46133223
+try:
+ # Get max timestamp. Works on POSIX-based systems like Linux and macOS,
+ # but will trigger an OverflowError, ValueError, or OSError on Windows
+ _MAX_TIMESTAMP = datetime.max.timestamp()
+except (OverflowError, ValueError, OSError): # pragma: no cover
+ # Fallback for Windows and 32-bit systems if initial max timestamp call fails
+ # Must get max value of ctime on Windows based on architecture (x32 vs x64)
+ # https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ctime-ctime32-ctime64-wctime-wctime32-wctime64
+ # Note: this may occur on both 32-bit Linux systems (issue #930) along with Windows systems
+ is_64bits = sys.maxsize > 2**32
+ _MAX_TIMESTAMP = (
+ datetime(3000, 1, 1, 23, 59, 59, 999999).timestamp()
+ if is_64bits
+ else datetime(2038, 1, 1, 23, 59, 59, 999999).timestamp()
+ )
+
+MAX_TIMESTAMP: Final[float] = _MAX_TIMESTAMP
+MAX_TIMESTAMP_MS: Final[float] = MAX_TIMESTAMP * 1000
+MAX_TIMESTAMP_US: Final[float] = MAX_TIMESTAMP * 1_000_000
+
+MAX_ORDINAL: Final[int] = datetime.max.toordinal()
+MIN_ORDINAL: Final[int] = 1
+
+DEFAULT_LOCALE: Final[str] = "en-us"
+
+# Supported dehumanize locales
+DEHUMANIZE_LOCALES = {
+ "en",
+ "en-us",
+ "en-gb",
+ "en-au",
+ "en-be",
+ "en-jp",
+ "en-za",
+ "en-ca",
+ "en-ph",
+ "fr",
+ "fr-fr",
+ "fr-ca",
+ "it",
+ "it-it",
+ "es",
+ "es-es",
+ "el",
+ "el-gr",
+ "ja",
+ "ja-jp",
+ "se",
+ "se-fi",
+ "se-no",
+ "se-se",
+ "sv",
+ "sv-se",
+ "fi",
+ "fi-fi",
+ "zh",
+ "zh-cn",
+ "zh-tw",
+ "zh-hk",
+ "nl",
+ "nl-nl",
+ "be",
+ "be-by",
+ "pl",
+ "pl-pl",
+ "ru",
+ "ru-ru",
+ "af",
+ "bg",
+ "bg-bg",
+ "ua",
+ "uk",
+ "uk-ua",
+ "mk",
+ "mk-mk",
+ "de",
+ "de-de",
+ "de-ch",
+ "de-at",
+ "nb",
+ "nb-no",
+ "nn",
+ "nn-no",
+ "pt",
+ "pt-pt",
+ "pt-br",
+ "tl",
+ "tl-ph",
+ "vi",
+ "vi-vn",
+ "tr",
+ "tr-tr",
+ "az",
+ "az-az",
+ "da",
+ "da-dk",
+ "ml",
+ "hi",
+ "cs",
+ "cs-cz",
+ "sk",
+ "sk-sk",
+ "fa",
+ "fa-ir",
+ "mr",
+ "ca",
+ "ca-es",
+ "ca-ad",
+ "ca-fr",
+ "ca-it",
+ "eo",
+ "eo-xx",
+ "bn",
+ "bn-bd",
+ "bn-in",
+ "rm",
+ "rm-ch",
+ "ro",
+ "ro-ro",
+ "sl",
+ "sl-si",
+ "id",
+ "id-id",
+ "ne",
+ "ne-np",
+ "ee",
+ "et",
+ "sw",
+ "sw-ke",
+ "sw-tz",
+ "la",
+ "la-va",
+ "lt",
+ "lt-lt",
+ "ms",
+ "ms-my",
+ "ms-bn",
+ "or",
+ "or-in",
+ "lb",
+ "lb-lu",
+ "zu",
+ "zu-za",
+ "sq",
+ "sq-al",
+ "ta",
+ "ta-in",
+ "ta-lk",
+ "ur",
+ "ur-pk",
+ "ka",
+ "ka-ge",
+ "kk",
+ "kk-kz",
+ # "lo",
+ # "lo-la",
+ "am",
+ "am-et",
+ "hy-am",
+ "hy",
+ "uz",
+ "uz-uz",
+}
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/factory.py b/strudel_ex/virt/Lib/site-packages/arrow/factory.py
new file mode 100644
index 00000000..f35085f1
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/factory.py
@@ -0,0 +1,345 @@
+"""
+Implements the :class:`ArrowFactory ` class,
+providing factory methods for common :class:`Arrow `
+construction scenarios.
+
+"""
+
+
+import calendar
+from datetime import date, datetime
+from datetime import tzinfo as dt_tzinfo
+from decimal import Decimal
+from time import struct_time
+from typing import Any, List, Optional, Tuple, Type, Union, overload
+
+from dateutil import tz as dateutil_tz
+
+from arrow import parser
+from arrow.arrow import TZ_EXPR, Arrow
+from arrow.constants import DEFAULT_LOCALE
+from arrow.util import is_timestamp, iso_to_gregorian
+
+
+class ArrowFactory:
+ """A factory for generating :class:`Arrow ` objects.
+
+ :param type: (optional) the :class:`Arrow `-based class to construct from.
+ Defaults to :class:`Arrow `.
+
+ """
+
+ type: Type[Arrow]
+
+ def __init__(self, type: Type[Arrow] = Arrow) -> None:
+ self.type = type
+
+ @overload
+ def get(
+ self,
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+ ) -> Arrow:
+ ... # pragma: no cover
+
+ @overload
+ def get(
+ self,
+ __obj: Union[
+ Arrow,
+ datetime,
+ date,
+ struct_time,
+ dt_tzinfo,
+ int,
+ float,
+ str,
+ Tuple[int, int, int],
+ ],
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+ ) -> Arrow:
+ ... # pragma: no cover
+
+ @overload
+ def get(
+ self,
+ __arg1: Union[datetime, date],
+ __arg2: TZ_EXPR,
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+ ) -> Arrow:
+ ... # pragma: no cover
+
+ @overload
+ def get(
+ self,
+ __arg1: str,
+ __arg2: Union[str, List[str]],
+ *,
+ locale: str = DEFAULT_LOCALE,
+ tzinfo: Optional[TZ_EXPR] = None,
+ normalize_whitespace: bool = False,
+ ) -> Arrow:
+ ... # pragma: no cover
+
+ def get(self, *args: Any, **kwargs: Any) -> Arrow:
+ """Returns an :class:`Arrow ` object based on flexible inputs.
+
+ :param locale: (optional) a ``str`` specifying a locale for the parser. Defaults to 'en-us'.
+ :param tzinfo: (optional) a :ref:`timezone expression ` or tzinfo object.
+ Replaces the timezone unless using an input form that is explicitly UTC or specifies
+ the timezone in a positional argument. Defaults to UTC.
+ :param normalize_whitespace: (optional) a ``bool`` specifying whether or not to normalize
+ redundant whitespace (spaces, tabs, and newlines) in a datetime string before parsing.
+ Defaults to false.
+
+ Usage::
+
+ >>> import arrow
+
+ **No inputs** to get current UTC time::
+
+ >>> arrow.get()
+
+
+ **One** :class:`Arrow ` object, to get a copy.
+
+ >>> arw = arrow.utcnow()
+ >>> arrow.get(arw)
+
+
+ **One** ``float`` or ``int``, convertible to a floating-point timestamp, to get
+ that timestamp in UTC::
+
+ >>> arrow.get(1367992474.293378)
+
+
+ >>> arrow.get(1367992474)
+
+
+ **One** ISO 8601-formatted ``str``, to parse it::
+
+ >>> arrow.get('2013-09-29T01:26:43.830580')
+
+
+ **One** ISO 8601-formatted ``str``, in basic format, to parse it::
+
+ >>> arrow.get('20160413T133656.456289')
+
+
+ **One** ``tzinfo``, to get the current time **converted** to that timezone::
+
+ >>> arrow.get(tz.tzlocal())
+
+
+ **One** naive ``datetime``, to get that datetime in UTC::
+
+ >>> arrow.get(datetime(2013, 5, 5))
+
+
+ **One** aware ``datetime``, to get that datetime::
+
+ >>> arrow.get(datetime(2013, 5, 5, tzinfo=tz.tzlocal()))
+
+
+ **One** naive ``date``, to get that date in UTC::
+
+ >>> arrow.get(date(2013, 5, 5))
+
+
+ **One** time.struct time::
+
+ >>> arrow.get(gmtime(0))
+
+
+ **One** iso calendar ``tuple``, to get that week date in UTC::
+
+ >>> arrow.get((2013, 18, 7))
+
+
+ **Two** arguments, a naive or aware ``datetime``, and a replacement
+ :ref:`timezone expression `::
+
+ >>> arrow.get(datetime(2013, 5, 5), 'US/Pacific')
+
+
+ **Two** arguments, a naive ``date``, and a replacement
+ :ref:`timezone expression `::
+
+ >>> arrow.get(date(2013, 5, 5), 'US/Pacific')
+
+
+ **Two** arguments, both ``str``, to parse the first according to the format of the second::
+
+ >>> arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ')
+
+
+ **Two** arguments, first a ``str`` to parse and second a ``list`` of formats to try::
+
+ >>> arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss'])
+
+
+ **Three or more** arguments, as for the direct constructor of an ``Arrow`` object::
+
+ >>> arrow.get(2013, 5, 5, 12, 30, 45)
+
+
+ """
+
+ arg_count = len(args)
+ locale = kwargs.pop("locale", DEFAULT_LOCALE)
+ tz = kwargs.get("tzinfo", None)
+ normalize_whitespace = kwargs.pop("normalize_whitespace", False)
+
+ # if kwargs given, send to constructor unless only tzinfo provided
+ if len(kwargs) > 1:
+ arg_count = 3
+
+ # tzinfo kwarg is not provided
+ if len(kwargs) == 1 and tz is None:
+ arg_count = 3
+
+ # () -> now, @ tzinfo or utc
+ if arg_count == 0:
+ if isinstance(tz, str):
+ tz = parser.TzinfoParser.parse(tz)
+ return self.type.now(tzinfo=tz)
+
+ if isinstance(tz, dt_tzinfo):
+ return self.type.now(tzinfo=tz)
+
+ return self.type.utcnow()
+
+ if arg_count == 1:
+ arg = args[0]
+ if isinstance(arg, Decimal):
+ arg = float(arg)
+
+ # (None) -> raises an exception
+ if arg is None:
+ raise TypeError("Cannot parse argument of type None.")
+
+ # try (int, float) -> from timestamp @ tzinfo
+ elif not isinstance(arg, str) and is_timestamp(arg):
+ if tz is None:
+ # set to UTC by default
+ tz = dateutil_tz.tzutc()
+ return self.type.fromtimestamp(arg, tzinfo=tz)
+
+ # (Arrow) -> from the object's datetime @ tzinfo
+ elif isinstance(arg, Arrow):
+ return self.type.fromdatetime(arg.datetime, tzinfo=tz)
+
+ # (datetime) -> from datetime @ tzinfo
+ elif isinstance(arg, datetime):
+ return self.type.fromdatetime(arg, tzinfo=tz)
+
+ # (date) -> from date @ tzinfo
+ elif isinstance(arg, date):
+ return self.type.fromdate(arg, tzinfo=tz)
+
+ # (tzinfo) -> now @ tzinfo
+ elif isinstance(arg, dt_tzinfo):
+ return self.type.now(tzinfo=arg)
+
+ # (str) -> parse @ tzinfo
+ elif isinstance(arg, str):
+ dt = parser.DateTimeParser(locale).parse_iso(arg, normalize_whitespace)
+ return self.type.fromdatetime(dt, tzinfo=tz)
+
+ # (struct_time) -> from struct_time
+ elif isinstance(arg, struct_time):
+ return self.type.utcfromtimestamp(calendar.timegm(arg))
+
+ # (iso calendar) -> convert then from date @ tzinfo
+ elif isinstance(arg, tuple) and len(arg) == 3:
+ d = iso_to_gregorian(*arg)
+ return self.type.fromdate(d, tzinfo=tz)
+
+ else:
+ raise TypeError(f"Cannot parse single argument of type {type(arg)!r}.")
+
+ elif arg_count == 2:
+ arg_1, arg_2 = args[0], args[1]
+
+ if isinstance(arg_1, datetime):
+ # (datetime, tzinfo/str) -> fromdatetime @ tzinfo
+ if isinstance(arg_2, (dt_tzinfo, str)):
+ return self.type.fromdatetime(arg_1, tzinfo=arg_2)
+ else:
+ raise TypeError(
+ f"Cannot parse two arguments of types 'datetime', {type(arg_2)!r}."
+ )
+
+ elif isinstance(arg_1, date):
+ # (date, tzinfo/str) -> fromdate @ tzinfo
+ if isinstance(arg_2, (dt_tzinfo, str)):
+ return self.type.fromdate(arg_1, tzinfo=arg_2)
+ else:
+ raise TypeError(
+ f"Cannot parse two arguments of types 'date', {type(arg_2)!r}."
+ )
+
+ # (str, format) -> parse @ tzinfo
+ elif isinstance(arg_1, str) and isinstance(arg_2, (str, list)):
+ dt = parser.DateTimeParser(locale).parse(
+ args[0], args[1], normalize_whitespace
+ )
+ return self.type.fromdatetime(dt, tzinfo=tz)
+
+ else:
+ raise TypeError(
+ f"Cannot parse two arguments of types {type(arg_1)!r} and {type(arg_2)!r}."
+ )
+
+ # 3+ args -> datetime-like via constructor
+ else:
+ return self.type(*args, **kwargs)
+
+ def utcnow(self) -> Arrow:
+ """Returns an :class:`Arrow ` object, representing "now" in UTC time.
+
+ Usage::
+
+ >>> import arrow
+ >>> arrow.utcnow()
+
+ """
+
+ return self.type.utcnow()
+
+ def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow:
+ """Returns an :class:`Arrow ` object, representing "now" in the given
+ timezone.
+
+ :param tz: (optional) A :ref:`timezone expression `. Defaults to local time.
+
+ Usage::
+
+ >>> import arrow
+ >>> arrow.now()
+
+
+ >>> arrow.now('US/Pacific')
+
+
+ >>> arrow.now('+02:00')
+
+
+ >>> arrow.now('local')
+
+ """
+
+ if tz is None:
+ tz = dateutil_tz.tzlocal()
+ elif not isinstance(tz, dt_tzinfo):
+ tz = parser.TzinfoParser.parse(tz)
+
+ return self.type.now(tz)
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/formatter.py b/strudel_ex/virt/Lib/site-packages/arrow/formatter.py
new file mode 100644
index 00000000..d45f7153
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/formatter.py
@@ -0,0 +1,148 @@
+"""Provides the :class:`Arrow ` class, an improved formatter for datetimes."""
+
+import re
+import sys
+from datetime import datetime, timedelta
+from typing import Optional, Pattern, cast
+
+from dateutil import tz as dateutil_tz
+
+from arrow import locales
+from arrow.constants import DEFAULT_LOCALE
+
+if sys.version_info < (3, 8): # pragma: no cover
+ from typing_extensions import Final
+else:
+ from typing import Final # pragma: no cover
+
+
+FORMAT_ATOM: Final[str] = "YYYY-MM-DD HH:mm:ssZZ"
+FORMAT_COOKIE: Final[str] = "dddd, DD-MMM-YYYY HH:mm:ss ZZZ"
+FORMAT_RFC822: Final[str] = "ddd, DD MMM YY HH:mm:ss Z"
+FORMAT_RFC850: Final[str] = "dddd, DD-MMM-YY HH:mm:ss ZZZ"
+FORMAT_RFC1036: Final[str] = "ddd, DD MMM YY HH:mm:ss Z"
+FORMAT_RFC1123: Final[str] = "ddd, DD MMM YYYY HH:mm:ss Z"
+FORMAT_RFC2822: Final[str] = "ddd, DD MMM YYYY HH:mm:ss Z"
+FORMAT_RFC3339: Final[str] = "YYYY-MM-DD HH:mm:ssZZ"
+FORMAT_RSS: Final[str] = "ddd, DD MMM YYYY HH:mm:ss Z"
+FORMAT_W3C: Final[str] = "YYYY-MM-DD HH:mm:ssZZ"
+
+
+class DateTimeFormatter:
+ # This pattern matches characters enclosed in square brackets are matched as
+ # an atomic group. For more info on atomic groups and how to they are
+ # emulated in Python's re library, see https://stackoverflow.com/a/13577411/2701578
+
+ _FORMAT_RE: Final[Pattern[str]] = re.compile(
+ r"(\[(?:(?=(?P[^]]))(?P=literal))*\]|YYY?Y?|MM?M?M?|Do|DD?D?D?|d?dd?d?|HH?|hh?|mm?|ss?|SS?S?S?S?S?|ZZ?Z?|a|A|X|x|W)"
+ )
+
+ locale: locales.Locale
+
+ def __init__(self, locale: str = DEFAULT_LOCALE) -> None:
+ self.locale = locales.get_locale(locale)
+
+ def format(cls, dt: datetime, fmt: str) -> str:
+ # FIXME: _format_token() is nullable
+ return cls._FORMAT_RE.sub(
+ lambda m: cast(str, cls._format_token(dt, m.group(0))), fmt
+ )
+
+ def _format_token(self, dt: datetime, token: Optional[str]) -> Optional[str]:
+ if token and token.startswith("[") and token.endswith("]"):
+ return token[1:-1]
+
+ if token == "YYYY":
+ return self.locale.year_full(dt.year)
+ if token == "YY":
+ return self.locale.year_abbreviation(dt.year)
+
+ if token == "MMMM":
+ return self.locale.month_name(dt.month)
+ if token == "MMM":
+ return self.locale.month_abbreviation(dt.month)
+ if token == "MM":
+ return f"{dt.month:02d}"
+ if token == "M":
+ return f"{dt.month}"
+
+ if token == "DDDD":
+ return f"{dt.timetuple().tm_yday:03d}"
+ if token == "DDD":
+ return f"{dt.timetuple().tm_yday}"
+ if token == "DD":
+ return f"{dt.day:02d}"
+ if token == "D":
+ return f"{dt.day}"
+
+ if token == "Do":
+ return self.locale.ordinal_number(dt.day)
+
+ if token == "dddd":
+ return self.locale.day_name(dt.isoweekday())
+ if token == "ddd":
+ return self.locale.day_abbreviation(dt.isoweekday())
+ if token == "d":
+ return f"{dt.isoweekday()}"
+
+ if token == "HH":
+ return f"{dt.hour:02d}"
+ if token == "H":
+ return f"{dt.hour}"
+ if token == "hh":
+ return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12):02d}"
+ if token == "h":
+ return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12)}"
+
+ if token == "mm":
+ return f"{dt.minute:02d}"
+ if token == "m":
+ return f"{dt.minute}"
+
+ if token == "ss":
+ return f"{dt.second:02d}"
+ if token == "s":
+ return f"{dt.second}"
+
+ if token == "SSSSSS":
+ return f"{dt.microsecond:06d}"
+ if token == "SSSSS":
+ return f"{dt.microsecond // 10:05d}"
+ if token == "SSSS":
+ return f"{dt.microsecond // 100:04d}"
+ if token == "SSS":
+ return f"{dt.microsecond // 1000:03d}"
+ if token == "SS":
+ return f"{dt.microsecond // 10000:02d}"
+ if token == "S":
+ return f"{dt.microsecond // 100000}"
+
+ if token == "X":
+ return f"{dt.timestamp()}"
+
+ if token == "x":
+ return f"{dt.timestamp() * 1_000_000:.0f}"
+
+ if token == "ZZZ":
+ return dt.tzname()
+
+ if token in ["ZZ", "Z"]:
+ separator = ":" if token == "ZZ" else ""
+ tz = dateutil_tz.tzutc() if dt.tzinfo is None else dt.tzinfo
+ # `dt` must be aware object. Otherwise, this line will raise AttributeError
+ # https://github.com/arrow-py/arrow/pull/883#discussion_r529866834
+ # datetime awareness: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects
+ total_minutes = int(cast(timedelta, tz.utcoffset(dt)).total_seconds() / 60)
+
+ sign = "+" if total_minutes >= 0 else "-"
+ total_minutes = abs(total_minutes)
+ hour, minute = divmod(total_minutes, 60)
+
+ return f"{sign}{hour:02d}{separator}{minute:02d}"
+
+ if token in ("a", "A"):
+ return self.locale.meridian(dt.hour, token)
+
+ if token == "W":
+ year, week, day = dt.isocalendar()
+ return f"{year}-W{week:02d}-{day}"
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/locales.py b/strudel_ex/virt/Lib/site-packages/arrow/locales.py
new file mode 100644
index 00000000..34b2a098
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/locales.py
@@ -0,0 +1,6485 @@
+"""Provides internationalization for arrow in over 60 languages and dialects."""
+
+import sys
+from math import trunc
+from typing import (
+ Any,
+ ClassVar,
+ Dict,
+ List,
+ Mapping,
+ Optional,
+ Sequence,
+ Tuple,
+ Type,
+ Union,
+ cast,
+)
+
+if sys.version_info < (3, 8): # pragma: no cover
+ from typing_extensions import Literal
+else:
+ from typing import Literal # pragma: no cover
+
+TimeFrameLiteral = Literal[
+ "now",
+ "second",
+ "seconds",
+ "minute",
+ "minutes",
+ "hour",
+ "hours",
+ "day",
+ "days",
+ "week",
+ "weeks",
+ "month",
+ "months",
+ "quarter",
+ "quarters",
+ "year",
+ "years",
+]
+
+_TimeFrameElements = Union[
+ str, Sequence[str], Mapping[str, str], Mapping[str, Sequence[str]]
+]
+
+_locale_map: Dict[str, Type["Locale"]] = {}
+
+
+def get_locale(name: str) -> "Locale":
+ """Returns an appropriate :class:`Locale `
+ corresponding to an input locale name.
+
+ :param name: the name of the locale.
+
+ """
+
+ normalized_locale_name = name.lower().replace("_", "-")
+ locale_cls = _locale_map.get(normalized_locale_name)
+
+ if locale_cls is None:
+ raise ValueError(f"Unsupported locale {normalized_locale_name!r}.")
+
+ return locale_cls()
+
+
+def get_locale_by_class_name(name: str) -> "Locale":
+ """Returns an appropriate :class:`Locale `
+ corresponding to an locale class name.
+
+ :param name: the name of the locale class.
+
+ """
+ locale_cls: Optional[Type[Locale]] = globals().get(name)
+
+ if locale_cls is None:
+ raise ValueError(f"Unsupported locale {name!r}.")
+
+ return locale_cls()
+
+
+class Locale:
+ """Represents locale-specific data and functionality."""
+
+ names: ClassVar[List[str]] = []
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, _TimeFrameElements]] = {
+ "now": "",
+ "second": "",
+ "seconds": "",
+ "minute": "",
+ "minutes": "",
+ "hour": "",
+ "hours": "",
+ "day": "",
+ "days": "",
+ "week": "",
+ "weeks": "",
+ "month": "",
+ "months": "",
+ "quarter": "",
+ "quarters": "",
+ "year": "",
+ "years": "",
+ }
+
+ meridians: ClassVar[Dict[str, str]] = {"am": "", "pm": "", "AM": "", "PM": ""}
+
+ past: ClassVar[str]
+ future: ClassVar[str]
+ and_word: ClassVar[Optional[str]] = None
+
+ month_names: ClassVar[List[str]] = []
+ month_abbreviations: ClassVar[List[str]] = []
+
+ day_names: ClassVar[List[str]] = []
+ day_abbreviations: ClassVar[List[str]] = []
+
+ ordinal_day_re: ClassVar[str] = r"(\d+)"
+
+ _month_name_to_ordinal: Optional[Dict[str, int]]
+
+ def __init_subclass__(cls, **kwargs: Any) -> None:
+ for locale_name in cls.names:
+ if locale_name in _locale_map:
+ raise LookupError(f"Duplicated locale name: {locale_name}")
+
+ _locale_map[locale_name.lower().replace("_", "-")] = cls
+
+ def __init__(self) -> None:
+ self._month_name_to_ordinal = None
+
+ def describe(
+ self,
+ timeframe: TimeFrameLiteral,
+ delta: Union[float, int] = 0,
+ only_distance: bool = False,
+ ) -> str:
+ """Describes a delta within a timeframe in plain language.
+
+ :param timeframe: a string representing a timeframe.
+ :param delta: a quantity representing a delta in a timeframe.
+ :param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
+ """
+
+ humanized = self._format_timeframe(timeframe, trunc(delta))
+ if not only_distance:
+ humanized = self._format_relative(humanized, timeframe, delta)
+
+ return humanized
+
+ def describe_multi(
+ self,
+ timeframes: Sequence[Tuple[TimeFrameLiteral, Union[int, float]]],
+ only_distance: bool = False,
+ ) -> str:
+ """Describes a delta within multiple timeframes in plain language.
+
+ :param timeframes: a list of string, quantity pairs each representing a timeframe and delta.
+ :param only_distance: return only distance eg: "2 hours and 11 seconds" without "in" or "ago" keywords
+ """
+
+ parts = [
+ self._format_timeframe(timeframe, trunc(delta))
+ for timeframe, delta in timeframes
+ ]
+ if self.and_word:
+ parts.insert(-1, self.and_word)
+ humanized = " ".join(parts)
+
+ if not only_distance:
+ # Needed to determine the correct relative string to use
+ timeframe_value = 0
+
+ for _, unit_value in timeframes:
+ if trunc(unit_value) != 0:
+ timeframe_value = trunc(unit_value)
+ break
+
+ # Note it doesn't matter the timeframe unit we use on the call, only the value
+ humanized = self._format_relative(humanized, "seconds", timeframe_value)
+
+ return humanized
+
+ def day_name(self, day: int) -> str:
+ """Returns the day name for a specified day of the week.
+
+ :param day: the ``int`` day of the week (1-7).
+
+ """
+
+ return self.day_names[day]
+
+ def day_abbreviation(self, day: int) -> str:
+ """Returns the day abbreviation for a specified day of the week.
+
+ :param day: the ``int`` day of the week (1-7).
+
+ """
+
+ return self.day_abbreviations[day]
+
+ def month_name(self, month: int) -> str:
+ """Returns the month name for a specified month of the year.
+
+ :param month: the ``int`` month of the year (1-12).
+
+ """
+
+ return self.month_names[month]
+
+ def month_abbreviation(self, month: int) -> str:
+ """Returns the month abbreviation for a specified month of the year.
+
+ :param month: the ``int`` month of the year (1-12).
+
+ """
+
+ return self.month_abbreviations[month]
+
+ def month_number(self, name: str) -> Optional[int]:
+ """Returns the month number for a month specified by name or abbreviation.
+
+ :param name: the month name or abbreviation.
+
+ """
+
+ if self._month_name_to_ordinal is None:
+ self._month_name_to_ordinal = self._name_to_ordinal(self.month_names)
+ self._month_name_to_ordinal.update(
+ self._name_to_ordinal(self.month_abbreviations)
+ )
+
+ return self._month_name_to_ordinal.get(name)
+
+ def year_full(self, year: int) -> str:
+ """Returns the year for specific locale if available
+
+ :param year: the ``int`` year (4-digit)
+ """
+ return f"{year:04d}"
+
+ def year_abbreviation(self, year: int) -> str:
+ """Returns the year for specific locale if available
+
+ :param year: the ``int`` year (4-digit)
+ """
+ return f"{year:04d}"[2:]
+
+ def meridian(self, hour: int, token: Any) -> Optional[str]:
+ """Returns the meridian indicator for a specified hour and format token.
+
+ :param hour: the ``int`` hour of the day.
+ :param token: the format token.
+ """
+
+ if token == "a":
+ return self.meridians["am"] if hour < 12 else self.meridians["pm"]
+ if token == "A":
+ return self.meridians["AM"] if hour < 12 else self.meridians["PM"]
+ return None
+
+ def ordinal_number(self, n: int) -> str:
+ """Returns the ordinal format of a given integer
+
+ :param n: an integer
+ """
+ return self._ordinal_number(n)
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}"
+
+ def _name_to_ordinal(self, lst: Sequence[str]) -> Dict[str, int]:
+ return {elem.lower(): i for i, elem in enumerate(lst[1:], 1)}
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ # TODO: remove cast
+ return cast(str, self.timeframes[timeframe]).format(trunc(abs(delta)))
+
+ def _format_relative(
+ self,
+ humanized: str,
+ timeframe: TimeFrameLiteral,
+ delta: Union[float, int],
+ ) -> str:
+ if timeframe == "now":
+ return humanized
+
+ direction = self.past if delta < 0 else self.future
+
+ return direction.format(humanized)
+
+
+class EnglishLocale(Locale):
+ names = [
+ "en",
+ "en-us",
+ "en-gb",
+ "en-au",
+ "en-be",
+ "en-jp",
+ "en-za",
+ "en-ca",
+ "en-ph",
+ ]
+
+ past = "{0} ago"
+ future = "in {0}"
+ and_word = "and"
+
+ timeframes = {
+ "now": "just now",
+ "second": "a second",
+ "seconds": "{0} seconds",
+ "minute": "a minute",
+ "minutes": "{0} minutes",
+ "hour": "an hour",
+ "hours": "{0} hours",
+ "day": "a day",
+ "days": "{0} days",
+ "week": "a week",
+ "weeks": "{0} weeks",
+ "month": "a month",
+ "months": "{0} months",
+ "quarter": "a quarter",
+ "quarters": "{0} quarters",
+ "year": "a year",
+ "years": "{0} years",
+ }
+
+ meridians = {"am": "am", "pm": "pm", "AM": "AM", "PM": "PM"}
+
+ month_names = [
+ "",
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+ ]
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+ ]
+
+ day_names = [
+ "",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday",
+ ]
+ day_abbreviations = ["", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+
+ ordinal_day_re = r"((?P[2-3]?1(?=st)|[2-3]?2(?=nd)|[2-3]?3(?=rd)|[1-3]?[04-9](?=th)|1[1-3](?=th))(st|nd|rd|th))"
+
+ def _ordinal_number(self, n: int) -> str:
+ if n % 100 not in (11, 12, 13):
+ remainder = abs(n) % 10
+ if remainder == 1:
+ return f"{n}st"
+ elif remainder == 2:
+ return f"{n}nd"
+ elif remainder == 3:
+ return f"{n}rd"
+ return f"{n}th"
+
+ def describe(
+ self,
+ timeframe: TimeFrameLiteral,
+ delta: Union[int, float] = 0,
+ only_distance: bool = False,
+ ) -> str:
+ """Describes a delta within a timeframe in plain language.
+
+ :param timeframe: a string representing a timeframe.
+ :param delta: a quantity representing a delta in a timeframe.
+ :param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
+ """
+
+ humanized = super().describe(timeframe, delta, only_distance)
+ if only_distance and timeframe == "now":
+ humanized = "instantly"
+
+ return humanized
+
+
+class ItalianLocale(Locale):
+ names = ["it", "it-it"]
+ past = "{0} fa"
+ future = "tra {0}"
+ and_word = "e"
+
+ timeframes = {
+ "now": "adesso",
+ "second": "un secondo",
+ "seconds": "{0} qualche secondo",
+ "minute": "un minuto",
+ "minutes": "{0} minuti",
+ "hour": "un'ora",
+ "hours": "{0} ore",
+ "day": "un giorno",
+ "days": "{0} giorni",
+ "week": "una settimana",
+ "weeks": "{0} settimane",
+ "month": "un mese",
+ "months": "{0} mesi",
+ "year": "un anno",
+ "years": "{0} anni",
+ }
+
+ month_names = [
+ "",
+ "gennaio",
+ "febbraio",
+ "marzo",
+ "aprile",
+ "maggio",
+ "giugno",
+ "luglio",
+ "agosto",
+ "settembre",
+ "ottobre",
+ "novembre",
+ "dicembre",
+ ]
+ month_abbreviations = [
+ "",
+ "gen",
+ "feb",
+ "mar",
+ "apr",
+ "mag",
+ "giu",
+ "lug",
+ "ago",
+ "set",
+ "ott",
+ "nov",
+ "dic",
+ ]
+
+ day_names = [
+ "",
+ "lunedì",
+ "martedì",
+ "mercoledì",
+ "giovedì",
+ "venerdì",
+ "sabato",
+ "domenica",
+ ]
+ day_abbreviations = ["", "lun", "mar", "mer", "gio", "ven", "sab", "dom"]
+
+ ordinal_day_re = r"((?P[1-3]?[0-9](?=[ºª]))[ºª])"
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}º"
+
+
+class SpanishLocale(Locale):
+ names = ["es", "es-es"]
+ past = "hace {0}"
+ future = "en {0}"
+ and_word = "y"
+
+ timeframes = {
+ "now": "ahora",
+ "second": "un segundo",
+ "seconds": "{0} segundos",
+ "minute": "un minuto",
+ "minutes": "{0} minutos",
+ "hour": "una hora",
+ "hours": "{0} horas",
+ "day": "un día",
+ "days": "{0} días",
+ "week": "una semana",
+ "weeks": "{0} semanas",
+ "month": "un mes",
+ "months": "{0} meses",
+ "year": "un año",
+ "years": "{0} años",
+ }
+
+ meridians = {"am": "am", "pm": "pm", "AM": "AM", "PM": "PM"}
+
+ month_names = [
+ "",
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre",
+ ]
+ month_abbreviations = [
+ "",
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic",
+ ]
+
+ day_names = [
+ "",
+ "lunes",
+ "martes",
+ "miércoles",
+ "jueves",
+ "viernes",
+ "sábado",
+ "domingo",
+ ]
+ day_abbreviations = ["", "lun", "mar", "mie", "jue", "vie", "sab", "dom"]
+
+ ordinal_day_re = r"((?P[1-3]?[0-9](?=[ºª]))[ºª])"
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}º"
+
+
+class FrenchBaseLocale(Locale):
+ past = "il y a {0}"
+ future = "dans {0}"
+ and_word = "et"
+
+ timeframes = {
+ "now": "maintenant",
+ "second": "une seconde",
+ "seconds": "{0} secondes",
+ "minute": "une minute",
+ "minutes": "{0} minutes",
+ "hour": "une heure",
+ "hours": "{0} heures",
+ "day": "un jour",
+ "days": "{0} jours",
+ "week": "une semaine",
+ "weeks": "{0} semaines",
+ "month": "un mois",
+ "months": "{0} mois",
+ "year": "un an",
+ "years": "{0} ans",
+ }
+
+ month_names = [
+ "",
+ "janvier",
+ "février",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "août",
+ "septembre",
+ "octobre",
+ "novembre",
+ "décembre",
+ ]
+
+ day_names = [
+ "",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi",
+ "dimanche",
+ ]
+ day_abbreviations = ["", "lun", "mar", "mer", "jeu", "ven", "sam", "dim"]
+
+ ordinal_day_re = (
+ r"((?P\b1(?=er\b)|[1-3]?[02-9](?=e\b)|[1-3]1(?=e\b))(er|e)\b)"
+ )
+
+ def _ordinal_number(self, n: int) -> str:
+ if abs(n) == 1:
+ return f"{n}er"
+ return f"{n}e"
+
+
+class FrenchLocale(FrenchBaseLocale, Locale):
+ names = ["fr", "fr-fr"]
+
+ month_abbreviations = [
+ "",
+ "janv",
+ "févr",
+ "mars",
+ "avr",
+ "mai",
+ "juin",
+ "juil",
+ "août",
+ "sept",
+ "oct",
+ "nov",
+ "déc",
+ ]
+
+
+class FrenchCanadianLocale(FrenchBaseLocale, Locale):
+ names = ["fr-ca"]
+
+ month_abbreviations = [
+ "",
+ "janv",
+ "févr",
+ "mars",
+ "avr",
+ "mai",
+ "juin",
+ "juill",
+ "août",
+ "sept",
+ "oct",
+ "nov",
+ "déc",
+ ]
+
+
+class GreekLocale(Locale):
+ names = ["el", "el-gr"]
+
+ past = "{0} πριν"
+ future = "σε {0}"
+ and_word = "και"
+
+ timeframes = {
+ "now": "τώρα",
+ "second": "ένα δεύτερο",
+ "seconds": "{0} δευτερόλεπτα",
+ "minute": "ένα λεπτό",
+ "minutes": "{0} λεπτά",
+ "hour": "μία ώρα",
+ "hours": "{0} ώρες",
+ "day": "μία μέρα",
+ "days": "{0} μέρες",
+ "week": "μία εβδομάδα",
+ "weeks": "{0} εβδομάδες",
+ "month": "ένα μήνα",
+ "months": "{0} μήνες",
+ "year": "ένα χρόνο",
+ "years": "{0} χρόνια",
+ }
+
+ month_names = [
+ "",
+ "Ιανουαρίου",
+ "Φεβρουαρίου",
+ "Μαρτίου",
+ "Απριλίου",
+ "Μαΐου",
+ "Ιουνίου",
+ "Ιουλίου",
+ "Αυγούστου",
+ "Σεπτεμβρίου",
+ "Οκτωβρίου",
+ "Νοεμβρίου",
+ "Δεκεμβρίου",
+ ]
+ month_abbreviations = [
+ "",
+ "Ιαν",
+ "Φεβ",
+ "Μαρ",
+ "Απρ",
+ "Μαϊ",
+ "Ιον",
+ "Ιολ",
+ "Αυγ",
+ "Σεπ",
+ "Οκτ",
+ "Νοε",
+ "Δεκ",
+ ]
+
+ day_names = [
+ "",
+ "Δευτέρα",
+ "Τρίτη",
+ "Τετάρτη",
+ "Πέμπτη",
+ "Παρασκευή",
+ "Σάββατο",
+ "Κυριακή",
+ ]
+ day_abbreviations = ["", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ", "Κυρ"]
+
+
+class JapaneseLocale(Locale):
+ names = ["ja", "ja-jp"]
+
+ past = "{0}前"
+ future = "{0}後"
+ and_word = ""
+
+ timeframes = {
+ "now": "現在",
+ "second": "1秒",
+ "seconds": "{0}秒",
+ "minute": "1分",
+ "minutes": "{0}分",
+ "hour": "1時間",
+ "hours": "{0}時間",
+ "day": "1日",
+ "days": "{0}日",
+ "week": "1週間",
+ "weeks": "{0}週間",
+ "month": "1ヶ月",
+ "months": "{0}ヶ月",
+ "year": "1年",
+ "years": "{0}年",
+ }
+
+ month_names = [
+ "",
+ "1月",
+ "2月",
+ "3月",
+ "4月",
+ "5月",
+ "6月",
+ "7月",
+ "8月",
+ "9月",
+ "10月",
+ "11月",
+ "12月",
+ ]
+ month_abbreviations = [
+ "",
+ " 1",
+ " 2",
+ " 3",
+ " 4",
+ " 5",
+ " 6",
+ " 7",
+ " 8",
+ " 9",
+ "10",
+ "11",
+ "12",
+ ]
+
+ day_names = ["", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日", "日曜日"]
+ day_abbreviations = ["", "月", "火", "水", "木", "金", "土", "日"]
+
+
+class SwedishLocale(Locale):
+ names = ["sv", "sv-se"]
+
+ past = "för {0} sen"
+ future = "om {0}"
+ and_word = "och"
+
+ timeframes = {
+ "now": "just nu",
+ "second": "en sekund",
+ "seconds": "{0} sekunder",
+ "minute": "en minut",
+ "minutes": "{0} minuter",
+ "hour": "en timme",
+ "hours": "{0} timmar",
+ "day": "en dag",
+ "days": "{0} dagar",
+ "week": "en vecka",
+ "weeks": "{0} veckor",
+ "month": "en månad",
+ "months": "{0} månader",
+ "year": "ett år",
+ "years": "{0} år",
+ }
+
+ month_names = [
+ "",
+ "januari",
+ "februari",
+ "mars",
+ "april",
+ "maj",
+ "juni",
+ "juli",
+ "augusti",
+ "september",
+ "oktober",
+ "november",
+ "december",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maj",
+ "jun",
+ "jul",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "måndag",
+ "tisdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "lördag",
+ "söndag",
+ ]
+ day_abbreviations = ["", "mån", "tis", "ons", "tor", "fre", "lör", "sön"]
+
+
+class FinnishLocale(Locale):
+ names = ["fi", "fi-fi"]
+
+ # The finnish grammar is very complex, and its hard to convert
+ # 1-to-1 to something like English.
+
+ past = "{0} sitten"
+ future = "{0} kuluttua"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "juuri nyt",
+ "second": {"past": "sekunti", "future": "sekunnin"},
+ "seconds": {"past": "{0} sekuntia", "future": "{0} sekunnin"},
+ "minute": {"past": "minuutti", "future": "minuutin"},
+ "minutes": {"past": "{0} minuuttia", "future": "{0} minuutin"},
+ "hour": {"past": "tunti", "future": "tunnin"},
+ "hours": {"past": "{0} tuntia", "future": "{0} tunnin"},
+ "day": {"past": "päivä", "future": "päivän"},
+ "days": {"past": "{0} päivää", "future": "{0} päivän"},
+ "week": {"past": "viikko", "future": "viikon"},
+ "weeks": {"past": "{0} viikkoa", "future": "{0} viikon"},
+ "month": {"past": "kuukausi", "future": "kuukauden"},
+ "months": {"past": "{0} kuukautta", "future": "{0} kuukauden"},
+ "year": {"past": "vuosi", "future": "vuoden"},
+ "years": {"past": "{0} vuotta", "future": "{0} vuoden"},
+ }
+
+ # Months and days are lowercase in Finnish
+ month_names = [
+ "",
+ "tammikuu",
+ "helmikuu",
+ "maaliskuu",
+ "huhtikuu",
+ "toukokuu",
+ "kesäkuu",
+ "heinäkuu",
+ "elokuu",
+ "syyskuu",
+ "lokakuu",
+ "marraskuu",
+ "joulukuu",
+ ]
+
+ month_abbreviations = [
+ "",
+ "tammi",
+ "helmi",
+ "maalis",
+ "huhti",
+ "touko",
+ "kesä",
+ "heinä",
+ "elo",
+ "syys",
+ "loka",
+ "marras",
+ "joulu",
+ ]
+
+ day_names = [
+ "",
+ "maanantai",
+ "tiistai",
+ "keskiviikko",
+ "torstai",
+ "perjantai",
+ "lauantai",
+ "sunnuntai",
+ ]
+
+ day_abbreviations = ["", "ma", "ti", "ke", "to", "pe", "la", "su"]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, Mapping):
+ if delta < 0:
+ form = form["past"]
+ else:
+ form = form["future"]
+
+ return form.format(abs(delta))
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}."
+
+
+class ChineseCNLocale(Locale):
+ names = ["zh", "zh-cn"]
+
+ past = "{0}前"
+ future = "{0}后"
+
+ timeframes = {
+ "now": "刚才",
+ "second": "1秒",
+ "seconds": "{0}秒",
+ "minute": "1分钟",
+ "minutes": "{0}分钟",
+ "hour": "1小时",
+ "hours": "{0}小时",
+ "day": "1天",
+ "days": "{0}天",
+ "week": "1周",
+ "weeks": "{0}周",
+ "month": "1个月",
+ "months": "{0}个月",
+ "year": "1年",
+ "years": "{0}年",
+ }
+
+ month_names = [
+ "",
+ "一月",
+ "二月",
+ "三月",
+ "四月",
+ "五月",
+ "六月",
+ "七月",
+ "八月",
+ "九月",
+ "十月",
+ "十一月",
+ "十二月",
+ ]
+ month_abbreviations = [
+ "",
+ " 1",
+ " 2",
+ " 3",
+ " 4",
+ " 5",
+ " 6",
+ " 7",
+ " 8",
+ " 9",
+ "10",
+ "11",
+ "12",
+ ]
+
+ day_names = ["", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
+ day_abbreviations = ["", "一", "二", "三", "四", "五", "六", "日"]
+
+
+class ChineseTWLocale(Locale):
+ names = ["zh-tw"]
+
+ past = "{0}前"
+ future = "{0}後"
+ and_word = "和"
+
+ timeframes = {
+ "now": "剛才",
+ "second": "1秒",
+ "seconds": "{0}秒",
+ "minute": "1分鐘",
+ "minutes": "{0}分鐘",
+ "hour": "1小時",
+ "hours": "{0}小時",
+ "day": "1天",
+ "days": "{0}天",
+ "week": "1週",
+ "weeks": "{0}週",
+ "month": "1個月",
+ "months": "{0}個月",
+ "year": "1年",
+ "years": "{0}年",
+ }
+
+ month_names = [
+ "",
+ "1月",
+ "2月",
+ "3月",
+ "4月",
+ "5月",
+ "6月",
+ "7月",
+ "8月",
+ "9月",
+ "10月",
+ "11月",
+ "12月",
+ ]
+ month_abbreviations = [
+ "",
+ " 1",
+ " 2",
+ " 3",
+ " 4",
+ " 5",
+ " 6",
+ " 7",
+ " 8",
+ " 9",
+ "10",
+ "11",
+ "12",
+ ]
+
+ day_names = ["", "週一", "週二", "週三", "週四", "週五", "週六", "週日"]
+ day_abbreviations = ["", "一", "二", "三", "四", "五", "六", "日"]
+
+
+class HongKongLocale(Locale):
+ names = ["zh-hk"]
+
+ past = "{0}前"
+ future = "{0}後"
+
+ timeframes = {
+ "now": "剛才",
+ "second": "1秒",
+ "seconds": "{0}秒",
+ "minute": "1分鐘",
+ "minutes": "{0}分鐘",
+ "hour": "1小時",
+ "hours": "{0}小時",
+ "day": "1天",
+ "days": "{0}天",
+ "week": "1星期",
+ "weeks": "{0}星期",
+ "month": "1個月",
+ "months": "{0}個月",
+ "year": "1年",
+ "years": "{0}年",
+ }
+
+ month_names = [
+ "",
+ "1月",
+ "2月",
+ "3月",
+ "4月",
+ "5月",
+ "6月",
+ "7月",
+ "8月",
+ "9月",
+ "10月",
+ "11月",
+ "12月",
+ ]
+ month_abbreviations = [
+ "",
+ " 1",
+ " 2",
+ " 3",
+ " 4",
+ " 5",
+ " 6",
+ " 7",
+ " 8",
+ " 9",
+ "10",
+ "11",
+ "12",
+ ]
+
+ day_names = ["", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
+ day_abbreviations = ["", "一", "二", "三", "四", "五", "六", "日"]
+
+
+class KoreanLocale(Locale):
+ names = ["ko", "ko-kr"]
+
+ past = "{0} 전"
+ future = "{0} 후"
+
+ timeframes = {
+ "now": "지금",
+ "second": "1초",
+ "seconds": "{0}초",
+ "minute": "1분",
+ "minutes": "{0}분",
+ "hour": "한시간",
+ "hours": "{0}시간",
+ "day": "하루",
+ "days": "{0}일",
+ "week": "1주",
+ "weeks": "{0}주",
+ "month": "한달",
+ "months": "{0}개월",
+ "year": "1년",
+ "years": "{0}년",
+ }
+
+ special_dayframes = {
+ -3: "그끄제",
+ -2: "그제",
+ -1: "어제",
+ 1: "내일",
+ 2: "모레",
+ 3: "글피",
+ 4: "그글피",
+ }
+
+ special_yearframes = {-2: "제작년", -1: "작년", 1: "내년", 2: "내후년"}
+
+ month_names = [
+ "",
+ "1월",
+ "2월",
+ "3월",
+ "4월",
+ "5월",
+ "6월",
+ "7월",
+ "8월",
+ "9월",
+ "10월",
+ "11월",
+ "12월",
+ ]
+ month_abbreviations = [
+ "",
+ " 1",
+ " 2",
+ " 3",
+ " 4",
+ " 5",
+ " 6",
+ " 7",
+ " 8",
+ " 9",
+ "10",
+ "11",
+ "12",
+ ]
+
+ day_names = ["", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일", "일요일"]
+ day_abbreviations = ["", "월", "화", "수", "목", "금", "토", "일"]
+
+ def _ordinal_number(self, n: int) -> str:
+ ordinals = ["0", "첫", "두", "세", "네", "다섯", "여섯", "일곱", "여덟", "아홉", "열"]
+ if n < len(ordinals):
+ return f"{ordinals[n]}번째"
+ return f"{n}번째"
+
+ def _format_relative(
+ self,
+ humanized: str,
+ timeframe: TimeFrameLiteral,
+ delta: Union[float, int],
+ ) -> str:
+ if timeframe in ("day", "days"):
+ special = self.special_dayframes.get(int(delta))
+ if special:
+ return special
+ elif timeframe in ("year", "years"):
+ special = self.special_yearframes.get(int(delta))
+ if special:
+ return special
+
+ return super()._format_relative(humanized, timeframe, delta)
+
+
+# derived locale types & implementations.
+class DutchLocale(Locale):
+ names = ["nl", "nl-nl"]
+
+ past = "{0} geleden"
+ future = "over {0}"
+
+ timeframes = {
+ "now": "nu",
+ "second": "een seconde",
+ "seconds": "{0} seconden",
+ "minute": "een minuut",
+ "minutes": "{0} minuten",
+ "hour": "een uur",
+ "hours": "{0} uur",
+ "day": "een dag",
+ "days": "{0} dagen",
+ "week": "een week",
+ "weeks": "{0} weken",
+ "month": "een maand",
+ "months": "{0} maanden",
+ "year": "een jaar",
+ "years": "{0} jaar",
+ }
+
+ # In Dutch names of months and days are not starting with a capital letter
+ # like in the English language.
+ month_names = [
+ "",
+ "januari",
+ "februari",
+ "maart",
+ "april",
+ "mei",
+ "juni",
+ "juli",
+ "augustus",
+ "september",
+ "oktober",
+ "november",
+ "december",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mrt",
+ "apr",
+ "mei",
+ "jun",
+ "jul",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "maandag",
+ "dinsdag",
+ "woensdag",
+ "donderdag",
+ "vrijdag",
+ "zaterdag",
+ "zondag",
+ ]
+ day_abbreviations = ["", "ma", "di", "wo", "do", "vr", "za", "zo"]
+
+
+class SlavicBaseLocale(Locale):
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+ delta = abs(delta)
+
+ if isinstance(form, Mapping):
+ if delta % 10 == 1 and delta % 100 != 11:
+ form = form["singular"]
+ elif 2 <= delta % 10 <= 4 and (delta % 100 < 10 or delta % 100 >= 20):
+ form = form["dual"]
+ else:
+ form = form["plural"]
+
+ return form.format(delta)
+
+
+class BelarusianLocale(SlavicBaseLocale):
+ names = ["be", "be-by"]
+
+ past = "{0} таму"
+ future = "праз {0}"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "зараз",
+ "second": "секунду",
+ "seconds": "{0} некалькі секунд",
+ "minute": "хвіліну",
+ "minutes": {
+ "singular": "{0} хвіліну",
+ "dual": "{0} хвіліны",
+ "plural": "{0} хвілін",
+ },
+ "hour": "гадзіну",
+ "hours": {
+ "singular": "{0} гадзіну",
+ "dual": "{0} гадзіны",
+ "plural": "{0} гадзін",
+ },
+ "day": "дзень",
+ "days": {"singular": "{0} дзень", "dual": "{0} дні", "plural": "{0} дзён"},
+ "month": "месяц",
+ "months": {
+ "singular": "{0} месяц",
+ "dual": "{0} месяцы",
+ "plural": "{0} месяцаў",
+ },
+ "year": "год",
+ "years": {"singular": "{0} год", "dual": "{0} гады", "plural": "{0} гадоў"},
+ }
+
+ month_names = [
+ "",
+ "студзеня",
+ "лютага",
+ "сакавіка",
+ "красавіка",
+ "траўня",
+ "чэрвеня",
+ "ліпеня",
+ "жніўня",
+ "верасня",
+ "кастрычніка",
+ "лістапада",
+ "снежня",
+ ]
+ month_abbreviations = [
+ "",
+ "студ",
+ "лют",
+ "сак",
+ "крас",
+ "трав",
+ "чэрв",
+ "ліп",
+ "жнів",
+ "вер",
+ "каст",
+ "ліст",
+ "снеж",
+ ]
+
+ day_names = [
+ "",
+ "панядзелак",
+ "аўторак",
+ "серада",
+ "чацвер",
+ "пятніца",
+ "субота",
+ "нядзеля",
+ ]
+ day_abbreviations = ["", "пн", "ат", "ср", "чц", "пт", "сб", "нд"]
+
+
+class PolishLocale(SlavicBaseLocale):
+ names = ["pl", "pl-pl"]
+
+ past = "{0} temu"
+ future = "za {0}"
+
+ # The nouns should be in genitive case (Polish: "dopełniacz")
+ # in order to correctly form `past` & `future` expressions.
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "teraz",
+ "second": "sekundę",
+ "seconds": {
+ "singular": "{0} sekund",
+ "dual": "{0} sekundy",
+ "plural": "{0} sekund",
+ },
+ "minute": "minutę",
+ "minutes": {
+ "singular": "{0} minut",
+ "dual": "{0} minuty",
+ "plural": "{0} minut",
+ },
+ "hour": "godzinę",
+ "hours": {
+ "singular": "{0} godzin",
+ "dual": "{0} godziny",
+ "plural": "{0} godzin",
+ },
+ "day": "dzień",
+ "days": "{0} dni",
+ "week": "tydzień",
+ "weeks": {
+ "singular": "{0} tygodni",
+ "dual": "{0} tygodnie",
+ "plural": "{0} tygodni",
+ },
+ "month": "miesiąc",
+ "months": {
+ "singular": "{0} miesięcy",
+ "dual": "{0} miesiące",
+ "plural": "{0} miesięcy",
+ },
+ "year": "rok",
+ "years": {"singular": "{0} lat", "dual": "{0} lata", "plural": "{0} lat"},
+ }
+
+ month_names = [
+ "",
+ "styczeń",
+ "luty",
+ "marzec",
+ "kwiecień",
+ "maj",
+ "czerwiec",
+ "lipiec",
+ "sierpień",
+ "wrzesień",
+ "październik",
+ "listopad",
+ "grudzień",
+ ]
+ month_abbreviations = [
+ "",
+ "sty",
+ "lut",
+ "mar",
+ "kwi",
+ "maj",
+ "cze",
+ "lip",
+ "sie",
+ "wrz",
+ "paź",
+ "lis",
+ "gru",
+ ]
+
+ day_names = [
+ "",
+ "poniedziałek",
+ "wtorek",
+ "środa",
+ "czwartek",
+ "piątek",
+ "sobota",
+ "niedziela",
+ ]
+ day_abbreviations = ["", "Pn", "Wt", "Śr", "Czw", "Pt", "So", "Nd"]
+
+
+class RussianLocale(SlavicBaseLocale):
+ names = ["ru", "ru-ru"]
+
+ past = "{0} назад"
+ future = "через {0}"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "сейчас",
+ "second": "секунда",
+ "seconds": {
+ "singular": "{0} секунду",
+ "dual": "{0} секунды",
+ "plural": "{0} секунд",
+ },
+ "minute": "минуту",
+ "minutes": {
+ "singular": "{0} минуту",
+ "dual": "{0} минуты",
+ "plural": "{0} минут",
+ },
+ "hour": "час",
+ "hours": {"singular": "{0} час", "dual": "{0} часа", "plural": "{0} часов"},
+ "day": "день",
+ "days": {"singular": "{0} день", "dual": "{0} дня", "plural": "{0} дней"},
+ "week": "неделю",
+ "weeks": {
+ "singular": "{0} неделю",
+ "dual": "{0} недели",
+ "plural": "{0} недель",
+ },
+ "month": "месяц",
+ "months": {
+ "singular": "{0} месяц",
+ "dual": "{0} месяца",
+ "plural": "{0} месяцев",
+ },
+ "quarter": "квартал",
+ "quarters": {
+ "singular": "{0} квартал",
+ "dual": "{0} квартала",
+ "plural": "{0} кварталов",
+ },
+ "year": "год",
+ "years": {"singular": "{0} год", "dual": "{0} года", "plural": "{0} лет"},
+ }
+
+ month_names = [
+ "",
+ "января",
+ "февраля",
+ "марта",
+ "апреля",
+ "мая",
+ "июня",
+ "июля",
+ "августа",
+ "сентября",
+ "октября",
+ "ноября",
+ "декабря",
+ ]
+ month_abbreviations = [
+ "",
+ "янв",
+ "фев",
+ "мар",
+ "апр",
+ "май",
+ "июн",
+ "июл",
+ "авг",
+ "сен",
+ "окт",
+ "ноя",
+ "дек",
+ ]
+
+ day_names = [
+ "",
+ "понедельник",
+ "вторник",
+ "среда",
+ "четверг",
+ "пятница",
+ "суббота",
+ "воскресенье",
+ ]
+ day_abbreviations = ["", "пн", "вт", "ср", "чт", "пт", "сб", "вс"]
+
+
+class AfrikaansLocale(Locale):
+ names = ["af", "af-nl"]
+
+ past = "{0} gelede"
+ future = "in {0}"
+
+ timeframes = {
+ "now": "nou",
+ "second": "n sekonde",
+ "seconds": "{0} sekondes",
+ "minute": "minuut",
+ "minutes": "{0} minute",
+ "hour": "uur",
+ "hours": "{0} ure",
+ "day": "een dag",
+ "days": "{0} dae",
+ "month": "een maand",
+ "months": "{0} maande",
+ "year": "een jaar",
+ "years": "{0} jaar",
+ }
+
+ month_names = [
+ "",
+ "Januarie",
+ "Februarie",
+ "Maart",
+ "April",
+ "Mei",
+ "Junie",
+ "Julie",
+ "Augustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember",
+ ]
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mrt",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des",
+ ]
+
+ day_names = [
+ "",
+ "Maandag",
+ "Dinsdag",
+ "Woensdag",
+ "Donderdag",
+ "Vrydag",
+ "Saterdag",
+ "Sondag",
+ ]
+ day_abbreviations = ["", "Ma", "Di", "Wo", "Do", "Vr", "Za", "So"]
+
+
+class BulgarianLocale(SlavicBaseLocale):
+ names = ["bg", "bg-bg"]
+
+ past = "{0} назад"
+ future = "напред {0}"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "сега",
+ "second": "секунда",
+ "seconds": "{0} няколко секунди",
+ "minute": "минута",
+ "minutes": {
+ "singular": "{0} минута",
+ "dual": "{0} минути",
+ "plural": "{0} минути",
+ },
+ "hour": "час",
+ "hours": {"singular": "{0} час", "dual": "{0} часа", "plural": "{0} часа"},
+ "day": "ден",
+ "days": {"singular": "{0} ден", "dual": "{0} дни", "plural": "{0} дни"},
+ "month": "месец",
+ "months": {
+ "singular": "{0} месец",
+ "dual": "{0} месеца",
+ "plural": "{0} месеца",
+ },
+ "year": "година",
+ "years": {
+ "singular": "{0} година",
+ "dual": "{0} години",
+ "plural": "{0} години",
+ },
+ }
+
+ month_names = [
+ "",
+ "януари",
+ "февруари",
+ "март",
+ "април",
+ "май",
+ "юни",
+ "юли",
+ "август",
+ "септември",
+ "октомври",
+ "ноември",
+ "декември",
+ ]
+ month_abbreviations = [
+ "",
+ "ян",
+ "февр",
+ "март",
+ "апр",
+ "май",
+ "юни",
+ "юли",
+ "авг",
+ "септ",
+ "окт",
+ "ноем",
+ "дек",
+ ]
+
+ day_names = [
+ "",
+ "понеделник",
+ "вторник",
+ "сряда",
+ "четвъртък",
+ "петък",
+ "събота",
+ "неделя",
+ ]
+ day_abbreviations = ["", "пон", "вт", "ср", "четв", "пет", "съб", "нед"]
+
+
+class UkrainianLocale(SlavicBaseLocale):
+ names = ["ua", "uk", "uk-ua"]
+
+ past = "{0} тому"
+ future = "за {0}"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "зараз",
+ "second": "секунда",
+ "seconds": "{0} кілька секунд",
+ "minute": "хвилину",
+ "minutes": {
+ "singular": "{0} хвилину",
+ "dual": "{0} хвилини",
+ "plural": "{0} хвилин",
+ },
+ "hour": "годину",
+ "hours": {
+ "singular": "{0} годину",
+ "dual": "{0} години",
+ "plural": "{0} годин",
+ },
+ "day": "день",
+ "days": {"singular": "{0} день", "dual": "{0} дні", "plural": "{0} днів"},
+ "month": "місяць",
+ "months": {
+ "singular": "{0} місяць",
+ "dual": "{0} місяці",
+ "plural": "{0} місяців",
+ },
+ "year": "рік",
+ "years": {"singular": "{0} рік", "dual": "{0} роки", "plural": "{0} років"},
+ }
+
+ month_names = [
+ "",
+ "січня",
+ "лютого",
+ "березня",
+ "квітня",
+ "травня",
+ "червня",
+ "липня",
+ "серпня",
+ "вересня",
+ "жовтня",
+ "листопада",
+ "грудня",
+ ]
+ month_abbreviations = [
+ "",
+ "січ",
+ "лют",
+ "бер",
+ "квіт",
+ "трав",
+ "черв",
+ "лип",
+ "серп",
+ "вер",
+ "жовт",
+ "лист",
+ "груд",
+ ]
+
+ day_names = [
+ "",
+ "понеділок",
+ "вівторок",
+ "середа",
+ "четвер",
+ "п’ятниця",
+ "субота",
+ "неділя",
+ ]
+ day_abbreviations = ["", "пн", "вт", "ср", "чт", "пт", "сб", "нд"]
+
+
+class MacedonianLocale(SlavicBaseLocale):
+ names = ["mk", "mk-mk"]
+
+ past = "пред {0}"
+ future = "за {0}"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "сега",
+ "second": "една секунда",
+ "seconds": {
+ "singular": "{0} секунда",
+ "dual": "{0} секунди",
+ "plural": "{0} секунди",
+ },
+ "minute": "една минута",
+ "minutes": {
+ "singular": "{0} минута",
+ "dual": "{0} минути",
+ "plural": "{0} минути",
+ },
+ "hour": "еден саат",
+ "hours": {"singular": "{0} саат", "dual": "{0} саати", "plural": "{0} саати"},
+ "day": "еден ден",
+ "days": {"singular": "{0} ден", "dual": "{0} дена", "plural": "{0} дена"},
+ "week": "една недела",
+ "weeks": {
+ "singular": "{0} недела",
+ "dual": "{0} недели",
+ "plural": "{0} недели",
+ },
+ "month": "еден месец",
+ "months": {
+ "singular": "{0} месец",
+ "dual": "{0} месеци",
+ "plural": "{0} месеци",
+ },
+ "year": "една година",
+ "years": {
+ "singular": "{0} година",
+ "dual": "{0} години",
+ "plural": "{0} години",
+ },
+ }
+
+ meridians = {"am": "дп", "pm": "пп", "AM": "претпладне", "PM": "попладне"}
+
+ month_names = [
+ "",
+ "Јануари",
+ "Февруари",
+ "Март",
+ "Април",
+ "Мај",
+ "Јуни",
+ "Јули",
+ "Август",
+ "Септември",
+ "Октомври",
+ "Ноември",
+ "Декември",
+ ]
+ month_abbreviations = [
+ "",
+ "Јан",
+ "Фев",
+ "Мар",
+ "Апр",
+ "Мај",
+ "Јун",
+ "Јул",
+ "Авг",
+ "Септ",
+ "Окт",
+ "Ноем",
+ "Декем",
+ ]
+
+ day_names = [
+ "",
+ "Понеделник",
+ "Вторник",
+ "Среда",
+ "Четврток",
+ "Петок",
+ "Сабота",
+ "Недела",
+ ]
+ day_abbreviations = [
+ "",
+ "Пон",
+ "Вт",
+ "Сре",
+ "Чет",
+ "Пет",
+ "Саб",
+ "Нед",
+ ]
+
+
+class GermanBaseLocale(Locale):
+ past = "vor {0}"
+ future = "in {0}"
+ and_word = "und"
+
+ timeframes: ClassVar[Dict[TimeFrameLiteral, str]] = {
+ "now": "gerade eben",
+ "second": "einer Sekunde",
+ "seconds": "{0} Sekunden",
+ "minute": "einer Minute",
+ "minutes": "{0} Minuten",
+ "hour": "einer Stunde",
+ "hours": "{0} Stunden",
+ "day": "einem Tag",
+ "days": "{0} Tagen",
+ "week": "einer Woche",
+ "weeks": "{0} Wochen",
+ "month": "einem Monat",
+ "months": "{0} Monaten",
+ "year": "einem Jahr",
+ "years": "{0} Jahren",
+ }
+
+ timeframes_only_distance = timeframes.copy()
+ timeframes_only_distance["second"] = "eine Sekunde"
+ timeframes_only_distance["minute"] = "eine Minute"
+ timeframes_only_distance["hour"] = "eine Stunde"
+ timeframes_only_distance["day"] = "ein Tag"
+ timeframes_only_distance["days"] = "{0} Tage"
+ timeframes_only_distance["week"] = "eine Woche"
+ timeframes_only_distance["month"] = "ein Monat"
+ timeframes_only_distance["months"] = "{0} Monate"
+ timeframes_only_distance["year"] = "ein Jahr"
+ timeframes_only_distance["years"] = "{0} Jahre"
+
+ month_names = [
+ "",
+ "Januar",
+ "Februar",
+ "März",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mär",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez",
+ ]
+
+ day_names = [
+ "",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag",
+ "Sonntag",
+ ]
+
+ day_abbreviations = ["", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}."
+
+ def describe(
+ self,
+ timeframe: TimeFrameLiteral,
+ delta: Union[int, float] = 0,
+ only_distance: bool = False,
+ ) -> str:
+ """Describes a delta within a timeframe in plain language.
+
+ :param timeframe: a string representing a timeframe.
+ :param delta: a quantity representing a delta in a timeframe.
+ :param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
+ """
+
+ if not only_distance:
+ return super().describe(timeframe, delta, only_distance)
+
+ # German uses a different case without 'in' or 'ago'
+ humanized: str = self.timeframes_only_distance[timeframe].format(
+ trunc(abs(delta))
+ )
+
+ return humanized
+
+
+class GermanLocale(GermanBaseLocale, Locale):
+ names = ["de", "de-de"]
+
+
+class SwissLocale(GermanBaseLocale, Locale):
+ names = ["de-ch"]
+
+
+class AustrianLocale(GermanBaseLocale, Locale):
+ names = ["de-at"]
+
+ month_names = [
+ "",
+ "Jänner",
+ "Februar",
+ "März",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember",
+ ]
+
+
+class NorwegianLocale(Locale):
+ names = ["nb", "nb-no"]
+
+ past = "for {0} siden"
+ future = "om {0}"
+
+ timeframes = {
+ "now": "nå nettopp",
+ "second": "ett sekund",
+ "seconds": "{0} sekunder",
+ "minute": "ett minutt",
+ "minutes": "{0} minutter",
+ "hour": "en time",
+ "hours": "{0} timer",
+ "day": "en dag",
+ "days": "{0} dager",
+ "week": "en uke",
+ "weeks": "{0} uker",
+ "month": "en måned",
+ "months": "{0} måneder",
+ "year": "ett år",
+ "years": "{0} år",
+ }
+
+ month_names = [
+ "",
+ "januar",
+ "februar",
+ "mars",
+ "april",
+ "mai",
+ "juni",
+ "juli",
+ "august",
+ "september",
+ "oktober",
+ "november",
+ "desember",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "mai",
+ "jun",
+ "jul",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "des",
+ ]
+
+ day_names = [
+ "",
+ "mandag",
+ "tirsdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "lørdag",
+ "søndag",
+ ]
+ day_abbreviations = ["", "ma", "ti", "on", "to", "fr", "lø", "sø"]
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}."
+
+
+class NewNorwegianLocale(Locale):
+ names = ["nn", "nn-no"]
+
+ past = "for {0} sidan"
+ future = "om {0}"
+
+ timeframes = {
+ "now": "no nettopp",
+ "second": "eitt sekund",
+ "seconds": "{0} sekund",
+ "minute": "eitt minutt",
+ "minutes": "{0} minutt",
+ "hour": "ein time",
+ "hours": "{0} timar",
+ "day": "ein dag",
+ "days": "{0} dagar",
+ "week": "ei veke",
+ "weeks": "{0} veker",
+ "month": "ein månad",
+ "months": "{0} månader",
+ "year": "eitt år",
+ "years": "{0} år",
+ }
+
+ month_names = [
+ "",
+ "januar",
+ "februar",
+ "mars",
+ "april",
+ "mai",
+ "juni",
+ "juli",
+ "august",
+ "september",
+ "oktober",
+ "november",
+ "desember",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "mai",
+ "jun",
+ "jul",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "des",
+ ]
+
+ day_names = [
+ "",
+ "måndag",
+ "tysdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "laurdag",
+ "sundag",
+ ]
+ day_abbreviations = ["", "må", "ty", "on", "to", "fr", "la", "su"]
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}."
+
+
+class PortugueseLocale(Locale):
+ names = ["pt", "pt-pt"]
+
+ past = "há {0}"
+ future = "em {0}"
+ and_word = "e"
+
+ timeframes = {
+ "now": "agora",
+ "second": "um segundo",
+ "seconds": "{0} segundos",
+ "minute": "um minuto",
+ "minutes": "{0} minutos",
+ "hour": "uma hora",
+ "hours": "{0} horas",
+ "day": "um dia",
+ "days": "{0} dias",
+ "week": "uma semana",
+ "weeks": "{0} semanas",
+ "month": "um mês",
+ "months": "{0} meses",
+ "year": "um ano",
+ "years": "{0} anos",
+ }
+
+ month_names = [
+ "",
+ "Janeiro",
+ "Fevereiro",
+ "Março",
+ "Abril",
+ "Maio",
+ "Junho",
+ "Julho",
+ "Agosto",
+ "Setembro",
+ "Outubro",
+ "Novembro",
+ "Dezembro",
+ ]
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Fev",
+ "Mar",
+ "Abr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Set",
+ "Out",
+ "Nov",
+ "Dez",
+ ]
+
+ day_names = [
+ "",
+ "Segunda-feira",
+ "Terça-feira",
+ "Quarta-feira",
+ "Quinta-feira",
+ "Sexta-feira",
+ "Sábado",
+ "Domingo",
+ ]
+ day_abbreviations = ["", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab", "Dom"]
+
+
+class BrazilianPortugueseLocale(PortugueseLocale):
+ names = ["pt-br"]
+
+ past = "faz {0}"
+
+
+class TagalogLocale(Locale):
+ names = ["tl", "tl-ph"]
+
+ past = "nakaraang {0}"
+ future = "{0} mula ngayon"
+
+ timeframes = {
+ "now": "ngayon lang",
+ "second": "isang segundo",
+ "seconds": "{0} segundo",
+ "minute": "isang minuto",
+ "minutes": "{0} minuto",
+ "hour": "isang oras",
+ "hours": "{0} oras",
+ "day": "isang araw",
+ "days": "{0} araw",
+ "week": "isang linggo",
+ "weeks": "{0} linggo",
+ "month": "isang buwan",
+ "months": "{0} buwan",
+ "year": "isang taon",
+ "years": "{0} taon",
+ }
+
+ month_names = [
+ "",
+ "Enero",
+ "Pebrero",
+ "Marso",
+ "Abril",
+ "Mayo",
+ "Hunyo",
+ "Hulyo",
+ "Agosto",
+ "Setyembre",
+ "Oktubre",
+ "Nobyembre",
+ "Disyembre",
+ ]
+ month_abbreviations = [
+ "",
+ "Ene",
+ "Peb",
+ "Mar",
+ "Abr",
+ "May",
+ "Hun",
+ "Hul",
+ "Ago",
+ "Set",
+ "Okt",
+ "Nob",
+ "Dis",
+ ]
+
+ day_names = [
+ "",
+ "Lunes",
+ "Martes",
+ "Miyerkules",
+ "Huwebes",
+ "Biyernes",
+ "Sabado",
+ "Linggo",
+ ]
+ day_abbreviations = ["", "Lun", "Mar", "Miy", "Huw", "Biy", "Sab", "Lin"]
+
+ meridians = {"am": "nu", "pm": "nh", "AM": "ng umaga", "PM": "ng hapon"}
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"ika-{n}"
+
+
+class VietnameseLocale(Locale):
+ names = ["vi", "vi-vn"]
+
+ past = "{0} trước"
+ future = "{0} nữa"
+
+ timeframes = {
+ "now": "hiện tại",
+ "second": "một giây",
+ "seconds": "{0} giây",
+ "minute": "một phút",
+ "minutes": "{0} phút",
+ "hour": "một giờ",
+ "hours": "{0} giờ",
+ "day": "một ngày",
+ "days": "{0} ngày",
+ "week": "một tuần",
+ "weeks": "{0} tuần",
+ "month": "một tháng",
+ "months": "{0} tháng",
+ "year": "một năm",
+ "years": "{0} năm",
+ }
+
+ month_names = [
+ "",
+ "Tháng Một",
+ "Tháng Hai",
+ "Tháng Ba",
+ "Tháng Tư",
+ "Tháng Năm",
+ "Tháng Sáu",
+ "Tháng Bảy",
+ "Tháng Tám",
+ "Tháng Chín",
+ "Tháng Mười",
+ "Tháng Mười Một",
+ "Tháng Mười Hai",
+ ]
+ month_abbreviations = [
+ "",
+ "Tháng 1",
+ "Tháng 2",
+ "Tháng 3",
+ "Tháng 4",
+ "Tháng 5",
+ "Tháng 6",
+ "Tháng 7",
+ "Tháng 8",
+ "Tháng 9",
+ "Tháng 10",
+ "Tháng 11",
+ "Tháng 12",
+ ]
+
+ day_names = [
+ "",
+ "Thứ Hai",
+ "Thứ Ba",
+ "Thứ Tư",
+ "Thứ Năm",
+ "Thứ Sáu",
+ "Thứ Bảy",
+ "Chủ Nhật",
+ ]
+ day_abbreviations = ["", "Thứ 2", "Thứ 3", "Thứ 4", "Thứ 5", "Thứ 6", "Thứ 7", "CN"]
+
+
+class TurkishLocale(Locale):
+ names = ["tr", "tr-tr"]
+
+ past = "{0} önce"
+ future = "{0} sonra"
+ and_word = "ve"
+
+ timeframes = {
+ "now": "şimdi",
+ "second": "bir saniye",
+ "seconds": "{0} saniye",
+ "minute": "bir dakika",
+ "minutes": "{0} dakika",
+ "hour": "bir saat",
+ "hours": "{0} saat",
+ "day": "bir gün",
+ "days": "{0} gün",
+ "week": "bir hafta",
+ "weeks": "{0} hafta",
+ "month": "bir ay",
+ "months": "{0} ay",
+ "year": "bir yıl",
+ "years": "{0} yıl",
+ }
+
+ meridians = {"am": "öö", "pm": "ös", "AM": "ÖÖ", "PM": "ÖS"}
+
+ month_names = [
+ "",
+ "Ocak",
+ "Şubat",
+ "Mart",
+ "Nisan",
+ "Mayıs",
+ "Haziran",
+ "Temmuz",
+ "Ağustos",
+ "Eylül",
+ "Ekim",
+ "Kasım",
+ "Aralık",
+ ]
+ month_abbreviations = [
+ "",
+ "Oca",
+ "Şub",
+ "Mar",
+ "Nis",
+ "May",
+ "Haz",
+ "Tem",
+ "Ağu",
+ "Eyl",
+ "Eki",
+ "Kas",
+ "Ara",
+ ]
+
+ day_names = [
+ "",
+ "Pazartesi",
+ "Salı",
+ "Çarşamba",
+ "Perşembe",
+ "Cuma",
+ "Cumartesi",
+ "Pazar",
+ ]
+ day_abbreviations = ["", "Pzt", "Sal", "Çar", "Per", "Cum", "Cmt", "Paz"]
+
+
+class AzerbaijaniLocale(Locale):
+ names = ["az", "az-az"]
+
+ past = "{0} əvvəl"
+ future = "{0} sonra"
+
+ timeframes = {
+ "now": "indi",
+ "second": "bir saniyə",
+ "seconds": "{0} saniyə",
+ "minute": "bir dəqiqə",
+ "minutes": "{0} dəqiqə",
+ "hour": "bir saat",
+ "hours": "{0} saat",
+ "day": "bir gün",
+ "days": "{0} gün",
+ "week": "bir həftə",
+ "weeks": "{0} həftə",
+ "month": "bir ay",
+ "months": "{0} ay",
+ "year": "bir il",
+ "years": "{0} il",
+ }
+
+ month_names = [
+ "",
+ "Yanvar",
+ "Fevral",
+ "Mart",
+ "Aprel",
+ "May",
+ "İyun",
+ "İyul",
+ "Avqust",
+ "Sentyabr",
+ "Oktyabr",
+ "Noyabr",
+ "Dekabr",
+ ]
+ month_abbreviations = [
+ "",
+ "Yan",
+ "Fev",
+ "Mar",
+ "Apr",
+ "May",
+ "İyn",
+ "İyl",
+ "Avq",
+ "Sen",
+ "Okt",
+ "Noy",
+ "Dek",
+ ]
+
+ day_names = [
+ "",
+ "Bazar ertəsi",
+ "Çərşənbə axşamı",
+ "Çərşənbə",
+ "Cümə axşamı",
+ "Cümə",
+ "Şənbə",
+ "Bazar",
+ ]
+ day_abbreviations = ["", "Ber", "Çax", "Çər", "Cax", "Cüm", "Şnb", "Bzr"]
+
+
+class ArabicLocale(Locale):
+ names = [
+ "ar",
+ "ar-ae",
+ "ar-bh",
+ "ar-dj",
+ "ar-eg",
+ "ar-eh",
+ "ar-er",
+ "ar-km",
+ "ar-kw",
+ "ar-ly",
+ "ar-om",
+ "ar-qa",
+ "ar-sa",
+ "ar-sd",
+ "ar-so",
+ "ar-ss",
+ "ar-td",
+ "ar-ye",
+ ]
+
+ past = "منذ {0}"
+ future = "خلال {0}"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "الآن",
+ "second": "ثانية",
+ "seconds": {"2": "ثانيتين", "ten": "{0} ثوان", "higher": "{0} ثانية"},
+ "minute": "دقيقة",
+ "minutes": {"2": "دقيقتين", "ten": "{0} دقائق", "higher": "{0} دقيقة"},
+ "hour": "ساعة",
+ "hours": {"2": "ساعتين", "ten": "{0} ساعات", "higher": "{0} ساعة"},
+ "day": "يوم",
+ "days": {"2": "يومين", "ten": "{0} أيام", "higher": "{0} يوم"},
+ "week": "اسبوع",
+ "weeks": {"2": "اسبوعين", "ten": "{0} أسابيع", "higher": "{0} اسبوع"},
+ "month": "شهر",
+ "months": {"2": "شهرين", "ten": "{0} أشهر", "higher": "{0} شهر"},
+ "year": "سنة",
+ "years": {"2": "سنتين", "ten": "{0} سنوات", "higher": "{0} سنة"},
+ }
+
+ month_names = [
+ "",
+ "يناير",
+ "فبراير",
+ "مارس",
+ "أبريل",
+ "مايو",
+ "يونيو",
+ "يوليو",
+ "أغسطس",
+ "سبتمبر",
+ "أكتوبر",
+ "نوفمبر",
+ "ديسمبر",
+ ]
+ month_abbreviations = [
+ "",
+ "يناير",
+ "فبراير",
+ "مارس",
+ "أبريل",
+ "مايو",
+ "يونيو",
+ "يوليو",
+ "أغسطس",
+ "سبتمبر",
+ "أكتوبر",
+ "نوفمبر",
+ "ديسمبر",
+ ]
+
+ day_names = [
+ "",
+ "الإثنين",
+ "الثلاثاء",
+ "الأربعاء",
+ "الخميس",
+ "الجمعة",
+ "السبت",
+ "الأحد",
+ ]
+ day_abbreviations = ["", "إثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت", "أحد"]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+ delta = abs(delta)
+ if isinstance(form, Mapping):
+ if delta == 2:
+ form = form["2"]
+ elif 2 < delta <= 10:
+ form = form["ten"]
+ else:
+ form = form["higher"]
+
+ return form.format(delta)
+
+
+class LevantArabicLocale(ArabicLocale):
+ names = ["ar-iq", "ar-jo", "ar-lb", "ar-ps", "ar-sy"]
+ month_names = [
+ "",
+ "كانون الثاني",
+ "شباط",
+ "آذار",
+ "نيسان",
+ "أيار",
+ "حزيران",
+ "تموز",
+ "آب",
+ "أيلول",
+ "تشرين الأول",
+ "تشرين الثاني",
+ "كانون الأول",
+ ]
+ month_abbreviations = [
+ "",
+ "كانون الثاني",
+ "شباط",
+ "آذار",
+ "نيسان",
+ "أيار",
+ "حزيران",
+ "تموز",
+ "آب",
+ "أيلول",
+ "تشرين الأول",
+ "تشرين الثاني",
+ "كانون الأول",
+ ]
+
+
+class AlgeriaTunisiaArabicLocale(ArabicLocale):
+ names = ["ar-tn", "ar-dz"]
+ month_names = [
+ "",
+ "جانفي",
+ "فيفري",
+ "مارس",
+ "أفريل",
+ "ماي",
+ "جوان",
+ "جويلية",
+ "أوت",
+ "سبتمبر",
+ "أكتوبر",
+ "نوفمبر",
+ "ديسمبر",
+ ]
+ month_abbreviations = [
+ "",
+ "جانفي",
+ "فيفري",
+ "مارس",
+ "أفريل",
+ "ماي",
+ "جوان",
+ "جويلية",
+ "أوت",
+ "سبتمبر",
+ "أكتوبر",
+ "نوفمبر",
+ "ديسمبر",
+ ]
+
+
+class MauritaniaArabicLocale(ArabicLocale):
+ names = ["ar-mr"]
+ month_names = [
+ "",
+ "يناير",
+ "فبراير",
+ "مارس",
+ "إبريل",
+ "مايو",
+ "يونيو",
+ "يوليو",
+ "أغشت",
+ "شتمبر",
+ "أكتوبر",
+ "نوفمبر",
+ "دجمبر",
+ ]
+ month_abbreviations = [
+ "",
+ "يناير",
+ "فبراير",
+ "مارس",
+ "إبريل",
+ "مايو",
+ "يونيو",
+ "يوليو",
+ "أغشت",
+ "شتمبر",
+ "أكتوبر",
+ "نوفمبر",
+ "دجمبر",
+ ]
+
+
+class MoroccoArabicLocale(ArabicLocale):
+ names = ["ar-ma"]
+ month_names = [
+ "",
+ "يناير",
+ "فبراير",
+ "مارس",
+ "أبريل",
+ "ماي",
+ "يونيو",
+ "يوليوز",
+ "غشت",
+ "شتنبر",
+ "أكتوبر",
+ "نونبر",
+ "دجنبر",
+ ]
+ month_abbreviations = [
+ "",
+ "يناير",
+ "فبراير",
+ "مارس",
+ "أبريل",
+ "ماي",
+ "يونيو",
+ "يوليوز",
+ "غشت",
+ "شتنبر",
+ "أكتوبر",
+ "نونبر",
+ "دجنبر",
+ ]
+
+
+class IcelandicLocale(Locale):
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, Mapping):
+ if delta < 0:
+ form = form["past"]
+ elif delta > 0:
+ form = form["future"]
+ else:
+ raise ValueError(
+ "Icelandic Locale does not support units with a delta of zero. "
+ "Please consider making a contribution to fix this issue."
+ )
+ # FIXME: handle when delta is 0
+
+ return form.format(abs(delta))
+
+ names = ["is", "is-is"]
+
+ past = "fyrir {0} síðan"
+ future = "eftir {0}"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "rétt í þessu",
+ "second": {"past": "sekúndu", "future": "sekúndu"},
+ "seconds": {"past": "{0} nokkrum sekúndum", "future": "nokkrar sekúndur"},
+ "minute": {"past": "einni mínútu", "future": "eina mínútu"},
+ "minutes": {"past": "{0} mínútum", "future": "{0} mínútur"},
+ "hour": {"past": "einum tíma", "future": "einn tíma"},
+ "hours": {"past": "{0} tímum", "future": "{0} tíma"},
+ "day": {"past": "einum degi", "future": "einn dag"},
+ "days": {"past": "{0} dögum", "future": "{0} daga"},
+ "month": {"past": "einum mánuði", "future": "einn mánuð"},
+ "months": {"past": "{0} mánuðum", "future": "{0} mánuði"},
+ "year": {"past": "einu ári", "future": "eitt ár"},
+ "years": {"past": "{0} árum", "future": "{0} ár"},
+ }
+
+ meridians = {"am": "f.h.", "pm": "e.h.", "AM": "f.h.", "PM": "e.h."}
+
+ month_names = [
+ "",
+ "janúar",
+ "febrúar",
+ "mars",
+ "apríl",
+ "maí",
+ "júní",
+ "júlí",
+ "ágúst",
+ "september",
+ "október",
+ "nóvember",
+ "desember",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maí",
+ "jún",
+ "júl",
+ "ágú",
+ "sep",
+ "okt",
+ "nóv",
+ "des",
+ ]
+
+ day_names = [
+ "",
+ "mánudagur",
+ "þriðjudagur",
+ "miðvikudagur",
+ "fimmtudagur",
+ "föstudagur",
+ "laugardagur",
+ "sunnudagur",
+ ]
+ day_abbreviations = ["", "mán", "þri", "mið", "fim", "fös", "lau", "sun"]
+
+
+class DanishLocale(Locale):
+ names = ["da", "da-dk"]
+
+ past = "for {0} siden"
+ future = "om {0}"
+ and_word = "og"
+
+ timeframes = {
+ "now": "lige nu",
+ "second": "et sekund",
+ "seconds": "{0} sekunder",
+ "minute": "et minut",
+ "minutes": "{0} minutter",
+ "hour": "en time",
+ "hours": "{0} timer",
+ "day": "en dag",
+ "days": "{0} dage",
+ "week": "en uge",
+ "weeks": "{0} uger",
+ "month": "en måned",
+ "months": "{0} måneder",
+ "year": "et år",
+ "years": "{0} år",
+ }
+
+ month_names = [
+ "",
+ "januar",
+ "februar",
+ "marts",
+ "april",
+ "maj",
+ "juni",
+ "juli",
+ "august",
+ "september",
+ "oktober",
+ "november",
+ "december",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maj",
+ "jun",
+ "jul",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "mandag",
+ "tirsdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "lørdag",
+ "søndag",
+ ]
+ day_abbreviations = ["", "man", "tir", "ons", "tor", "fre", "lør", "søn"]
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}."
+
+
+class MalayalamLocale(Locale):
+ names = ["ml"]
+
+ past = "{0} മുമ്പ്"
+ future = "{0} ശേഷം"
+
+ timeframes = {
+ "now": "ഇപ്പോൾ",
+ "second": "ഒരു നിമിഷം",
+ "seconds": "{0} സെക്കന്റ്",
+ "minute": "ഒരു മിനിറ്റ്",
+ "minutes": "{0} മിനിറ്റ്",
+ "hour": "ഒരു മണിക്കൂർ",
+ "hours": "{0} മണിക്കൂർ",
+ "day": "ഒരു ദിവസം ",
+ "days": "{0} ദിവസം ",
+ "month": "ഒരു മാസം ",
+ "months": "{0} മാസം ",
+ "year": "ഒരു വർഷം ",
+ "years": "{0} വർഷം ",
+ }
+
+ meridians = {
+ "am": "രാവിലെ",
+ "pm": "ഉച്ചക്ക് ശേഷം",
+ "AM": "രാവിലെ",
+ "PM": "ഉച്ചക്ക് ശേഷം",
+ }
+
+ month_names = [
+ "",
+ "ജനുവരി",
+ "ഫെബ്രുവരി",
+ "മാർച്ച്",
+ "ഏപ്രിൽ ",
+ "മെയ് ",
+ "ജൂണ്",
+ "ജൂലൈ",
+ "ഓഗസ്റ്റ്",
+ "സെപ്റ്റംബർ",
+ "ഒക്ടോബർ",
+ "നവംബർ",
+ "ഡിസംബർ",
+ ]
+ month_abbreviations = [
+ "",
+ "ജനു",
+ "ഫെബ് ",
+ "മാർ",
+ "ഏപ്രിൽ",
+ "മേയ്",
+ "ജൂണ്",
+ "ജൂലൈ",
+ "ഓഗസ്റ",
+ "സെപ്റ്റ",
+ "ഒക്ടോ",
+ "നവം",
+ "ഡിസം",
+ ]
+
+ day_names = ["", "തിങ്കള്", "ചൊവ്വ", "ബുധന്", "വ്യാഴം", "വെള്ളി", "ശനി", "ഞായര്"]
+ day_abbreviations = [
+ "",
+ "തിങ്കള്",
+ "ചൊവ്വ",
+ "ബുധന്",
+ "വ്യാഴം",
+ "വെള്ളി",
+ "ശനി",
+ "ഞായര്",
+ ]
+
+
+class HindiLocale(Locale):
+ names = ["hi", "hi-in"]
+
+ past = "{0} पहले"
+ future = "{0} बाद"
+
+ timeframes = {
+ "now": "अभी",
+ "second": "एक पल",
+ "seconds": "{0} सेकंड्",
+ "minute": "एक मिनट ",
+ "minutes": "{0} मिनट ",
+ "hour": "एक घंटा",
+ "hours": "{0} घंटे",
+ "day": "एक दिन",
+ "days": "{0} दिन",
+ "month": "एक माह ",
+ "months": "{0} महीने ",
+ "year": "एक वर्ष ",
+ "years": "{0} साल ",
+ }
+
+ meridians = {"am": "सुबह", "pm": "शाम", "AM": "सुबह", "PM": "शाम"}
+
+ month_names = [
+ "",
+ "जनवरी",
+ "फरवरी",
+ "मार्च",
+ "अप्रैल ",
+ "मई",
+ "जून",
+ "जुलाई",
+ "अगस्त",
+ "सितंबर",
+ "अक्टूबर",
+ "नवंबर",
+ "दिसंबर",
+ ]
+ month_abbreviations = [
+ "",
+ "जन",
+ "फ़र",
+ "मार्च",
+ "अप्रै",
+ "मई",
+ "जून",
+ "जुलाई",
+ "आग",
+ "सित",
+ "अकत",
+ "नवे",
+ "दिस",
+ ]
+
+ day_names = [
+ "",
+ "सोमवार",
+ "मंगलवार",
+ "बुधवार",
+ "गुरुवार",
+ "शुक्रवार",
+ "शनिवार",
+ "रविवार",
+ ]
+ day_abbreviations = ["", "सोम", "मंगल", "बुध", "गुरुवार", "शुक्र", "शनि", "रवि"]
+
+
+class CzechLocale(Locale):
+ names = ["cs", "cs-cz"]
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "Teď",
+ "second": {"past": "vteřina", "future": "vteřina"},
+ "seconds": {
+ "zero": "vteřina",
+ "past": "{0} sekundami",
+ "future-singular": "{0} sekundy",
+ "future-paucal": "{0} sekund",
+ },
+ "minute": {"past": "minutou", "future": "minutu"},
+ "minutes": {
+ "zero": "{0} minut",
+ "past": "{0} minutami",
+ "future-singular": "{0} minuty",
+ "future-paucal": "{0} minut",
+ },
+ "hour": {"past": "hodinou", "future": "hodinu"},
+ "hours": {
+ "zero": "{0} hodin",
+ "past": "{0} hodinami",
+ "future-singular": "{0} hodiny",
+ "future-paucal": "{0} hodin",
+ },
+ "day": {"past": "dnem", "future": "den"},
+ "days": {
+ "zero": "{0} dnů",
+ "past": "{0} dny",
+ "future-singular": "{0} dny",
+ "future-paucal": "{0} dnů",
+ },
+ "week": {"past": "týdnem", "future": "týden"},
+ "weeks": {
+ "zero": "{0} týdnů",
+ "past": "{0} týdny",
+ "future-singular": "{0} týdny",
+ "future-paucal": "{0} týdnů",
+ },
+ "month": {"past": "měsícem", "future": "měsíc"},
+ "months": {
+ "zero": "{0} měsíců",
+ "past": "{0} měsíci",
+ "future-singular": "{0} měsíce",
+ "future-paucal": "{0} měsíců",
+ },
+ "year": {"past": "rokem", "future": "rok"},
+ "years": {
+ "zero": "{0} let",
+ "past": "{0} lety",
+ "future-singular": "{0} roky",
+ "future-paucal": "{0} let",
+ },
+ }
+
+ past = "Před {0}"
+ future = "Za {0}"
+
+ month_names = [
+ "",
+ "leden",
+ "únor",
+ "březen",
+ "duben",
+ "květen",
+ "červen",
+ "červenec",
+ "srpen",
+ "září",
+ "říjen",
+ "listopad",
+ "prosinec",
+ ]
+ month_abbreviations = [
+ "",
+ "led",
+ "úno",
+ "bře",
+ "dub",
+ "kvě",
+ "čvn",
+ "čvc",
+ "srp",
+ "zář",
+ "říj",
+ "lis",
+ "pro",
+ ]
+
+ day_names = [
+ "",
+ "pondělí",
+ "úterý",
+ "středa",
+ "čtvrtek",
+ "pátek",
+ "sobota",
+ "neděle",
+ ]
+ day_abbreviations = ["", "po", "út", "st", "čt", "pá", "so", "ne"]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ """Czech aware time frame format function, takes into account
+ the differences between past and future forms."""
+ abs_delta = abs(delta)
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, str):
+ return form.format(abs_delta)
+
+ if delta == 0:
+ key = "zero" # And *never* use 0 in the singular!
+ elif delta < 0:
+ key = "past"
+ else:
+ # Needed since both regular future and future-singular and future-paucal cases
+ if "future-singular" not in form:
+ key = "future"
+ elif 2 <= abs_delta % 10 <= 4 and (
+ abs_delta % 100 < 10 or abs_delta % 100 >= 20
+ ):
+ key = "future-singular"
+ else:
+ key = "future-paucal"
+
+ form: str = form[key]
+ return form.format(abs_delta)
+
+
+class SlovakLocale(Locale):
+ names = ["sk", "sk-sk"]
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "Teraz",
+ "second": {"past": "sekundou", "future": "sekundu"},
+ "seconds": {
+ "zero": "{0} sekúnd",
+ "past": "{0} sekundami",
+ "future-singular": "{0} sekundy",
+ "future-paucal": "{0} sekúnd",
+ },
+ "minute": {"past": "minútou", "future": "minútu"},
+ "minutes": {
+ "zero": "{0} minút",
+ "past": "{0} minútami",
+ "future-singular": "{0} minúty",
+ "future-paucal": "{0} minút",
+ },
+ "hour": {"past": "hodinou", "future": "hodinu"},
+ "hours": {
+ "zero": "{0} hodín",
+ "past": "{0} hodinami",
+ "future-singular": "{0} hodiny",
+ "future-paucal": "{0} hodín",
+ },
+ "day": {"past": "dňom", "future": "deň"},
+ "days": {
+ "zero": "{0} dní",
+ "past": "{0} dňami",
+ "future-singular": "{0} dni",
+ "future-paucal": "{0} dní",
+ },
+ "week": {"past": "týždňom", "future": "týždeň"},
+ "weeks": {
+ "zero": "{0} týždňov",
+ "past": "{0} týždňami",
+ "future-singular": "{0} týždne",
+ "future-paucal": "{0} týždňov",
+ },
+ "month": {"past": "mesiacom", "future": "mesiac"},
+ "months": {
+ "zero": "{0} mesiacov",
+ "past": "{0} mesiacmi",
+ "future-singular": "{0} mesiace",
+ "future-paucal": "{0} mesiacov",
+ },
+ "year": {"past": "rokom", "future": "rok"},
+ "years": {
+ "zero": "{0} rokov",
+ "past": "{0} rokmi",
+ "future-singular": "{0} roky",
+ "future-paucal": "{0} rokov",
+ },
+ }
+
+ past = "Pred {0}"
+ future = "O {0}"
+ and_word = "a"
+
+ month_names = [
+ "",
+ "január",
+ "február",
+ "marec",
+ "apríl",
+ "máj",
+ "jún",
+ "júl",
+ "august",
+ "september",
+ "október",
+ "november",
+ "december",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "máj",
+ "jún",
+ "júl",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "pondelok",
+ "utorok",
+ "streda",
+ "štvrtok",
+ "piatok",
+ "sobota",
+ "nedeľa",
+ ]
+ day_abbreviations = ["", "po", "ut", "st", "št", "pi", "so", "ne"]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ """Slovak aware time frame format function, takes into account
+ the differences between past and future forms."""
+ abs_delta = abs(delta)
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, str):
+ return form.format(abs_delta)
+
+ if delta == 0:
+ key = "zero" # And *never* use 0 in the singular!
+ elif delta < 0:
+ key = "past"
+ else:
+ if "future-singular" not in form:
+ key = "future"
+ elif 2 <= abs_delta % 10 <= 4 and (
+ abs_delta % 100 < 10 or abs_delta % 100 >= 20
+ ):
+ key = "future-singular"
+ else:
+ key = "future-paucal"
+
+ form: str = form[key]
+ return form.format(abs_delta)
+
+
+class FarsiLocale(Locale):
+ names = ["fa", "fa-ir"]
+
+ past = "{0} قبل"
+ future = "در {0}"
+
+ timeframes = {
+ "now": "اکنون",
+ "second": "یک لحظه",
+ "seconds": "{0} ثانیه",
+ "minute": "یک دقیقه",
+ "minutes": "{0} دقیقه",
+ "hour": "یک ساعت",
+ "hours": "{0} ساعت",
+ "day": "یک روز",
+ "days": "{0} روز",
+ "month": "یک ماه",
+ "months": "{0} ماه",
+ "year": "یک سال",
+ "years": "{0} سال",
+ }
+
+ meridians = {
+ "am": "قبل از ظهر",
+ "pm": "بعد از ظهر",
+ "AM": "قبل از ظهر",
+ "PM": "بعد از ظهر",
+ }
+
+ month_names = [
+ "",
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+ ]
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+ ]
+
+ day_names = [
+ "",
+ "دو شنبه",
+ "سه شنبه",
+ "چهارشنبه",
+ "پنجشنبه",
+ "جمعه",
+ "شنبه",
+ "یکشنبه",
+ ]
+ day_abbreviations = ["", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+
+
+class HebrewLocale(Locale):
+ names = ["he", "he-il"]
+
+ past = "לפני {0}"
+ future = "בעוד {0}"
+ and_word = "ו"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "הרגע",
+ "second": "שנייה",
+ "seconds": "{0} שניות",
+ "minute": "דקה",
+ "minutes": "{0} דקות",
+ "hour": "שעה",
+ "hours": {"2": "שעתיים", "ten": "{0} שעות", "higher": "{0} שעות"},
+ "day": "יום",
+ "days": {"2": "יומיים", "ten": "{0} ימים", "higher": "{0} יום"},
+ "week": "שבוע",
+ "weeks": {"2": "שבועיים", "ten": "{0} שבועות", "higher": "{0} שבועות"},
+ "month": "חודש",
+ "months": {"2": "חודשיים", "ten": "{0} חודשים", "higher": "{0} חודשים"},
+ "year": "שנה",
+ "years": {"2": "שנתיים", "ten": "{0} שנים", "higher": "{0} שנה"},
+ }
+
+ meridians = {
+ "am": 'לפנ"צ',
+ "pm": 'אחר"צ',
+ "AM": "לפני הצהריים",
+ "PM": "אחרי הצהריים",
+ }
+
+ month_names = [
+ "",
+ "ינואר",
+ "פברואר",
+ "מרץ",
+ "אפריל",
+ "מאי",
+ "יוני",
+ "יולי",
+ "אוגוסט",
+ "ספטמבר",
+ "אוקטובר",
+ "נובמבר",
+ "דצמבר",
+ ]
+ month_abbreviations = [
+ "",
+ "ינו׳",
+ "פבר׳",
+ "מרץ",
+ "אפר׳",
+ "מאי",
+ "יוני",
+ "יולי",
+ "אוג׳",
+ "ספט׳",
+ "אוק׳",
+ "נוב׳",
+ "דצמ׳",
+ ]
+
+ day_names = ["", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"]
+ day_abbreviations = ["", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳", "א׳"]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+ delta = abs(delta)
+ if isinstance(form, Mapping):
+ if delta == 2:
+ form = form["2"]
+ elif delta == 0 or 2 < delta <= 10:
+ form = form["ten"]
+ else:
+ form = form["higher"]
+
+ return form.format(delta)
+
+ def describe_multi(
+ self,
+ timeframes: Sequence[Tuple[TimeFrameLiteral, Union[int, float]]],
+ only_distance: bool = False,
+ ) -> str:
+ """Describes a delta within multiple timeframes in plain language.
+ In Hebrew, the and word behaves a bit differently.
+
+ :param timeframes: a list of string, quantity pairs each representing a timeframe and delta.
+ :param only_distance: return only distance eg: "2 hours and 11 seconds" without "in" or "ago" keywords
+ """
+
+ humanized = ""
+ for index, (timeframe, delta) in enumerate(timeframes):
+ last_humanized = self._format_timeframe(timeframe, trunc(delta))
+ if index == 0:
+ humanized = last_humanized
+ elif index == len(timeframes) - 1: # Must have at least 2 items
+ humanized += " " + self.and_word
+ if last_humanized[0].isdecimal():
+ humanized += "־"
+ humanized += last_humanized
+ else: # Don't add for the last one
+ humanized += ", " + last_humanized
+
+ if not only_distance:
+ humanized = self._format_relative(humanized, timeframe, trunc(delta))
+
+ return humanized
+
+
+class MarathiLocale(Locale):
+ names = ["mr"]
+
+ past = "{0} आधी"
+ future = "{0} नंतर"
+
+ timeframes = {
+ "now": "सद्य",
+ "second": "एक सेकंद",
+ "seconds": "{0} सेकंद",
+ "minute": "एक मिनिट ",
+ "minutes": "{0} मिनिट ",
+ "hour": "एक तास",
+ "hours": "{0} तास",
+ "day": "एक दिवस",
+ "days": "{0} दिवस",
+ "month": "एक महिना ",
+ "months": "{0} महिने ",
+ "year": "एक वर्ष ",
+ "years": "{0} वर्ष ",
+ }
+
+ meridians = {"am": "सकाळ", "pm": "संध्याकाळ", "AM": "सकाळ", "PM": "संध्याकाळ"}
+
+ month_names = [
+ "",
+ "जानेवारी",
+ "फेब्रुवारी",
+ "मार्च",
+ "एप्रिल",
+ "मे",
+ "जून",
+ "जुलै",
+ "अॉगस्ट",
+ "सप्टेंबर",
+ "अॉक्टोबर",
+ "नोव्हेंबर",
+ "डिसेंबर",
+ ]
+ month_abbreviations = [
+ "",
+ "जान",
+ "फेब्रु",
+ "मार्च",
+ "एप्रि",
+ "मे",
+ "जून",
+ "जुलै",
+ "अॉग",
+ "सप्टें",
+ "अॉक्टो",
+ "नोव्हें",
+ "डिसें",
+ ]
+
+ day_names = [
+ "",
+ "सोमवार",
+ "मंगळवार",
+ "बुधवार",
+ "गुरुवार",
+ "शुक्रवार",
+ "शनिवार",
+ "रविवार",
+ ]
+ day_abbreviations = ["", "सोम", "मंगळ", "बुध", "गुरु", "शुक्र", "शनि", "रवि"]
+
+
+class CatalanLocale(Locale):
+ names = ["ca", "ca-es", "ca-ad", "ca-fr", "ca-it"]
+ past = "Fa {0}"
+ future = "En {0}"
+ and_word = "i"
+
+ timeframes = {
+ "now": "Ara mateix",
+ "second": "un segon",
+ "seconds": "{0} segons",
+ "minute": "un minut",
+ "minutes": "{0} minuts",
+ "hour": "una hora",
+ "hours": "{0} hores",
+ "day": "un dia",
+ "days": "{0} dies",
+ "month": "un mes",
+ "months": "{0} mesos",
+ "year": "un any",
+ "years": "{0} anys",
+ }
+
+ month_names = [
+ "",
+ "gener",
+ "febrer",
+ "març",
+ "abril",
+ "maig",
+ "juny",
+ "juliol",
+ "agost",
+ "setembre",
+ "octubre",
+ "novembre",
+ "desembre",
+ ]
+ month_abbreviations = [
+ "",
+ "gen.",
+ "febr.",
+ "març",
+ "abr.",
+ "maig",
+ "juny",
+ "jul.",
+ "ag.",
+ "set.",
+ "oct.",
+ "nov.",
+ "des.",
+ ]
+ day_names = [
+ "",
+ "dilluns",
+ "dimarts",
+ "dimecres",
+ "dijous",
+ "divendres",
+ "dissabte",
+ "diumenge",
+ ]
+ day_abbreviations = [
+ "",
+ "dl.",
+ "dt.",
+ "dc.",
+ "dj.",
+ "dv.",
+ "ds.",
+ "dg.",
+ ]
+
+
+class BasqueLocale(Locale):
+ names = ["eu", "eu-eu"]
+ past = "duela {0}"
+ future = "{0}" # I don't know what's the right phrase in Basque for the future.
+
+ timeframes = {
+ "now": "Orain",
+ "second": "segundo bat",
+ "seconds": "{0} segundu",
+ "minute": "minutu bat",
+ "minutes": "{0} minutu",
+ "hour": "ordu bat",
+ "hours": "{0} ordu",
+ "day": "egun bat",
+ "days": "{0} egun",
+ "month": "hilabete bat",
+ "months": "{0} hilabet",
+ "year": "urte bat",
+ "years": "{0} urte",
+ }
+
+ month_names = [
+ "",
+ "urtarrilak",
+ "otsailak",
+ "martxoak",
+ "apirilak",
+ "maiatzak",
+ "ekainak",
+ "uztailak",
+ "abuztuak",
+ "irailak",
+ "urriak",
+ "azaroak",
+ "abenduak",
+ ]
+ month_abbreviations = [
+ "",
+ "urt",
+ "ots",
+ "mar",
+ "api",
+ "mai",
+ "eka",
+ "uzt",
+ "abu",
+ "ira",
+ "urr",
+ "aza",
+ "abe",
+ ]
+ day_names = [
+ "",
+ "astelehena",
+ "asteartea",
+ "asteazkena",
+ "osteguna",
+ "ostirala",
+ "larunbata",
+ "igandea",
+ ]
+ day_abbreviations = ["", "al", "ar", "az", "og", "ol", "lr", "ig"]
+
+
+class HungarianLocale(Locale):
+ names = ["hu", "hu-hu"]
+
+ past = "{0} ezelőtt"
+ future = "{0} múlva"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "éppen most",
+ "second": {"past": "egy második", "future": "egy második"},
+ "seconds": {"past": "{0} másodpercekkel", "future": "{0} pár másodperc"},
+ "minute": {"past": "egy perccel", "future": "egy perc"},
+ "minutes": {"past": "{0} perccel", "future": "{0} perc"},
+ "hour": {"past": "egy órával", "future": "egy óra"},
+ "hours": {"past": "{0} órával", "future": "{0} óra"},
+ "day": {"past": "egy nappal", "future": "egy nap"},
+ "days": {"past": "{0} nappal", "future": "{0} nap"},
+ "week": {"past": "egy héttel", "future": "egy hét"},
+ "weeks": {"past": "{0} héttel", "future": "{0} hét"},
+ "month": {"past": "egy hónappal", "future": "egy hónap"},
+ "months": {"past": "{0} hónappal", "future": "{0} hónap"},
+ "year": {"past": "egy évvel", "future": "egy év"},
+ "years": {"past": "{0} évvel", "future": "{0} év"},
+ }
+
+ month_names = [
+ "",
+ "január",
+ "február",
+ "március",
+ "április",
+ "május",
+ "június",
+ "július",
+ "augusztus",
+ "szeptember",
+ "október",
+ "november",
+ "december",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "febr",
+ "márc",
+ "ápr",
+ "máj",
+ "jún",
+ "júl",
+ "aug",
+ "szept",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "hétfő",
+ "kedd",
+ "szerda",
+ "csütörtök",
+ "péntek",
+ "szombat",
+ "vasárnap",
+ ]
+ day_abbreviations = ["", "hét", "kedd", "szer", "csüt", "pént", "szom", "vas"]
+
+ meridians = {"am": "de", "pm": "du", "AM": "DE", "PM": "DU"}
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, Mapping):
+ if delta > 0:
+ form = form["future"]
+ else:
+ form = form["past"]
+
+ return form.format(abs(delta))
+
+
+class EsperantoLocale(Locale):
+ names = ["eo", "eo-xx"]
+ past = "antaŭ {0}"
+ future = "post {0}"
+
+ timeframes = {
+ "now": "nun",
+ "second": "sekundo",
+ "seconds": "{0} kelkaj sekundoj",
+ "minute": "unu minuto",
+ "minutes": "{0} minutoj",
+ "hour": "un horo",
+ "hours": "{0} horoj",
+ "day": "unu tago",
+ "days": "{0} tagoj",
+ "month": "unu monato",
+ "months": "{0} monatoj",
+ "year": "unu jaro",
+ "years": "{0} jaroj",
+ }
+
+ month_names = [
+ "",
+ "januaro",
+ "februaro",
+ "marto",
+ "aprilo",
+ "majo",
+ "junio",
+ "julio",
+ "aŭgusto",
+ "septembro",
+ "oktobro",
+ "novembro",
+ "decembro",
+ ]
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maj",
+ "jun",
+ "jul",
+ "aŭg",
+ "sep",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "lundo",
+ "mardo",
+ "merkredo",
+ "ĵaŭdo",
+ "vendredo",
+ "sabato",
+ "dimanĉo",
+ ]
+ day_abbreviations = ["", "lun", "mar", "mer", "ĵaŭ", "ven", "sab", "dim"]
+
+ meridians = {"am": "atm", "pm": "ptm", "AM": "ATM", "PM": "PTM"}
+
+ ordinal_day_re = r"((?P[1-3]?[0-9](?=a))a)"
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}a"
+
+
+class ThaiLocale(Locale):
+ names = ["th", "th-th"]
+
+ past = "{0} ที่ผ่านมา"
+ future = "ในอีก {0}"
+
+ timeframes = {
+ "now": "ขณะนี้",
+ "second": "วินาที",
+ "seconds": "{0} ไม่กี่วินาที",
+ "minute": "1 นาที",
+ "minutes": "{0} นาที",
+ "hour": "1 ชั่วโมง",
+ "hours": "{0} ชั่วโมง",
+ "day": "1 วัน",
+ "days": "{0} วัน",
+ "month": "1 เดือน",
+ "months": "{0} เดือน",
+ "year": "1 ปี",
+ "years": "{0} ปี",
+ }
+
+ month_names = [
+ "",
+ "มกราคม",
+ "กุมภาพันธ์",
+ "มีนาคม",
+ "เมษายน",
+ "พฤษภาคม",
+ "มิถุนายน",
+ "กรกฎาคม",
+ "สิงหาคม",
+ "กันยายน",
+ "ตุลาคม",
+ "พฤศจิกายน",
+ "ธันวาคม",
+ ]
+ month_abbreviations = [
+ "",
+ "ม.ค.",
+ "ก.พ.",
+ "มี.ค.",
+ "เม.ย.",
+ "พ.ค.",
+ "มิ.ย.",
+ "ก.ค.",
+ "ส.ค.",
+ "ก.ย.",
+ "ต.ค.",
+ "พ.ย.",
+ "ธ.ค.",
+ ]
+
+ day_names = ["", "จันทร์", "อังคาร", "พุธ", "พฤหัสบดี", "ศุกร์", "เสาร์", "อาทิตย์"]
+ day_abbreviations = ["", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"]
+
+ meridians = {"am": "am", "pm": "pm", "AM": "AM", "PM": "PM"}
+
+ BE_OFFSET = 543
+
+ def year_full(self, year: int) -> str:
+ """Thai always use Buddhist Era (BE) which is CE + 543"""
+ year += self.BE_OFFSET
+ return f"{year:04d}"
+
+ def year_abbreviation(self, year: int) -> str:
+ """Thai always use Buddhist Era (BE) which is CE + 543"""
+ year += self.BE_OFFSET
+ return f"{year:04d}"[2:]
+
+ def _format_relative(
+ self,
+ humanized: str,
+ timeframe: TimeFrameLiteral,
+ delta: Union[float, int],
+ ) -> str:
+ """Thai normally doesn't have any space between words"""
+ if timeframe == "now":
+ return humanized
+
+ direction = self.past if delta < 0 else self.future
+ relative_string = direction.format(humanized)
+
+ if timeframe == "seconds":
+ relative_string = relative_string.replace(" ", "")
+
+ return relative_string
+
+
+class LaotianLocale(Locale):
+ names = ["lo", "lo-la"]
+
+ past = "{0} ກ່ອນຫນ້ານີ້"
+ future = "ໃນ {0}"
+
+ timeframes = {
+ "now": "ດຽວນີ້",
+ "second": "ວິນາທີ",
+ "seconds": "{0} ວິນາທີ",
+ "minute": "ນາທີ",
+ "minutes": "{0} ນາທີ",
+ "hour": "ຊົ່ວໂມງ",
+ "hours": "{0} ຊົ່ວໂມງ",
+ "day": "ມື້",
+ "days": "{0} ມື້",
+ "week": "ອາທິດ",
+ "weeks": "{0} ອາທິດ",
+ "month": "ເດືອນ",
+ "months": "{0} ເດືອນ",
+ "year": "ປີ",
+ "years": "{0} ປີ",
+ }
+
+ month_names = [
+ "",
+ "ມັງກອນ", # mangkon
+ "ກຸມພາ", # kumpha
+ "ມີນາ", # mina
+ "ເມສາ", # mesa
+ "ພຶດສະພາ", # phudsapha
+ "ມິຖຸນາ", # mithuna
+ "ກໍລະກົດ", # kolakod
+ "ສິງຫາ", # singha
+ "ກັນຍາ", # knaia
+ "ຕຸລາ", # tula
+ "ພະຈິກ", # phachik
+ "ທັນວາ", # thanuaa
+ ]
+ month_abbreviations = [
+ "",
+ "ມັງກອນ",
+ "ກຸມພາ",
+ "ມີນາ",
+ "ເມສາ",
+ "ພຶດສະພາ",
+ "ມິຖຸນາ",
+ "ກໍລະກົດ",
+ "ສິງຫາ",
+ "ກັນຍາ",
+ "ຕຸລາ",
+ "ພະຈິກ",
+ "ທັນວາ",
+ ]
+
+ day_names = [
+ "",
+ "ວັນຈັນ", # vanchan
+ "ວັນອັງຄານ", # vnoangkhan
+ "ວັນພຸດ", # vanphud
+ "ວັນພະຫັດ", # vanphahad
+ "ວັນສຸກ", # vansuk
+ "ວັນເສົາ", # vansao
+ "ວັນອາທິດ", # vnoathid
+ ]
+ day_abbreviations = [
+ "",
+ "ວັນຈັນ",
+ "ວັນອັງຄານ",
+ "ວັນພຸດ",
+ "ວັນພະຫັດ",
+ "ວັນສຸກ",
+ "ວັນເສົາ",
+ "ວັນອາທິດ",
+ ]
+
+ BE_OFFSET = 543
+
+ def year_full(self, year: int) -> str:
+ """Lao always use Buddhist Era (BE) which is CE + 543"""
+ year += self.BE_OFFSET
+ return f"{year:04d}"
+
+ def year_abbreviation(self, year: int) -> str:
+ """Lao always use Buddhist Era (BE) which is CE + 543"""
+ year += self.BE_OFFSET
+ return f"{year:04d}"[2:]
+
+ def _format_relative(
+ self,
+ humanized: str,
+ timeframe: TimeFrameLiteral,
+ delta: Union[float, int],
+ ) -> str:
+ """Lao normally doesn't have any space between words"""
+ if timeframe == "now":
+ return humanized
+
+ direction = self.past if delta < 0 else self.future
+ relative_string = direction.format(humanized)
+
+ if timeframe == "seconds":
+ relative_string = relative_string.replace(" ", "")
+
+ return relative_string
+
+
+class BengaliLocale(Locale):
+ names = ["bn", "bn-bd", "bn-in"]
+
+ past = "{0} আগে"
+ future = "{0} পরে"
+
+ timeframes = {
+ "now": "এখন",
+ "second": "একটি দ্বিতীয়",
+ "seconds": "{0} সেকেন্ড",
+ "minute": "এক মিনিট",
+ "minutes": "{0} মিনিট",
+ "hour": "এক ঘণ্টা",
+ "hours": "{0} ঘণ্টা",
+ "day": "এক দিন",
+ "days": "{0} দিন",
+ "month": "এক মাস",
+ "months": "{0} মাস ",
+ "year": "এক বছর",
+ "years": "{0} বছর",
+ }
+
+ meridians = {"am": "সকাল", "pm": "বিকাল", "AM": "সকাল", "PM": "বিকাল"}
+
+ month_names = [
+ "",
+ "জানুয়ারি",
+ "ফেব্রুয়ারি",
+ "মার্চ",
+ "এপ্রিল",
+ "মে",
+ "জুন",
+ "জুলাই",
+ "আগস্ট",
+ "সেপ্টেম্বর",
+ "অক্টোবর",
+ "নভেম্বর",
+ "ডিসেম্বর",
+ ]
+ month_abbreviations = [
+ "",
+ "জানু",
+ "ফেব",
+ "মার্চ",
+ "এপ্রি",
+ "মে",
+ "জুন",
+ "জুল",
+ "অগা",
+ "সেপ্ট",
+ "অক্টো",
+ "নভে",
+ "ডিসে",
+ ]
+
+ day_names = [
+ "",
+ "সোমবার",
+ "মঙ্গলবার",
+ "বুধবার",
+ "বৃহস্পতিবার",
+ "শুক্রবার",
+ "শনিবার",
+ "রবিবার",
+ ]
+ day_abbreviations = ["", "সোম", "মঙ্গল", "বুধ", "বৃহঃ", "শুক্র", "শনি", "রবি"]
+
+ def _ordinal_number(self, n: int) -> str:
+ if n > 10 or n == 0:
+ return f"{n}তম"
+ if n in [1, 5, 7, 8, 9, 10]:
+ return f"{n}ম"
+ if n in [2, 3]:
+ return f"{n}য়"
+ if n == 4:
+ return f"{n}র্থ"
+ if n == 6:
+ return f"{n}ষ্ঠ"
+ return ""
+
+
+class RomanshLocale(Locale):
+ names = ["rm", "rm-ch"]
+
+ past = "avant {0}"
+ future = "en {0}"
+
+ timeframes = {
+ "now": "en quest mument",
+ "second": "in secunda",
+ "seconds": "{0} secundas",
+ "minute": "ina minuta",
+ "minutes": "{0} minutas",
+ "hour": "in'ura",
+ "hours": "{0} ura",
+ "day": "in di",
+ "days": "{0} dis",
+ "week": "in'emna",
+ "weeks": "{0} emnas",
+ "month": "in mais",
+ "months": "{0} mais",
+ "year": "in onn",
+ "years": "{0} onns",
+ }
+
+ month_names = [
+ "",
+ "schaner",
+ "favrer",
+ "mars",
+ "avrigl",
+ "matg",
+ "zercladur",
+ "fanadur",
+ "avust",
+ "settember",
+ "october",
+ "november",
+ "december",
+ ]
+
+ month_abbreviations = [
+ "",
+ "schan",
+ "fav",
+ "mars",
+ "avr",
+ "matg",
+ "zer",
+ "fan",
+ "avu",
+ "set",
+ "oct",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "glindesdi",
+ "mardi",
+ "mesemna",
+ "gievgia",
+ "venderdi",
+ "sonda",
+ "dumengia",
+ ]
+
+ day_abbreviations = ["", "gli", "ma", "me", "gie", "ve", "so", "du"]
+
+
+class RomanianLocale(Locale):
+ names = ["ro", "ro-ro"]
+
+ past = "{0} în urmă"
+ future = "peste {0}"
+ and_word = "și"
+
+ timeframes = {
+ "now": "acum",
+ "second": "o secunda",
+ "seconds": "{0} câteva secunde",
+ "minute": "un minut",
+ "minutes": "{0} minute",
+ "hour": "o oră",
+ "hours": "{0} ore",
+ "day": "o zi",
+ "days": "{0} zile",
+ "month": "o lună",
+ "months": "{0} luni",
+ "year": "un an",
+ "years": "{0} ani",
+ }
+
+ month_names = [
+ "",
+ "ianuarie",
+ "februarie",
+ "martie",
+ "aprilie",
+ "mai",
+ "iunie",
+ "iulie",
+ "august",
+ "septembrie",
+ "octombrie",
+ "noiembrie",
+ "decembrie",
+ ]
+ month_abbreviations = [
+ "",
+ "ian",
+ "febr",
+ "mart",
+ "apr",
+ "mai",
+ "iun",
+ "iul",
+ "aug",
+ "sept",
+ "oct",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "luni",
+ "marți",
+ "miercuri",
+ "joi",
+ "vineri",
+ "sâmbătă",
+ "duminică",
+ ]
+ day_abbreviations = ["", "Lun", "Mar", "Mie", "Joi", "Vin", "Sâm", "Dum"]
+
+
+class SlovenianLocale(Locale):
+ names = ["sl", "sl-si"]
+
+ past = "pred {0}"
+ future = "čez {0}"
+ and_word = "in"
+
+ timeframes = {
+ "now": "zdaj",
+ "second": "sekundo",
+ "seconds": "{0} sekund",
+ "minute": "minuta",
+ "minutes": "{0} minutami",
+ "hour": "uro",
+ "hours": "{0} ur",
+ "day": "dan",
+ "days": "{0} dni",
+ "month": "mesec",
+ "months": "{0} mesecev",
+ "year": "leto",
+ "years": "{0} let",
+ }
+
+ meridians = {"am": "", "pm": "", "AM": "", "PM": ""}
+
+ month_names = [
+ "",
+ "Januar",
+ "Februar",
+ "Marec",
+ "April",
+ "Maj",
+ "Junij",
+ "Julij",
+ "Avgust",
+ "September",
+ "Oktober",
+ "November",
+ "December",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Maj",
+ "Jun",
+ "Jul",
+ "Avg",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dec",
+ ]
+
+ day_names = [
+ "",
+ "Ponedeljek",
+ "Torek",
+ "Sreda",
+ "Četrtek",
+ "Petek",
+ "Sobota",
+ "Nedelja",
+ ]
+
+ day_abbreviations = ["", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob", "Ned"]
+
+
+class IndonesianLocale(Locale):
+ names = ["id", "id-id"]
+
+ past = "{0} yang lalu"
+ future = "dalam {0}"
+ and_word = "dan"
+
+ timeframes = {
+ "now": "baru saja",
+ "second": "1 sebentar",
+ "seconds": "{0} detik",
+ "minute": "1 menit",
+ "minutes": "{0} menit",
+ "hour": "1 jam",
+ "hours": "{0} jam",
+ "day": "1 hari",
+ "days": "{0} hari",
+ "week": "1 minggu",
+ "weeks": "{0} minggu",
+ "month": "1 bulan",
+ "months": "{0} bulan",
+ "quarter": "1 kuartal",
+ "quarters": "{0} kuartal",
+ "year": "1 tahun",
+ "years": "{0} tahun",
+ }
+
+ meridians = {"am": "", "pm": "", "AM": "", "PM": ""}
+
+ month_names = [
+ "",
+ "Januari",
+ "Februari",
+ "Maret",
+ "April",
+ "Mei",
+ "Juni",
+ "Juli",
+ "Agustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Ags",
+ "Sept",
+ "Okt",
+ "Nov",
+ "Des",
+ ]
+
+ day_names = ["", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu"]
+
+ day_abbreviations = [
+ "",
+ "Senin",
+ "Selasa",
+ "Rabu",
+ "Kamis",
+ "Jumat",
+ "Sabtu",
+ "Minggu",
+ ]
+
+
+class NepaliLocale(Locale):
+ names = ["ne", "ne-np"]
+
+ past = "{0} पहिले"
+ future = "{0} पछी"
+
+ timeframes = {
+ "now": "अहिले",
+ "second": "एक सेकेन्ड",
+ "seconds": "{0} सेकण्ड",
+ "minute": "मिनेट",
+ "minutes": "{0} मिनेट",
+ "hour": "एक घण्टा",
+ "hours": "{0} घण्टा",
+ "day": "एक दिन",
+ "days": "{0} दिन",
+ "month": "एक महिना",
+ "months": "{0} महिना",
+ "year": "एक बर्ष",
+ "years": "{0} बर्ष",
+ }
+
+ meridians = {"am": "पूर्वाह्न", "pm": "अपरान्ह", "AM": "पूर्वाह्न", "PM": "अपरान्ह"}
+
+ month_names = [
+ "",
+ "जनवरी",
+ "फेब्रुअरी",
+ "मार्च",
+ "एप्रील",
+ "मे",
+ "जुन",
+ "जुलाई",
+ "अगष्ट",
+ "सेप्टेम्बर",
+ "अक्टोबर",
+ "नोवेम्बर",
+ "डिसेम्बर",
+ ]
+ month_abbreviations = [
+ "",
+ "जन",
+ "फेब",
+ "मार्च",
+ "एप्रील",
+ "मे",
+ "जुन",
+ "जुलाई",
+ "अग",
+ "सेप",
+ "अक्ट",
+ "नोव",
+ "डिस",
+ ]
+
+ day_names = [
+ "",
+ "सोमवार",
+ "मंगलवार",
+ "बुधवार",
+ "बिहिवार",
+ "शुक्रवार",
+ "शनिवार",
+ "आइतवार",
+ ]
+
+ day_abbreviations = ["", "सोम", "मंगल", "बुध", "बिहि", "शुक्र", "शनि", "आइत"]
+
+
+class EstonianLocale(Locale):
+ names = ["ee", "et"]
+
+ past = "{0} tagasi"
+ future = "{0} pärast"
+ and_word = "ja"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Mapping[str, str]]] = {
+ "now": {"past": "just nüüd", "future": "just nüüd"},
+ "second": {"past": "üks sekund", "future": "ühe sekundi"},
+ "seconds": {"past": "{0} sekundit", "future": "{0} sekundi"},
+ "minute": {"past": "üks minut", "future": "ühe minuti"},
+ "minutes": {"past": "{0} minutit", "future": "{0} minuti"},
+ "hour": {"past": "tund aega", "future": "tunni aja"},
+ "hours": {"past": "{0} tundi", "future": "{0} tunni"},
+ "day": {"past": "üks päev", "future": "ühe päeva"},
+ "days": {"past": "{0} päeva", "future": "{0} päeva"},
+ "month": {"past": "üks kuu", "future": "ühe kuu"},
+ "months": {"past": "{0} kuud", "future": "{0} kuu"},
+ "year": {"past": "üks aasta", "future": "ühe aasta"},
+ "years": {"past": "{0} aastat", "future": "{0} aasta"},
+ }
+
+ month_names = [
+ "",
+ "Jaanuar",
+ "Veebruar",
+ "Märts",
+ "Aprill",
+ "Mai",
+ "Juuni",
+ "Juuli",
+ "August",
+ "September",
+ "Oktoober",
+ "November",
+ "Detsember",
+ ]
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Veb",
+ "Mär",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dets",
+ ]
+
+ day_names = [
+ "",
+ "Esmaspäev",
+ "Teisipäev",
+ "Kolmapäev",
+ "Neljapäev",
+ "Reede",
+ "Laupäev",
+ "Pühapäev",
+ ]
+ day_abbreviations = ["", "Esm", "Teis", "Kolm", "Nelj", "Re", "Lau", "Püh"]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+ if delta > 0:
+ _form = form["future"]
+ else:
+ _form = form["past"]
+ return _form.format(abs(delta))
+
+
+class LatvianLocale(Locale):
+ names = ["lv", "lv-lv"]
+
+ past = "pirms {0}"
+ future = "pēc {0}"
+ and_word = "un"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "tagad",
+ "second": "sekundes",
+ "seconds": "{0} sekundēm",
+ "minute": "minūtes",
+ "minutes": "{0} minūtēm",
+ "hour": "stundas",
+ "hours": "{0} stundām",
+ "day": "dienas",
+ "days": "{0} dienām",
+ "week": "nedēļas",
+ "weeks": "{0} nedēļām",
+ "month": "mēneša",
+ "months": "{0} mēnešiem",
+ "year": "gada",
+ "years": "{0} gadiem",
+ }
+
+ month_names = [
+ "",
+ "janvāris",
+ "februāris",
+ "marts",
+ "aprīlis",
+ "maijs",
+ "jūnijs",
+ "jūlijs",
+ "augusts",
+ "septembris",
+ "oktobris",
+ "novembris",
+ "decembris",
+ ]
+
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "marts",
+ "apr",
+ "maijs",
+ "jūnijs",
+ "jūlijs",
+ "aug",
+ "sept",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "pirmdiena",
+ "otrdiena",
+ "trešdiena",
+ "ceturtdiena",
+ "piektdiena",
+ "sestdiena",
+ "svētdiena",
+ ]
+
+ day_abbreviations = [
+ "",
+ "pi",
+ "ot",
+ "tr",
+ "ce",
+ "pi",
+ "se",
+ "sv",
+ ]
+
+
+class SwahiliLocale(Locale):
+ names = [
+ "sw",
+ "sw-ke",
+ "sw-tz",
+ ]
+
+ past = "{0} iliyopita"
+ future = "muda wa {0}"
+ and_word = "na"
+
+ timeframes = {
+ "now": "sasa hivi",
+ "second": "sekunde",
+ "seconds": "sekunde {0}",
+ "minute": "dakika moja",
+ "minutes": "dakika {0}",
+ "hour": "saa moja",
+ "hours": "saa {0}",
+ "day": "siku moja",
+ "days": "siku {0}",
+ "week": "wiki moja",
+ "weeks": "wiki {0}",
+ "month": "mwezi moja",
+ "months": "miezi {0}",
+ "year": "mwaka moja",
+ "years": "miaka {0}",
+ }
+
+ meridians = {"am": "asu", "pm": "mch", "AM": "ASU", "PM": "MCH"}
+
+ month_names = [
+ "",
+ "Januari",
+ "Februari",
+ "Machi",
+ "Aprili",
+ "Mei",
+ "Juni",
+ "Julai",
+ "Agosti",
+ "Septemba",
+ "Oktoba",
+ "Novemba",
+ "Desemba",
+ ]
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mac",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des",
+ ]
+
+ day_names = [
+ "",
+ "Jumatatu",
+ "Jumanne",
+ "Jumatano",
+ "Alhamisi",
+ "Ijumaa",
+ "Jumamosi",
+ "Jumapili",
+ ]
+ day_abbreviations = [
+ "",
+ "Jumatatu",
+ "Jumanne",
+ "Jumatano",
+ "Alhamisi",
+ "Ijumaa",
+ "Jumamosi",
+ "Jumapili",
+ ]
+
+
+class CroatianLocale(Locale):
+ names = ["hr", "hr-hr"]
+
+ past = "prije {0}"
+ future = "za {0}"
+ and_word = "i"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "upravo sad",
+ "second": "sekundu",
+ "seconds": {"double": "{0} sekunde", "higher": "{0} sekundi"},
+ "minute": "minutu",
+ "minutes": {"double": "{0} minute", "higher": "{0} minuta"},
+ "hour": "sat",
+ "hours": {"double": "{0} sata", "higher": "{0} sati"},
+ "day": "jedan dan",
+ "days": {"double": "{0} dana", "higher": "{0} dana"},
+ "week": "tjedan",
+ "weeks": {"double": "{0} tjedna", "higher": "{0} tjedana"},
+ "month": "mjesec",
+ "months": {"double": "{0} mjeseca", "higher": "{0} mjeseci"},
+ "year": "godinu",
+ "years": {"double": "{0} godine", "higher": "{0} godina"},
+ }
+
+ month_names = [
+ "",
+ "siječanj",
+ "veljača",
+ "ožujak",
+ "travanj",
+ "svibanj",
+ "lipanj",
+ "srpanj",
+ "kolovoz",
+ "rujan",
+ "listopad",
+ "studeni",
+ "prosinac",
+ ]
+
+ month_abbreviations = [
+ "",
+ "siječ",
+ "velj",
+ "ožuj",
+ "trav",
+ "svib",
+ "lip",
+ "srp",
+ "kol",
+ "ruj",
+ "list",
+ "stud",
+ "pros",
+ ]
+
+ day_names = [
+ "",
+ "ponedjeljak",
+ "utorak",
+ "srijeda",
+ "četvrtak",
+ "petak",
+ "subota",
+ "nedjelja",
+ ]
+
+ day_abbreviations = [
+ "",
+ "po",
+ "ut",
+ "sr",
+ "če",
+ "pe",
+ "su",
+ "ne",
+ ]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+ delta = abs(delta)
+ if isinstance(form, Mapping):
+ if 1 < delta <= 4:
+ form = form["double"]
+ else:
+ form = form["higher"]
+
+ return form.format(delta)
+
+
+class LatinLocale(Locale):
+ names = ["la", "la-va"]
+
+ past = "ante {0}"
+ future = "in {0}"
+ and_word = "et"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "nunc",
+ "second": "secundum",
+ "seconds": "{0} secundis",
+ "minute": "minutam",
+ "minutes": "{0} minutis",
+ "hour": "horam",
+ "hours": "{0} horas",
+ "day": "diem",
+ "days": "{0} dies",
+ "week": "hebdomadem",
+ "weeks": "{0} hebdomades",
+ "month": "mensem",
+ "months": "{0} mensis",
+ "year": "annum",
+ "years": "{0} annos",
+ }
+
+ month_names = [
+ "",
+ "Ianuarius",
+ "Februarius",
+ "Martius",
+ "Aprilis",
+ "Maius",
+ "Iunius",
+ "Iulius",
+ "Augustus",
+ "September",
+ "October",
+ "November",
+ "December",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Ian",
+ "Febr",
+ "Mart",
+ "Apr",
+ "Mai",
+ "Iun",
+ "Iul",
+ "Aug",
+ "Sept",
+ "Oct",
+ "Nov",
+ "Dec",
+ ]
+
+ day_names = [
+ "",
+ "dies Lunae",
+ "dies Martis",
+ "dies Mercurii",
+ "dies Iovis",
+ "dies Veneris",
+ "dies Saturni",
+ "dies Solis",
+ ]
+
+ day_abbreviations = [
+ "",
+ "dies Lunae",
+ "dies Martis",
+ "dies Mercurii",
+ "dies Iovis",
+ "dies Veneris",
+ "dies Saturni",
+ "dies Solis",
+ ]
+
+
+class LithuanianLocale(Locale):
+ names = ["lt", "lt-lt"]
+
+ past = "prieš {0}"
+ future = "po {0}"
+ and_word = "ir"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "dabar",
+ "second": "sekundės",
+ "seconds": "{0} sekundžių",
+ "minute": "minutės",
+ "minutes": "{0} minučių",
+ "hour": "valandos",
+ "hours": "{0} valandų",
+ "day": "dieną",
+ "days": "{0} dienų",
+ "week": "savaitės",
+ "weeks": "{0} savaičių",
+ "month": "mėnesio",
+ "months": "{0} mėnesių",
+ "year": "metų",
+ "years": "{0} metų",
+ }
+
+ month_names = [
+ "",
+ "sausis",
+ "vasaris",
+ "kovas",
+ "balandis",
+ "gegužė",
+ "birželis",
+ "liepa",
+ "rugpjūtis",
+ "rugsėjis",
+ "spalis",
+ "lapkritis",
+ "gruodis",
+ ]
+
+ month_abbreviations = [
+ "",
+ "saus",
+ "vas",
+ "kovas",
+ "bal",
+ "geg",
+ "birž",
+ "liepa",
+ "rugp",
+ "rugs",
+ "spalis",
+ "lapkr",
+ "gr",
+ ]
+
+ day_names = [
+ "",
+ "pirmadienis",
+ "antradienis",
+ "trečiadienis",
+ "ketvirtadienis",
+ "penktadienis",
+ "šeštadienis",
+ "sekmadienis",
+ ]
+
+ day_abbreviations = [
+ "",
+ "pi",
+ "an",
+ "tr",
+ "ke",
+ "pe",
+ "še",
+ "se",
+ ]
+
+
+class MalayLocale(Locale):
+ names = ["ms", "ms-my", "ms-bn"]
+
+ past = "{0} yang lalu"
+ future = "dalam {0}"
+ and_word = "dan"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "sekarang",
+ "second": "saat",
+ "seconds": "{0} saat",
+ "minute": "minit",
+ "minutes": "{0} minit",
+ "hour": "jam",
+ "hours": "{0} jam",
+ "day": "hari",
+ "days": "{0} hari",
+ "week": "minggu",
+ "weeks": "{0} minggu",
+ "month": "bulan",
+ "months": "{0} bulan",
+ "year": "tahun",
+ "years": "{0} tahun",
+ }
+
+ month_names = [
+ "",
+ "Januari",
+ "Februari",
+ "Mac",
+ "April",
+ "Mei",
+ "Jun",
+ "Julai",
+ "Ogos",
+ "September",
+ "Oktober",
+ "November",
+ "Disember",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Jan.",
+ "Feb.",
+ "Mac",
+ "Apr.",
+ "Mei",
+ "Jun",
+ "Julai",
+ "Og.",
+ "Sept.",
+ "Okt.",
+ "Nov.",
+ "Dis.",
+ ]
+
+ day_names = [
+ "",
+ "Isnin",
+ "Selasa",
+ "Rabu",
+ "Khamis",
+ "Jumaat",
+ "Sabtu",
+ "Ahad",
+ ]
+
+ day_abbreviations = [
+ "",
+ "Isnin",
+ "Selasa",
+ "Rabu",
+ "Khamis",
+ "Jumaat",
+ "Sabtu",
+ "Ahad",
+ ]
+
+
+class MalteseLocale(Locale):
+ names = ["mt", "mt-mt"]
+
+ past = "{0} ilu"
+ future = "fi {0}"
+ and_word = "u"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "issa",
+ "second": "sekonda",
+ "seconds": "{0} sekondi",
+ "minute": "minuta",
+ "minutes": "{0} minuti",
+ "hour": "siegħa",
+ "hours": {"dual": "{0} sagħtejn", "plural": "{0} sigħat"},
+ "day": "jum",
+ "days": {"dual": "{0} jumejn", "plural": "{0} ijiem"},
+ "week": "ġimgħa",
+ "weeks": {"dual": "{0} ġimagħtejn", "plural": "{0} ġimgħat"},
+ "month": "xahar",
+ "months": {"dual": "{0} xahrejn", "plural": "{0} xhur"},
+ "year": "sena",
+ "years": {"dual": "{0} sentejn", "plural": "{0} snin"},
+ }
+
+ month_names = [
+ "",
+ "Jannar",
+ "Frar",
+ "Marzu",
+ "April",
+ "Mejju",
+ "Ġunju",
+ "Lulju",
+ "Awwissu",
+ "Settembru",
+ "Ottubru",
+ "Novembru",
+ "Diċembru",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Fr",
+ "Mar",
+ "Apr",
+ "Mejju",
+ "Ġun",
+ "Lul",
+ "Aw",
+ "Sett",
+ "Ott",
+ "Nov",
+ "Diċ",
+ ]
+
+ day_names = [
+ "",
+ "It-Tnejn",
+ "It-Tlieta",
+ "L-Erbgħa",
+ "Il-Ħamis",
+ "Il-Ġimgħa",
+ "Is-Sibt",
+ "Il-Ħadd",
+ ]
+
+ day_abbreviations = [
+ "",
+ "T",
+ "TL",
+ "E",
+ "Ħ",
+ "Ġ",
+ "S",
+ "Ħ",
+ ]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+ delta = abs(delta)
+ if isinstance(form, Mapping):
+ if delta == 2:
+ form = form["dual"]
+ else:
+ form = form["plural"]
+
+ return form.format(delta)
+
+
+class SamiLocale(Locale):
+ names = ["se", "se-fi", "se-no", "se-se"]
+
+ past = "{0} dassái"
+ future = "{0} " # NOTE: couldn't find preposition for Sami here, none needed?
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "dál",
+ "second": "sekunda",
+ "seconds": "{0} sekundda",
+ "minute": "minuhta",
+ "minutes": "{0} minuhta",
+ "hour": "diimmu",
+ "hours": "{0} diimmu",
+ "day": "beaivvi",
+ "days": "{0} beaivvi",
+ "week": "vahku",
+ "weeks": "{0} vahku",
+ "month": "mánu",
+ "months": "{0} mánu",
+ "year": "jagi",
+ "years": "{0} jagi",
+ }
+
+ month_names = [
+ "",
+ "Ođđajagimánnu",
+ "Guovvamánnu",
+ "Njukčamánnu",
+ "Cuoŋománnu",
+ "Miessemánnu",
+ "Geassemánnu",
+ "Suoidnemánnu",
+ "Borgemánnu",
+ "Čakčamánnu",
+ "Golggotmánnu",
+ "Skábmamánnu",
+ "Juovlamánnu",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Ođđajagimánnu",
+ "Guovvamánnu",
+ "Njukčamánnu",
+ "Cuoŋománnu",
+ "Miessemánnu",
+ "Geassemánnu",
+ "Suoidnemánnu",
+ "Borgemánnu",
+ "Čakčamánnu",
+ "Golggotmánnu",
+ "Skábmamánnu",
+ "Juovlamánnu",
+ ]
+
+ day_names = [
+ "",
+ "Mánnodat",
+ "Disdat",
+ "Gaskavahkku",
+ "Duorastat",
+ "Bearjadat",
+ "Lávvordat",
+ "Sotnabeaivi",
+ ]
+
+ day_abbreviations = [
+ "",
+ "Mánnodat",
+ "Disdat",
+ "Gaskavahkku",
+ "Duorastat",
+ "Bearjadat",
+ "Lávvordat",
+ "Sotnabeaivi",
+ ]
+
+
+class OdiaLocale(Locale):
+ names = ["or", "or-in"]
+
+ past = "{0} ପୂର୍ବେ"
+ future = "{0} ପରେ"
+
+ timeframes = {
+ "now": "ବର୍ତ୍ତମାନ",
+ "second": "ଏକ ସେକେଣ୍ଡ",
+ "seconds": "{0} ସେକେଣ୍ଡ",
+ "minute": "ଏକ ମିନଟ",
+ "minutes": "{0} ମିନଟ",
+ "hour": "ଏକ ଘଣ୍ଟା",
+ "hours": "{0} ଘଣ୍ଟା",
+ "day": "ଏକ ଦିନ",
+ "days": "{0} ଦିନ",
+ "month": "ଏକ ମାସ",
+ "months": "{0} ମାସ ",
+ "year": "ଏକ ବର୍ଷ",
+ "years": "{0} ବର୍ଷ",
+ }
+
+ meridians = {"am": "ପୂର୍ବାହ୍ନ", "pm": "ଅପରାହ୍ନ", "AM": "ପୂର୍ବାହ୍ନ", "PM": "ଅପରାହ୍ନ"}
+
+ month_names = [
+ "",
+ "ଜାନୁଆରୀ",
+ "ଫେବୃଆରୀ",
+ "ମାର୍ଚ୍ଚ୍",
+ "ଅପ୍ରେଲ",
+ "ମଇ",
+ "ଜୁନ୍",
+ "ଜୁଲାଇ",
+ "ଅଗଷ୍ଟ",
+ "ସେପ୍ଟେମ୍ବର",
+ "ଅକ୍ଟୋବର୍",
+ "ନଭେମ୍ବର୍",
+ "ଡିସେମ୍ବର୍",
+ ]
+ month_abbreviations = [
+ "",
+ "ଜାନୁ",
+ "ଫେବୃ",
+ "ମାର୍ଚ୍ଚ୍",
+ "ଅପ୍ରେ",
+ "ମଇ",
+ "ଜୁନ୍",
+ "ଜୁଲା",
+ "ଅଗ",
+ "ସେପ୍ଟେ",
+ "ଅକ୍ଟୋ",
+ "ନଭେ",
+ "ଡିସେ",
+ ]
+
+ day_names = [
+ "",
+ "ସୋମବାର",
+ "ମଙ୍ଗଳବାର",
+ "ବୁଧବାର",
+ "ଗୁରୁବାର",
+ "ଶୁକ୍ରବାର",
+ "ଶନିବାର",
+ "ରବିବାର",
+ ]
+ day_abbreviations = [
+ "",
+ "ସୋମ",
+ "ମଙ୍ଗଳ",
+ "ବୁଧ",
+ "ଗୁରୁ",
+ "ଶୁକ୍ର",
+ "ଶନି",
+ "ରବି",
+ ]
+
+ def _ordinal_number(self, n: int) -> str:
+ if n > 10 or n == 0:
+ return f"{n}ତମ"
+ if n in [1, 5, 7, 8, 9, 10]:
+ return f"{n}ମ"
+ if n in [2, 3]:
+ return f"{n}ୟ"
+ if n == 4:
+ return f"{n}ର୍ଥ"
+ if n == 6:
+ return f"{n}ଷ୍ଠ"
+ return ""
+
+
+class SerbianLocale(Locale):
+ names = ["sr", "sr-rs", "sr-sp"]
+
+ past = "pre {0}"
+ future = "za {0}"
+ and_word = "i"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
+ "now": "sada",
+ "second": "sekundu",
+ "seconds": {"double": "{0} sekunde", "higher": "{0} sekundi"},
+ "minute": "minutu",
+ "minutes": {"double": "{0} minute", "higher": "{0} minuta"},
+ "hour": "sat",
+ "hours": {"double": "{0} sata", "higher": "{0} sati"},
+ "day": "dan",
+ "days": {"double": "{0} dana", "higher": "{0} dana"},
+ "week": "nedelju",
+ "weeks": {"double": "{0} nedelje", "higher": "{0} nedelja"},
+ "month": "mesec",
+ "months": {"double": "{0} meseca", "higher": "{0} meseci"},
+ "year": "godinu",
+ "years": {"double": "{0} godine", "higher": "{0} godina"},
+ }
+
+ month_names = [
+ "",
+ "januar", # јануар
+ "februar", # фебруар
+ "mart", # март
+ "april", # април
+ "maj", # мај
+ "jun", # јун
+ "jul", # јул
+ "avgust", # август
+ "septembar", # септембар
+ "oktobar", # октобар
+ "novembar", # новембар
+ "decembar", # децембар
+ ]
+
+ month_abbreviations = [
+ "",
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maj",
+ "jun",
+ "jul",
+ "avg",
+ "sep",
+ "okt",
+ "nov",
+ "dec",
+ ]
+
+ day_names = [
+ "",
+ "ponedeljak", # понедељак
+ "utorak", # уторак
+ "sreda", # среда
+ "četvrtak", # четвртак
+ "petak", # петак
+ "subota", # субота
+ "nedelja", # недеља
+ ]
+
+ day_abbreviations = [
+ "",
+ "po", # по
+ "ut", # ут
+ "sr", # ср
+ "če", # че
+ "pe", # пе
+ "su", # су
+ "ne", # не
+ ]
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ form = self.timeframes[timeframe]
+ delta = abs(delta)
+ if isinstance(form, Mapping):
+ if 1 < delta <= 4:
+ form = form["double"]
+ else:
+ form = form["higher"]
+
+ return form.format(delta)
+
+
+class LuxembourgishLocale(Locale):
+ names = ["lb", "lb-lu"]
+
+ past = "virun {0}"
+ future = "an {0}"
+ and_word = "an"
+
+ timeframes: ClassVar[Dict[TimeFrameLiteral, str]] = {
+ "now": "just elo",
+ "second": "enger Sekonn",
+ "seconds": "{0} Sekonnen",
+ "minute": "enger Minutt",
+ "minutes": "{0} Minutten",
+ "hour": "enger Stonn",
+ "hours": "{0} Stonnen",
+ "day": "engem Dag",
+ "days": "{0} Deeg",
+ "week": "enger Woch",
+ "weeks": "{0} Wochen",
+ "month": "engem Mount",
+ "months": "{0} Méint",
+ "year": "engem Joer",
+ "years": "{0} Jahren",
+ }
+
+ timeframes_only_distance = timeframes.copy()
+ timeframes_only_distance["second"] = "eng Sekonn"
+ timeframes_only_distance["minute"] = "eng Minutt"
+ timeframes_only_distance["hour"] = "eng Stonn"
+ timeframes_only_distance["day"] = "een Dag"
+ timeframes_only_distance["days"] = "{0} Deeg"
+ timeframes_only_distance["week"] = "eng Woch"
+ timeframes_only_distance["month"] = "ee Mount"
+ timeframes_only_distance["months"] = "{0} Méint"
+ timeframes_only_distance["year"] = "ee Joer"
+ timeframes_only_distance["years"] = "{0} Joer"
+
+ month_names = [
+ "",
+ "Januar",
+ "Februar",
+ "Mäerz",
+ "Abrëll",
+ "Mee",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktouber",
+ "November",
+ "Dezember",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Jan",
+ "Feb",
+ "Mäe",
+ "Abr",
+ "Mee",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez",
+ ]
+
+ day_names = [
+ "",
+ "Méindeg",
+ "Dënschdeg",
+ "Mëttwoch",
+ "Donneschdeg",
+ "Freideg",
+ "Samschdeg",
+ "Sonndeg",
+ ]
+
+ day_abbreviations = ["", "Méi", "Dën", "Mët", "Don", "Fre", "Sam", "Son"]
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}."
+
+ def describe(
+ self,
+ timeframe: TimeFrameLiteral,
+ delta: Union[int, float] = 0,
+ only_distance: bool = False,
+ ) -> str:
+ if not only_distance:
+ return super().describe(timeframe, delta, only_distance)
+
+ # Luxembourgish uses a different case without 'in' or 'ago'
+ humanized: str = self.timeframes_only_distance[timeframe].format(
+ trunc(abs(delta))
+ )
+
+ return humanized
+
+
+class ZuluLocale(Locale):
+ names = ["zu", "zu-za"]
+
+ past = "{0} edlule"
+ future = "{0} "
+ and_word = "futhi"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[Mapping[str, str], str]]] = {
+ "now": "manje",
+ "second": {"past": "umzuzwana", "future": "ngomzuzwana"},
+ "seconds": {"past": "{0} imizuzwana", "future": "{0} ngemizuzwana"},
+ "minute": {"past": "umzuzu", "future": "ngomzuzu"},
+ "minutes": {"past": "{0} imizuzu", "future": "{0} ngemizuzu"},
+ "hour": {"past": "ihora", "future": "ngehora"},
+ "hours": {"past": "{0} amahora", "future": "{0} emahoreni"},
+ "day": {"past": "usuku", "future": "ngosuku"},
+ "days": {"past": "{0} izinsuku", "future": "{0} ezinsukwini"},
+ "week": {"past": "isonto", "future": "ngesonto"},
+ "weeks": {"past": "{0} amasonto", "future": "{0} emasontweni"},
+ "month": {"past": "inyanga", "future": "ngenyanga"},
+ "months": {"past": "{0} izinyanga", "future": "{0} ezinyangeni"},
+ "year": {"past": "unyaka", "future": "ngonyak"},
+ "years": {"past": "{0} iminyaka", "future": "{0} eminyakeni"},
+ }
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ """Zulu aware time frame format function, takes into account
+ the differences between past and future forms."""
+ abs_delta = abs(delta)
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, str):
+ return form.format(abs_delta)
+
+ if delta > 0:
+ key = "future"
+ else:
+ key = "past"
+ form = form[key]
+
+ return form.format(abs_delta)
+
+ month_names = [
+ "",
+ "uMasingane",
+ "uNhlolanja",
+ "uNdasa",
+ "UMbasa",
+ "UNhlaba",
+ "UNhlangulana",
+ "uNtulikazi",
+ "UNcwaba",
+ "uMandulo",
+ "uMfumfu",
+ "uLwezi",
+ "uZibandlela",
+ ]
+
+ month_abbreviations = [
+ "",
+ "uMasingane",
+ "uNhlolanja",
+ "uNdasa",
+ "UMbasa",
+ "UNhlaba",
+ "UNhlangulana",
+ "uNtulikazi",
+ "UNcwaba",
+ "uMandulo",
+ "uMfumfu",
+ "uLwezi",
+ "uZibandlela",
+ ]
+
+ day_names = [
+ "",
+ "uMsombuluko",
+ "uLwesibili",
+ "uLwesithathu",
+ "uLwesine",
+ "uLwesihlanu",
+ "uMgqibelo",
+ "iSonto",
+ ]
+
+ day_abbreviations = [
+ "",
+ "uMsombuluko",
+ "uLwesibili",
+ "uLwesithathu",
+ "uLwesine",
+ "uLwesihlanu",
+ "uMgqibelo",
+ "iSonto",
+ ]
+
+
+class TamilLocale(Locale):
+ names = ["ta", "ta-in", "ta-lk"]
+
+ past = "{0} நேரத்திற்கு முன்பு"
+ future = "இல் {0}"
+
+ timeframes = {
+ "now": "இப்போது",
+ "second": "ஒரு இரண்டாவது",
+ "seconds": "{0} விநாடிகள்",
+ "minute": "ஒரு நிமிடம்",
+ "minutes": "{0} நிமிடங்கள்",
+ "hour": "ஒரு மணி",
+ "hours": "{0} மணிநேரம்",
+ "day": "ஒரு நாள்",
+ "days": "{0} நாட்கள்",
+ "week": "ஒரு வாரம்",
+ "weeks": "{0} வாரங்கள்",
+ "month": "ஒரு மாதம்",
+ "months": "{0} மாதங்கள்",
+ "year": "ஒரு ஆண்டு",
+ "years": "{0} ஆண்டுகள்",
+ }
+
+ month_names = [
+ "",
+ "சித்திரை",
+ "வைகாசி",
+ "ஆனி",
+ "ஆடி",
+ "ஆவணி",
+ "புரட்டாசி",
+ "ஐப்பசி",
+ "கார்த்திகை",
+ "மார்கழி",
+ "தை",
+ "மாசி",
+ "பங்குனி",
+ ]
+
+ month_abbreviations = [
+ "",
+ "ஜன",
+ "பிப்",
+ "மார்",
+ "ஏப்",
+ "மே",
+ "ஜூன்",
+ "ஜூலை",
+ "ஆக",
+ "செப்",
+ "அக்",
+ "நவ",
+ "டிச",
+ ]
+
+ day_names = [
+ "",
+ "திங்கட்கிழமை",
+ "செவ்வாய்க்கிழமை",
+ "புதன்கிழமை",
+ "வியாழக்கிழமை",
+ "வெள்ளிக்கிழமை",
+ "சனிக்கிழமை",
+ "ஞாயிற்றுக்கிழமை",
+ ]
+
+ day_abbreviations = [
+ "",
+ "திங்கட்",
+ "செவ்வாய்",
+ "புதன்",
+ "வியாழன்",
+ "வெள்ளி",
+ "சனி",
+ "ஞாயிறு",
+ ]
+
+ def _ordinal_number(self, n: int) -> str:
+ if n == 1:
+ return f"{n}வது"
+ elif n >= 0:
+ return f"{n}ஆம்"
+ else:
+ return ""
+
+
+class AlbanianLocale(Locale):
+ names = ["sq", "sq-al"]
+
+ past = "{0} më parë"
+ future = "në {0}"
+ and_word = "dhe"
+
+ timeframes = {
+ "now": "tani",
+ "second": "sekondë",
+ "seconds": "{0} sekonda",
+ "minute": "minutë",
+ "minutes": "{0} minuta",
+ "hour": "orë",
+ "hours": "{0} orë",
+ "day": "ditë",
+ "days": "{0} ditë",
+ "week": "javë",
+ "weeks": "{0} javë",
+ "month": "muaj",
+ "months": "{0} muaj",
+ "year": "vit",
+ "years": "{0} vjet",
+ }
+
+ month_names = [
+ "",
+ "janar",
+ "shkurt",
+ "mars",
+ "prill",
+ "maj",
+ "qershor",
+ "korrik",
+ "gusht",
+ "shtator",
+ "tetor",
+ "nëntor",
+ "dhjetor",
+ ]
+
+ month_abbreviations = [
+ "",
+ "jan",
+ "shk",
+ "mar",
+ "pri",
+ "maj",
+ "qer",
+ "korr",
+ "gush",
+ "sht",
+ "tet",
+ "nën",
+ "dhj",
+ ]
+
+ day_names = [
+ "",
+ "e hënë",
+ "e martë",
+ "e mërkurë",
+ "e enjte",
+ "e premte",
+ "e shtunë",
+ "e diel",
+ ]
+
+ day_abbreviations = [
+ "",
+ "hën",
+ "mar",
+ "mër",
+ "enj",
+ "pre",
+ "sht",
+ "die",
+ ]
+
+
+class GeorgianLocale(Locale):
+ names = ["ka", "ka-ge"]
+
+ past = "{0} წინ" # ts’in
+ future = "{0} შემდეგ" # shemdeg
+ and_word = "და" # da
+
+ timeframes = {
+ "now": "ახლა", # akhla
+ # When a cardinal qualifies a noun, it stands in the singular
+ "second": "წამის", # ts’amis
+ "seconds": "{0} წამის",
+ "minute": "წუთის", # ts’utis
+ "minutes": "{0} წუთის",
+ "hour": "საათის", # saatis
+ "hours": "{0} საათის",
+ "day": "დღის", # dghis
+ "days": "{0} დღის",
+ "week": "კვირის", # k’viris
+ "weeks": "{0} კვირის",
+ "month": "თვის", # tvis
+ "months": "{0} თვის",
+ "year": "წლის", # ts’lis
+ "years": "{0} წლის",
+ }
+
+ month_names = [
+ # modern month names
+ "",
+ "იანვარი", # Ianvari
+ "თებერვალი", # Tebervali
+ "მარტი", # Mart'i
+ "აპრილი", # Ap'rili
+ "მაისი", # Maisi
+ "ივნისი", # Ivnisi
+ "ივლისი", # Ivlisi
+ "აგვისტო", # Agvist'o
+ "სექტემბერი", # Sekt'emberi
+ "ოქტომბერი", # Okt'omberi
+ "ნოემბერი", # Noemberi
+ "დეკემბერი", # Dek'emberi
+ ]
+
+ month_abbreviations = [
+ # no abbr. found yet
+ "",
+ "იანვარი", # Ianvari
+ "თებერვალი", # Tebervali
+ "მარტი", # Mart'i
+ "აპრილი", # Ap'rili
+ "მაისი", # Maisi
+ "ივნისი", # Ivnisi
+ "ივლისი", # Ivlisi
+ "აგვისტო", # Agvist'o
+ "სექტემბერი", # Sekt'emberi
+ "ოქტომბერი", # Okt'omberi
+ "ნოემბერი", # Noemberi
+ "დეკემბერი", # Dek'emberi
+ ]
+
+ day_names = [
+ "",
+ "ორშაბათი", # orshabati
+ "სამშაბათი", # samshabati
+ "ოთხშაბათი", # otkhshabati
+ "ხუთშაბათი", # khutshabati
+ "პარასკევი", # p’arask’evi
+ "შაბათი", # shabati
+ # "k’vira" also serves as week; to avoid confusion "k’vira-dge" can be used for Sunday
+ "კვირა", # k’vira
+ ]
+
+ day_abbreviations = [
+ "",
+ "ორშაბათი", # orshabati
+ "სამშაბათი", # samshabati
+ "ოთხშაბათი", # otkhshabati
+ "ხუთშაბათი", # khutshabati
+ "პარასკევი", # p’arask’evi
+ "შაბათი", # shabati
+ "კვირა", # k’vira
+ ]
+
+
+class SinhalaLocale(Locale):
+ names = ["si", "si-lk"]
+
+ past = "{0}ට පෙර"
+ future = "{0}"
+ and_word = "සහ"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[Mapping[str, str], str]]] = {
+ "now": "දැන්",
+ "second": {
+ "past": "තත්පරයක",
+ "future": "තත්පරයකින්",
+ }, # ක් is the article
+ "seconds": {
+ "past": "තත්පර {0} ක",
+ "future": "තත්පර {0} කින්",
+ },
+ "minute": {
+ "past": "විනාඩියක",
+ "future": "විනාඩියකින්",
+ },
+ "minutes": {
+ "past": "විනාඩි {0} ක",
+ "future": "මිනිත්තු {0} කින්",
+ },
+ "hour": {"past": "පැයක", "future": "පැයකින්"},
+ "hours": {
+ "past": "පැය {0} ක",
+ "future": "පැය {0} කින්",
+ },
+ "day": {"past": "දිනක", "future": "දිනකට"},
+ "days": {
+ "past": "දින {0} ක",
+ "future": "දින {0} කින්",
+ },
+ "week": {"past": "සතියක", "future": "සතියකින්"},
+ "weeks": {
+ "past": "සති {0} ක",
+ "future": "සති {0} කින්",
+ },
+ "month": {"past": "මාසයක", "future": "එය මාසය තුළ"},
+ "months": {
+ "past": "මාස {0} ක",
+ "future": "මාස {0} කින්",
+ },
+ "year": {"past": "වසරක", "future": "වසරක් තුළ"},
+ "years": {
+ "past": "අවුරුදු {0} ක",
+ "future": "අවුරුදු {0} තුළ",
+ },
+ }
+ # Sinhala: the general format to describe timeframe is different from past and future,
+ # so we do not copy the original timeframes dictionary
+ timeframes_only_distance = {}
+ timeframes_only_distance["second"] = "තත්පරයක්"
+ timeframes_only_distance["seconds"] = "තත්පර {0}"
+ timeframes_only_distance["minute"] = "මිනිත්තුවක්"
+ timeframes_only_distance["minutes"] = "විනාඩි {0}"
+ timeframes_only_distance["hour"] = "පැයක්"
+ timeframes_only_distance["hours"] = "පැය {0}"
+ timeframes_only_distance["day"] = "දවසක්"
+ timeframes_only_distance["days"] = "දවස් {0}"
+ timeframes_only_distance["week"] = "සතියක්"
+ timeframes_only_distance["weeks"] = "සති {0}"
+ timeframes_only_distance["month"] = "මාසයක්"
+ timeframes_only_distance["months"] = "මාස {0}"
+ timeframes_only_distance["year"] = "අවුරුද්දක්"
+ timeframes_only_distance["years"] = "අවුරුදු {0}"
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ """
+ Sinhala awares time frame format function, takes into account
+ the differences between general, past, and future forms (three different suffixes).
+ """
+ abs_delta = abs(delta)
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, str):
+ return form.format(abs_delta)
+
+ if delta > 0:
+ key = "future"
+ else:
+ key = "past"
+ form = form[key]
+
+ return form.format(abs_delta)
+
+ def describe(
+ self,
+ timeframe: TimeFrameLiteral,
+ delta: Union[float, int] = 1, # key is always future when only_distance=False
+ only_distance: bool = False,
+ ) -> str:
+ """Describes a delta within a timeframe in plain language.
+
+ :param timeframe: a string representing a timeframe.
+ :param delta: a quantity representing a delta in a timeframe.
+ :param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
+ """
+
+ if not only_distance:
+ return super().describe(timeframe, delta, only_distance)
+ # Sinhala uses a different case without 'in' or 'ago'
+ humanized = self.timeframes_only_distance[timeframe].format(trunc(abs(delta)))
+
+ return humanized
+
+ month_names = [
+ "",
+ "ජනවාරි",
+ "පෙබරවාරි",
+ "මාර්තු",
+ "අප්රේල්",
+ "මැයි",
+ "ජූනි",
+ "ජූලි",
+ "අගෝස්තු",
+ "සැප්තැම්බර්",
+ "ඔක්තෝබර්",
+ "නොවැම්බර්",
+ "දෙසැම්බර්",
+ ]
+
+ month_abbreviations = [
+ "",
+ "ජන",
+ "පෙබ",
+ "මාර්",
+ "අප්රේ",
+ "මැයි",
+ "ජුනි",
+ "ජූලි",
+ "අගෝ",
+ "සැප්",
+ "ඔක්",
+ "නොවැ",
+ "දෙසැ",
+ ]
+
+ day_names = [
+ "",
+ "සදුදා",
+ "අඟහරැවදා",
+ "බදාදා",
+ "බ්රහස්පතින්දා",
+ "සිකුරාදා",
+ "සෙනසුරාදා",
+ "ඉරිදා",
+ ]
+
+ day_abbreviations = [
+ "",
+ "සදුද",
+ "බදා",
+ "බදා",
+ "සිකු",
+ "සෙන",
+ "අ",
+ "ඉරිදා",
+ ]
+
+
+class UrduLocale(Locale):
+ names = ["ur", "ur-pk"]
+
+ past = "پہلے {0}"
+ future = "میں {0}"
+ and_word = "اور"
+
+ timeframes = {
+ "now": "ابھی",
+ "second": "ایک سیکنڈ",
+ "seconds": "{0} سیکنڈ",
+ "minute": "ایک منٹ",
+ "minutes": "{0} منٹ",
+ "hour": "ایک گھنٹے",
+ "hours": "{0} گھنٹے",
+ "day": "ایک دن",
+ "days": "{0} دن",
+ "week": "ایک ہفتے",
+ "weeks": "{0} ہفتے",
+ "month": "ایک مہینہ",
+ "months": "{0} ماہ",
+ "year": "ایک سال",
+ "years": "{0} سال",
+ }
+
+ month_names = [
+ "",
+ "جنوری",
+ "فروری",
+ "مارچ",
+ "اپریل",
+ "مئی",
+ "جون",
+ "جولائی",
+ "اگست",
+ "ستمبر",
+ "اکتوبر",
+ "نومبر",
+ "دسمبر",
+ ]
+
+ month_abbreviations = [
+ "",
+ "جنوری",
+ "فروری",
+ "مارچ",
+ "اپریل",
+ "مئی",
+ "جون",
+ "جولائی",
+ "اگست",
+ "ستمبر",
+ "اکتوبر",
+ "نومبر",
+ "دسمبر",
+ ]
+
+ day_names = [
+ "",
+ "سوموار",
+ "منگل",
+ "بدھ",
+ "جمعرات",
+ "جمعہ",
+ "ہفتہ",
+ "اتوار",
+ ]
+
+ day_abbreviations = [
+ "",
+ "سوموار",
+ "منگل",
+ "بدھ",
+ "جمعرات",
+ "جمعہ",
+ "ہفتہ",
+ "اتوار",
+ ]
+
+
+class KazakhLocale(Locale):
+ names = ["kk", "kk-kz"]
+
+ past = "{0} бұрын"
+ future = "{0} кейін"
+ timeframes = {
+ "now": "қазір",
+ "second": "бір секунд",
+ "seconds": "{0} секунд",
+ "minute": "бір минут",
+ "minutes": "{0} минут",
+ "hour": "бір сағат",
+ "hours": "{0} сағат",
+ "day": "бір күн",
+ "days": "{0} күн",
+ "week": "бір апта",
+ "weeks": "{0} апта",
+ "month": "бір ай",
+ "months": "{0} ай",
+ "year": "бір жыл",
+ "years": "{0} жыл",
+ }
+
+ month_names = [
+ "",
+ "Қаңтар",
+ "Ақпан",
+ "Наурыз",
+ "Сәуір",
+ "Мамыр",
+ "Маусым",
+ "Шілде",
+ "Тамыз",
+ "Қыркүйек",
+ "Қазан",
+ "Қараша",
+ "Желтоқсан",
+ ]
+ month_abbreviations = [
+ "",
+ "Қан",
+ "Ақп",
+ "Нау",
+ "Сәу",
+ "Мам",
+ "Мау",
+ "Шіл",
+ "Там",
+ "Қыр",
+ "Қаз",
+ "Қар",
+ "Жел",
+ ]
+
+ day_names = [
+ "",
+ "Дүйсембі",
+ "Сейсенбі",
+ "Сәрсенбі",
+ "Бейсенбі",
+ "Жұма",
+ "Сенбі",
+ "Жексенбі",
+ ]
+ day_abbreviations = ["", "Дс", "Сс", "Ср", "Бс", "Жм", "Сб", "Жс"]
+
+
+class AmharicLocale(Locale):
+ names = ["am", "am-et"]
+
+ past = "{0} በፊት"
+ future = "{0} ውስጥ"
+ and_word = "እና"
+
+ timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[Mapping[str, str], str]]] = {
+ "now": "አሁን",
+ "second": {
+ "past": "ከአንድ ሰከንድ",
+ "future": "በአንድ ሰከንድ",
+ },
+ "seconds": {
+ "past": "ከ {0} ሰከንድ",
+ "future": "በ {0} ሰከንድ",
+ },
+ "minute": {
+ "past": "ከአንድ ደቂቃ",
+ "future": "በአንድ ደቂቃ",
+ },
+ "minutes": {
+ "past": "ከ {0} ደቂቃዎች",
+ "future": "በ {0} ደቂቃዎች",
+ },
+ "hour": {
+ "past": "ከአንድ ሰዓት",
+ "future": "በአንድ ሰዓት",
+ },
+ "hours": {
+ "past": "ከ {0} ሰዓታት",
+ "future": "በ {0} ሰከንድ",
+ },
+ "day": {
+ "past": "ከአንድ ቀን",
+ "future": "በአንድ ቀን",
+ },
+ "days": {
+ "past": "ከ {0} ቀናት",
+ "future": "በ {0} ቀናት",
+ },
+ "week": {
+ "past": "ከአንድ ሳምንት",
+ "future": "በአንድ ሳምንት",
+ },
+ "weeks": {
+ "past": "ከ {0} ሳምንታት",
+ "future": "በ {0} ሳምንታት",
+ },
+ "month": {
+ "past": "ከአንድ ወር",
+ "future": "በአንድ ወር",
+ },
+ "months": {
+ "past": "ከ {0} ወር",
+ "future": "በ {0} ወራት",
+ },
+ "year": {
+ "past": "ከአንድ አመት",
+ "future": "በአንድ አመት",
+ },
+ "years": {
+ "past": "ከ {0} ዓመታት",
+ "future": "በ {0} ዓመታት",
+ },
+ }
+ # Amharic: the general format to describe timeframe is different from past and future,
+ # so we do not copy the original timeframes dictionary
+ timeframes_only_distance = {
+ "second": "አንድ ሰከንድ",
+ "seconds": "{0} ሰከንድ",
+ "minute": "አንድ ደቂቃ",
+ "minutes": "{0} ደቂቃዎች",
+ "hour": "አንድ ሰዓት",
+ "hours": "{0} ሰዓት",
+ "day": "አንድ ቀን",
+ "days": "{0} ቀናት",
+ "week": "አንድ ሳምንት",
+ "weeks": "{0} ሳምንት",
+ "month": "አንድ ወር",
+ "months": "{0} ወራት",
+ "year": "አንድ አመት",
+ "years": "{0} ዓመታት",
+ }
+
+ month_names = [
+ "",
+ "ጃንዩወሪ",
+ "ፌብሩወሪ",
+ "ማርች",
+ "ኤፕሪል",
+ "ሜይ",
+ "ጁን",
+ "ጁላይ",
+ "ኦገስት",
+ "ሴፕቴምበር",
+ "ኦክቶበር",
+ "ኖቬምበር",
+ "ዲሴምበር",
+ ]
+
+ month_abbreviations = [
+ "",
+ "ጃንዩ",
+ "ፌብሩ",
+ "ማርች",
+ "ኤፕሪ",
+ "ሜይ",
+ "ጁን",
+ "ጁላይ",
+ "ኦገስ",
+ "ሴፕቴ",
+ "ኦክቶ",
+ "ኖቬም",
+ "ዲሴም",
+ ]
+
+ day_names = [
+ "",
+ "ሰኞ",
+ "ማክሰኞ",
+ "ረቡዕ",
+ "ሐሙስ",
+ "ዓርብ",
+ "ቅዳሜ",
+ "እሑድ",
+ ]
+ day_abbreviations = ["", "እ", "ሰ", "ማ", "ረ", "ሐ", "ዓ", "ቅ"]
+
+ def _ordinal_number(self, n: int) -> str:
+ return f"{n}ኛ"
+
+ def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
+ """
+ Amharic awares time frame format function, takes into account
+ the differences between general, past, and future forms (three different suffixes).
+ """
+ abs_delta = abs(delta)
+ form = self.timeframes[timeframe]
+
+ if isinstance(form, str):
+ return form.format(abs_delta)
+
+ if delta > 0:
+ key = "future"
+ else:
+ key = "past"
+ form = form[key]
+
+ return form.format(abs_delta)
+
+ def describe(
+ self,
+ timeframe: TimeFrameLiteral,
+ delta: Union[float, int] = 1, # key is always future when only_distance=False
+ only_distance: bool = False,
+ ) -> str:
+ """Describes a delta within a timeframe in plain language.
+
+ :param timeframe: a string representing a timeframe.
+ :param delta: a quantity representing a delta in a timeframe.
+ :param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
+ """
+
+ if not only_distance:
+ return super().describe(timeframe, delta, only_distance)
+ humanized = self.timeframes_only_distance[timeframe].format(trunc(abs(delta)))
+
+ return humanized
+
+
+class ArmenianLocale(Locale):
+ names = ["hy", "hy-am"]
+ past = "{0} առաջ"
+ future = "{0}ից"
+ and_word = "Եվ" # Yev
+
+ timeframes = {
+ "now": "հիմա",
+ "second": "վայրկյան",
+ "seconds": "{0} վայրկյան",
+ "minute": "րոպե",
+ "minutes": "{0} րոպե",
+ "hour": "ժամ",
+ "hours": "{0} ժամ",
+ "day": "օր",
+ "days": "{0} օր",
+ "month": "ամիս",
+ "months": "{0} ամիս",
+ "year": "տարին",
+ "years": "{0} տարին",
+ "week": "շաբաթ",
+ "weeks": "{0} շաբաթ",
+ }
+
+ meridians = {
+ "am": "Ամ",
+ "pm": "պ.մ.",
+ "AM": "Ամ",
+ "PM": "պ.մ.",
+ }
+
+ month_names = [
+ "",
+ "հունվար",
+ "փետրվար",
+ "մարտ",
+ "ապրիլ",
+ "մայիս",
+ "հունիս",
+ "հուլիս",
+ "օգոստոս",
+ "սեպտեմբեր",
+ "հոկտեմբեր",
+ "նոյեմբեր",
+ "դեկտեմբեր",
+ ]
+
+ month_abbreviations = [
+ "",
+ "հունվար",
+ "փետրվար",
+ "մարտ",
+ "ապրիլ",
+ "մայիս",
+ "հունիս",
+ "հուլիս",
+ "օգոստոս",
+ "սեպտեմբեր",
+ "հոկտեմբեր",
+ "նոյեմբեր",
+ "դեկտեմբեր",
+ ]
+
+ day_names = [
+ "",
+ "երկուշաբթի",
+ "երեքշաբթի",
+ "չորեքշաբթի",
+ "հինգշաբթի",
+ "ուրբաթ",
+ "շաբաթ",
+ "կիրակի",
+ ]
+
+ day_abbreviations = [
+ "",
+ "երկ.",
+ "երեք.",
+ "չորեք.",
+ "հինգ.",
+ "ուրբ.",
+ "շաբ.",
+ "կիր.",
+ ]
+
+
+class UzbekLocale(Locale):
+ names = ["uz", "uz-uz"]
+ past = "{0}dan avval"
+ future = "{0}dan keyin"
+ timeframes = {
+ "now": "hozir",
+ "second": "bir soniya",
+ "seconds": "{0} soniya",
+ "minute": "bir daqiqa",
+ "minutes": "{0} daqiqa",
+ "hour": "bir soat",
+ "hours": "{0} soat",
+ "day": "bir kun",
+ "days": "{0} kun",
+ "week": "bir hafta",
+ "weeks": "{0} hafta",
+ "month": "bir oy",
+ "months": "{0} oy",
+ "year": "bir yil",
+ "years": "{0} yil",
+ }
+
+ month_names = [
+ "",
+ "Yanvar",
+ "Fevral",
+ "Mart",
+ "Aprel",
+ "May",
+ "Iyun",
+ "Iyul",
+ "Avgust",
+ "Sentyabr",
+ "Oktyabr",
+ "Noyabr",
+ "Dekabr",
+ ]
+
+ month_abbreviations = [
+ "",
+ "Yan",
+ "Fev",
+ "Mar",
+ "Apr",
+ "May",
+ "Iyn",
+ "Iyl",
+ "Avg",
+ "Sen",
+ "Okt",
+ "Noy",
+ "Dek",
+ ]
+
+ day_names = [
+ "",
+ "Dushanba",
+ "Seshanba",
+ "Chorshanba",
+ "Payshanba",
+ "Juma",
+ "Shanba",
+ "Yakshanba",
+ ]
+
+ day_abbreviations = ["", "Dush", "Sesh", "Chor", "Pay", "Jum", "Shan", "Yak"]
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/parser.py b/strudel_ex/virt/Lib/site-packages/arrow/parser.py
new file mode 100644
index 00000000..645e3da7
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/parser.py
@@ -0,0 +1,771 @@
+"""Provides the :class:`Arrow ` class, a better way to parse datetime strings."""
+
+import re
+import sys
+from datetime import datetime, timedelta
+from datetime import tzinfo as dt_tzinfo
+from functools import lru_cache
+from typing import (
+ Any,
+ ClassVar,
+ Dict,
+ Iterable,
+ List,
+ Match,
+ Optional,
+ Pattern,
+ SupportsFloat,
+ SupportsInt,
+ Tuple,
+ Union,
+ cast,
+ overload,
+)
+
+from dateutil import tz
+
+from arrow import locales
+from arrow.constants import DEFAULT_LOCALE
+from arrow.util import next_weekday, normalize_timestamp
+
+if sys.version_info < (3, 8): # pragma: no cover
+ from typing_extensions import Literal, TypedDict
+else:
+ from typing import Literal, TypedDict # pragma: no cover
+
+
+class ParserError(ValueError):
+ pass
+
+
+# Allows for ParserErrors to be propagated from _build_datetime()
+# when day_of_year errors occur.
+# Before this, the ParserErrors were caught by the try/except in
+# _parse_multiformat() and the appropriate error message was not
+# transmitted to the user.
+class ParserMatchError(ParserError):
+ pass
+
+
+_WEEKDATE_ELEMENT = Union[str, bytes, SupportsInt, bytearray]
+
+_FORMAT_TYPE = Literal[
+ "YYYY",
+ "YY",
+ "MM",
+ "M",
+ "DDDD",
+ "DDD",
+ "DD",
+ "D",
+ "HH",
+ "H",
+ "hh",
+ "h",
+ "mm",
+ "m",
+ "ss",
+ "s",
+ "X",
+ "x",
+ "ZZZ",
+ "ZZ",
+ "Z",
+ "S",
+ "W",
+ "MMMM",
+ "MMM",
+ "Do",
+ "dddd",
+ "ddd",
+ "d",
+ "a",
+ "A",
+]
+
+
+class _Parts(TypedDict, total=False):
+ year: int
+ month: int
+ day_of_year: int
+ day: int
+ hour: int
+ minute: int
+ second: int
+ microsecond: int
+ timestamp: float
+ expanded_timestamp: int
+ tzinfo: dt_tzinfo
+ am_pm: Literal["am", "pm"]
+ day_of_week: int
+ weekdate: Tuple[_WEEKDATE_ELEMENT, _WEEKDATE_ELEMENT, Optional[_WEEKDATE_ELEMENT]]
+
+
+class DateTimeParser:
+ _FORMAT_RE: ClassVar[Pattern[str]] = re.compile(
+ r"(YYY?Y?|MM?M?M?|Do|DD?D?D?|d?d?d?d|HH?|hh?|mm?|ss?|S+|ZZ?Z?|a|A|x|X|W)"
+ )
+ _ESCAPE_RE: ClassVar[Pattern[str]] = re.compile(r"\[[^\[\]]*\]")
+
+ _ONE_OR_TWO_DIGIT_RE: ClassVar[Pattern[str]] = re.compile(r"\d{1,2}")
+ _ONE_OR_TWO_OR_THREE_DIGIT_RE: ClassVar[Pattern[str]] = re.compile(r"\d{1,3}")
+ _ONE_OR_MORE_DIGIT_RE: ClassVar[Pattern[str]] = re.compile(r"\d+")
+ _TWO_DIGIT_RE: ClassVar[Pattern[str]] = re.compile(r"\d{2}")
+ _THREE_DIGIT_RE: ClassVar[Pattern[str]] = re.compile(r"\d{3}")
+ _FOUR_DIGIT_RE: ClassVar[Pattern[str]] = re.compile(r"\d{4}")
+ _TZ_Z_RE: ClassVar[Pattern[str]] = re.compile(r"([\+\-])(\d{2})(?:(\d{2}))?|Z")
+ _TZ_ZZ_RE: ClassVar[Pattern[str]] = re.compile(r"([\+\-])(\d{2})(?:\:(\d{2}))?|Z")
+ _TZ_NAME_RE: ClassVar[Pattern[str]] = re.compile(r"\w[\w+\-/]+")
+ # NOTE: timestamps cannot be parsed from natural language strings (by removing the ^...$) because it will
+ # break cases like "15 Jul 2000" and a format list (see issue #447)
+ _TIMESTAMP_RE: ClassVar[Pattern[str]] = re.compile(r"^\-?\d+\.?\d+$")
+ _TIMESTAMP_EXPANDED_RE: ClassVar[Pattern[str]] = re.compile(r"^\-?\d+$")
+ _TIME_RE: ClassVar[Pattern[str]] = re.compile(
+ r"^(\d{2})(?:\:?(\d{2}))?(?:\:?(\d{2}))?(?:([\.\,])(\d+))?$"
+ )
+ _WEEK_DATE_RE: ClassVar[Pattern[str]] = re.compile(
+ r"(?P\d{4})[\-]?W(?P\d{2})[\-]?(?P\d)?"
+ )
+
+ _BASE_INPUT_RE_MAP: ClassVar[Dict[_FORMAT_TYPE, Pattern[str]]] = {
+ "YYYY": _FOUR_DIGIT_RE,
+ "YY": _TWO_DIGIT_RE,
+ "MM": _TWO_DIGIT_RE,
+ "M": _ONE_OR_TWO_DIGIT_RE,
+ "DDDD": _THREE_DIGIT_RE,
+ "DDD": _ONE_OR_TWO_OR_THREE_DIGIT_RE,
+ "DD": _TWO_DIGIT_RE,
+ "D": _ONE_OR_TWO_DIGIT_RE,
+ "HH": _TWO_DIGIT_RE,
+ "H": _ONE_OR_TWO_DIGIT_RE,
+ "hh": _TWO_DIGIT_RE,
+ "h": _ONE_OR_TWO_DIGIT_RE,
+ "mm": _TWO_DIGIT_RE,
+ "m": _ONE_OR_TWO_DIGIT_RE,
+ "ss": _TWO_DIGIT_RE,
+ "s": _ONE_OR_TWO_DIGIT_RE,
+ "X": _TIMESTAMP_RE,
+ "x": _TIMESTAMP_EXPANDED_RE,
+ "ZZZ": _TZ_NAME_RE,
+ "ZZ": _TZ_ZZ_RE,
+ "Z": _TZ_Z_RE,
+ "S": _ONE_OR_MORE_DIGIT_RE,
+ "W": _WEEK_DATE_RE,
+ }
+
+ SEPARATORS: ClassVar[List[str]] = ["-", "/", "."]
+
+ locale: locales.Locale
+ _input_re_map: Dict[_FORMAT_TYPE, Pattern[str]]
+
+ def __init__(self, locale: str = DEFAULT_LOCALE, cache_size: int = 0) -> None:
+ self.locale = locales.get_locale(locale)
+ self._input_re_map = self._BASE_INPUT_RE_MAP.copy()
+ self._input_re_map.update(
+ {
+ "MMMM": self._generate_choice_re(
+ self.locale.month_names[1:], re.IGNORECASE
+ ),
+ "MMM": self._generate_choice_re(
+ self.locale.month_abbreviations[1:], re.IGNORECASE
+ ),
+ "Do": re.compile(self.locale.ordinal_day_re),
+ "dddd": self._generate_choice_re(
+ self.locale.day_names[1:], re.IGNORECASE
+ ),
+ "ddd": self._generate_choice_re(
+ self.locale.day_abbreviations[1:], re.IGNORECASE
+ ),
+ "d": re.compile(r"[1-7]"),
+ "a": self._generate_choice_re(
+ (self.locale.meridians["am"], self.locale.meridians["pm"])
+ ),
+ # note: 'A' token accepts both 'am/pm' and 'AM/PM' formats to
+ # ensure backwards compatibility of this token
+ "A": self._generate_choice_re(self.locale.meridians.values()),
+ }
+ )
+ if cache_size > 0:
+ self._generate_pattern_re = lru_cache(maxsize=cache_size)( # type: ignore
+ self._generate_pattern_re
+ )
+
+ # TODO: since we support more than ISO 8601, we should rename this function
+ # IDEA: break into multiple functions
+ def parse_iso(
+ self, datetime_string: str, normalize_whitespace: bool = False
+ ) -> datetime:
+ if normalize_whitespace:
+ datetime_string = re.sub(r"\s+", " ", datetime_string.strip())
+
+ has_space_divider = " " in datetime_string
+ has_t_divider = "T" in datetime_string
+
+ num_spaces = datetime_string.count(" ")
+ if has_space_divider and num_spaces != 1 or has_t_divider and num_spaces > 0:
+ raise ParserError(
+ f"Expected an ISO 8601-like string, but was given {datetime_string!r}. "
+ "Try passing in a format string to resolve this."
+ )
+
+ has_time = has_space_divider or has_t_divider
+ has_tz = False
+
+ # date formats (ISO 8601 and others) to test against
+ # NOTE: YYYYMM is omitted to avoid confusion with YYMMDD (no longer part of ISO 8601, but is still often used)
+ formats = [
+ "YYYY-MM-DD",
+ "YYYY-M-DD",
+ "YYYY-M-D",
+ "YYYY/MM/DD",
+ "YYYY/M/DD",
+ "YYYY/M/D",
+ "YYYY.MM.DD",
+ "YYYY.M.DD",
+ "YYYY.M.D",
+ "YYYYMMDD",
+ "YYYY-DDDD",
+ "YYYYDDDD",
+ "YYYY-MM",
+ "YYYY/MM",
+ "YYYY.MM",
+ "YYYY",
+ "W",
+ ]
+
+ if has_time:
+ if has_space_divider:
+ date_string, time_string = datetime_string.split(" ", 1)
+ else:
+ date_string, time_string = datetime_string.split("T", 1)
+
+ time_parts = re.split(
+ r"[\+\-Z]", time_string, maxsplit=1, flags=re.IGNORECASE
+ )
+
+ time_components: Optional[Match[str]] = self._TIME_RE.match(time_parts[0])
+
+ if time_components is None:
+ raise ParserError(
+ "Invalid time component provided. "
+ "Please specify a format or provide a valid time component in the basic or extended ISO 8601 time format."
+ )
+
+ (
+ hours,
+ minutes,
+ seconds,
+ subseconds_sep,
+ subseconds,
+ ) = time_components.groups()
+
+ has_tz = len(time_parts) == 2
+ has_minutes = minutes is not None
+ has_seconds = seconds is not None
+ has_subseconds = subseconds is not None
+
+ is_basic_time_format = ":" not in time_parts[0]
+ tz_format = "Z"
+
+ # use 'ZZ' token instead since tz offset is present in non-basic format
+ if has_tz and ":" in time_parts[1]:
+ tz_format = "ZZ"
+
+ time_sep = "" if is_basic_time_format else ":"
+
+ if has_subseconds:
+ time_string = "HH{time_sep}mm{time_sep}ss{subseconds_sep}S".format(
+ time_sep=time_sep, subseconds_sep=subseconds_sep
+ )
+ elif has_seconds:
+ time_string = "HH{time_sep}mm{time_sep}ss".format(time_sep=time_sep)
+ elif has_minutes:
+ time_string = f"HH{time_sep}mm"
+ else:
+ time_string = "HH"
+
+ if has_space_divider:
+ formats = [f"{f} {time_string}" for f in formats]
+ else:
+ formats = [f"{f}T{time_string}" for f in formats]
+
+ if has_time and has_tz:
+ # Add "Z" or "ZZ" to the format strings to indicate to
+ # _parse_token() that a timezone needs to be parsed
+ formats = [f"{f}{tz_format}" for f in formats]
+
+ return self._parse_multiformat(datetime_string, formats)
+
+ def parse(
+ self,
+ datetime_string: str,
+ fmt: Union[List[str], str],
+ normalize_whitespace: bool = False,
+ ) -> datetime:
+ if normalize_whitespace:
+ datetime_string = re.sub(r"\s+", " ", datetime_string)
+
+ if isinstance(fmt, list):
+ return self._parse_multiformat(datetime_string, fmt)
+
+ try:
+ fmt_tokens: List[_FORMAT_TYPE]
+ fmt_pattern_re: Pattern[str]
+ fmt_tokens, fmt_pattern_re = self._generate_pattern_re(fmt)
+ except re.error as e:
+ raise ParserMatchError(
+ f"Failed to generate regular expression pattern: {e}."
+ )
+
+ match = fmt_pattern_re.search(datetime_string)
+
+ if match is None:
+ raise ParserMatchError(
+ f"Failed to match {fmt!r} when parsing {datetime_string!r}."
+ )
+
+ parts: _Parts = {}
+ for token in fmt_tokens:
+ value: Union[Tuple[str, str, str], str]
+ if token == "Do":
+ value = match.group("value")
+ elif token == "W":
+ value = (match.group("year"), match.group("week"), match.group("day"))
+ else:
+ value = match.group(token)
+
+ if value is None:
+ raise ParserMatchError(
+ f"Unable to find a match group for the specified token {token!r}."
+ )
+
+ self._parse_token(token, value, parts) # type: ignore[arg-type]
+
+ return self._build_datetime(parts)
+
+ def _generate_pattern_re(self, fmt: str) -> Tuple[List[_FORMAT_TYPE], Pattern[str]]:
+ # fmt is a string of tokens like 'YYYY-MM-DD'
+ # we construct a new string by replacing each
+ # token by its pattern:
+ # 'YYYY-MM-DD' -> '(?P\d{4})-(?P\d{2})-(?P
\d{2})'
+ tokens: List[_FORMAT_TYPE] = []
+ offset = 0
+
+ # Escape all special RegEx chars
+ escaped_fmt = re.escape(fmt)
+
+ # Extract the bracketed expressions to be reinserted later.
+ escaped_fmt = re.sub(self._ESCAPE_RE, "#", escaped_fmt)
+
+ # Any number of S is the same as one.
+ # TODO: allow users to specify the number of digits to parse
+ escaped_fmt = re.sub(r"S+", "S", escaped_fmt)
+
+ escaped_data = re.findall(self._ESCAPE_RE, fmt)
+
+ fmt_pattern = escaped_fmt
+
+ for m in self._FORMAT_RE.finditer(escaped_fmt):
+ token: _FORMAT_TYPE = cast(_FORMAT_TYPE, m.group(0))
+ try:
+ input_re = self._input_re_map[token]
+ except KeyError:
+ raise ParserError(f"Unrecognized token {token!r}.")
+ input_pattern = f"(?P<{token}>{input_re.pattern})"
+ tokens.append(token)
+ # a pattern doesn't have the same length as the token
+ # it replaces! We keep the difference in the offset variable.
+ # This works because the string is scanned left-to-right and matches
+ # are returned in the order found by finditer.
+ fmt_pattern = (
+ fmt_pattern[: m.start() + offset]
+ + input_pattern
+ + fmt_pattern[m.end() + offset :]
+ )
+ offset += len(input_pattern) - (m.end() - m.start())
+
+ final_fmt_pattern = ""
+ split_fmt = fmt_pattern.split(r"\#")
+
+ # Due to the way Python splits, 'split_fmt' will always be longer
+ for i in range(len(split_fmt)):
+ final_fmt_pattern += split_fmt[i]
+ if i < len(escaped_data):
+ final_fmt_pattern += escaped_data[i][1:-1]
+
+ # Wrap final_fmt_pattern in a custom word boundary to strictly
+ # match the formatting pattern and filter out date and time formats
+ # that include junk such as: blah1998-09-12 blah, blah 1998-09-12blah,
+ # blah1998-09-12blah. The custom word boundary matches every character
+ # that is not a whitespace character to allow for searching for a date
+ # and time string in a natural language sentence. Therefore, searching
+ # for a string of the form YYYY-MM-DD in "blah 1998-09-12 blah" will
+ # work properly.
+ # Certain punctuation before or after the target pattern such as
+ # "1998-09-12," is permitted. For the full list of valid punctuation,
+ # see the documentation.
+
+ starting_word_boundary = (
+ r"(?\s])" # This is the list of punctuation that is ok before the
+ # pattern (i.e. "It can't not be these characters before the pattern")
+ r"(\b|^)"
+ # The \b is to block cases like 1201912 but allow 201912 for pattern YYYYMM. The ^ was necessary to allow a
+ # negative number through i.e. before epoch numbers
+ )
+ ending_word_boundary = (
+ r"(?=[\,\.\;\:\?\!\"\'\`\[\]\{\}\(\)\<\>]?" # Positive lookahead stating that these punctuation marks
+ # can appear after the pattern at most 1 time
+ r"(?!\S))" # Don't allow any non-whitespace character after the punctuation
+ )
+ bounded_fmt_pattern = r"{}{}{}".format(
+ starting_word_boundary, final_fmt_pattern, ending_word_boundary
+ )
+
+ return tokens, re.compile(bounded_fmt_pattern, flags=re.IGNORECASE)
+
+ @overload
+ def _parse_token(
+ self,
+ token: Literal[
+ "YYYY",
+ "YY",
+ "MM",
+ "M",
+ "DDDD",
+ "DDD",
+ "DD",
+ "D",
+ "Do",
+ "HH",
+ "hh",
+ "h",
+ "H",
+ "mm",
+ "m",
+ "ss",
+ "s",
+ "x",
+ ],
+ value: Union[str, bytes, SupportsInt, bytearray],
+ parts: _Parts,
+ ) -> None:
+ ... # pragma: no cover
+
+ @overload
+ def _parse_token(
+ self,
+ token: Literal["X"],
+ value: Union[str, bytes, SupportsFloat, bytearray],
+ parts: _Parts,
+ ) -> None:
+ ... # pragma: no cover
+
+ @overload
+ def _parse_token(
+ self,
+ token: Literal["MMMM", "MMM", "dddd", "ddd", "S"],
+ value: Union[str, bytes, bytearray],
+ parts: _Parts,
+ ) -> None:
+ ... # pragma: no cover
+
+ @overload
+ def _parse_token(
+ self,
+ token: Literal["a", "A", "ZZZ", "ZZ", "Z"],
+ value: Union[str, bytes],
+ parts: _Parts,
+ ) -> None:
+ ... # pragma: no cover
+
+ @overload
+ def _parse_token(
+ self,
+ token: Literal["W"],
+ value: Tuple[_WEEKDATE_ELEMENT, _WEEKDATE_ELEMENT, Optional[_WEEKDATE_ELEMENT]],
+ parts: _Parts,
+ ) -> None:
+ ... # pragma: no cover
+
+ def _parse_token(
+ self,
+ token: Any,
+ value: Any,
+ parts: _Parts,
+ ) -> None:
+ if token == "YYYY":
+ parts["year"] = int(value)
+
+ elif token == "YY":
+ value = int(value)
+ parts["year"] = 1900 + value if value > 68 else 2000 + value
+
+ elif token in ["MMMM", "MMM"]:
+ # FIXME: month_number() is nullable
+ parts["month"] = self.locale.month_number(value.lower()) # type: ignore[typeddict-item]
+
+ elif token in ["MM", "M"]:
+ parts["month"] = int(value)
+
+ elif token in ["DDDD", "DDD"]:
+ parts["day_of_year"] = int(value)
+
+ elif token in ["DD", "D"]:
+ parts["day"] = int(value)
+
+ elif token == "Do":
+ parts["day"] = int(value)
+
+ elif token == "dddd":
+ # locale day names are 1-indexed
+ day_of_week = [x.lower() for x in self.locale.day_names].index(
+ value.lower()
+ )
+ parts["day_of_week"] = day_of_week - 1
+
+ elif token == "ddd":
+ # locale day abbreviations are 1-indexed
+ day_of_week = [x.lower() for x in self.locale.day_abbreviations].index(
+ value.lower()
+ )
+ parts["day_of_week"] = day_of_week - 1
+
+ elif token.upper() in ["HH", "H"]:
+ parts["hour"] = int(value)
+
+ elif token in ["mm", "m"]:
+ parts["minute"] = int(value)
+
+ elif token in ["ss", "s"]:
+ parts["second"] = int(value)
+
+ elif token == "S":
+ # We have the *most significant* digits of an arbitrary-precision integer.
+ # We want the six most significant digits as an integer, rounded.
+ # IDEA: add nanosecond support somehow? Need datetime support for it first.
+ value = value.ljust(7, "0")
+
+ # floating-point (IEEE-754) defaults to half-to-even rounding
+ seventh_digit = int(value[6])
+ if seventh_digit == 5:
+ rounding = int(value[5]) % 2
+ elif seventh_digit > 5:
+ rounding = 1
+ else:
+ rounding = 0
+
+ parts["microsecond"] = int(value[:6]) + rounding
+
+ elif token == "X":
+ parts["timestamp"] = float(value)
+
+ elif token == "x":
+ parts["expanded_timestamp"] = int(value)
+
+ elif token in ["ZZZ", "ZZ", "Z"]:
+ parts["tzinfo"] = TzinfoParser.parse(value)
+
+ elif token in ["a", "A"]:
+ if value in (self.locale.meridians["am"], self.locale.meridians["AM"]):
+ parts["am_pm"] = "am"
+ if "hour" in parts and not 0 <= parts["hour"] <= 12:
+ raise ParserMatchError(
+ f"Hour token value must be between 0 and 12 inclusive for token {token!r}."
+ )
+ elif value in (self.locale.meridians["pm"], self.locale.meridians["PM"]):
+ parts["am_pm"] = "pm"
+ elif token == "W":
+ parts["weekdate"] = value
+
+ @staticmethod
+ def _build_datetime(parts: _Parts) -> datetime:
+ weekdate = parts.get("weekdate")
+
+ if weekdate is not None:
+ year, week = int(weekdate[0]), int(weekdate[1])
+
+ if weekdate[2] is not None:
+ _day = int(weekdate[2])
+ else:
+ # day not given, default to 1
+ _day = 1
+
+ date_string = f"{year}-{week}-{_day}"
+
+ # tokens for ISO 8601 weekdates
+ dt = datetime.strptime(date_string, "%G-%V-%u")
+
+ parts["year"] = dt.year
+ parts["month"] = dt.month
+ parts["day"] = dt.day
+
+ timestamp = parts.get("timestamp")
+
+ if timestamp is not None:
+ return datetime.fromtimestamp(timestamp, tz=tz.tzutc())
+
+ expanded_timestamp = parts.get("expanded_timestamp")
+
+ if expanded_timestamp is not None:
+ return datetime.fromtimestamp(
+ normalize_timestamp(expanded_timestamp),
+ tz=tz.tzutc(),
+ )
+
+ day_of_year = parts.get("day_of_year")
+
+ if day_of_year is not None:
+ _year = parts.get("year")
+ month = parts.get("month")
+ if _year is None:
+ raise ParserError(
+ "Year component is required with the DDD and DDDD tokens."
+ )
+
+ if month is not None:
+ raise ParserError(
+ "Month component is not allowed with the DDD and DDDD tokens."
+ )
+
+ date_string = f"{_year}-{day_of_year}"
+ try:
+ dt = datetime.strptime(date_string, "%Y-%j")
+ except ValueError:
+ raise ParserError(
+ f"The provided day of year {day_of_year!r} is invalid."
+ )
+
+ parts["year"] = dt.year
+ parts["month"] = dt.month
+ parts["day"] = dt.day
+
+ day_of_week: Optional[int] = parts.get("day_of_week")
+ day = parts.get("day")
+
+ # If day is passed, ignore day of week
+ if day_of_week is not None and day is None:
+ year = parts.get("year", 1970)
+ month = parts.get("month", 1)
+ day = 1
+
+ # dddd => first day of week after epoch
+ # dddd YYYY => first day of week in specified year
+ # dddd MM YYYY => first day of week in specified year and month
+ # dddd MM => first day after epoch in specified month
+ next_weekday_dt = next_weekday(datetime(year, month, day), day_of_week)
+ parts["year"] = next_weekday_dt.year
+ parts["month"] = next_weekday_dt.month
+ parts["day"] = next_weekday_dt.day
+
+ am_pm = parts.get("am_pm")
+ hour = parts.get("hour", 0)
+
+ if am_pm == "pm" and hour < 12:
+ hour += 12
+ elif am_pm == "am" and hour == 12:
+ hour = 0
+
+ # Support for midnight at the end of day
+ if hour == 24:
+ if parts.get("minute", 0) != 0:
+ raise ParserError("Midnight at the end of day must not contain minutes")
+ if parts.get("second", 0) != 0:
+ raise ParserError("Midnight at the end of day must not contain seconds")
+ if parts.get("microsecond", 0) != 0:
+ raise ParserError(
+ "Midnight at the end of day must not contain microseconds"
+ )
+ hour = 0
+ day_increment = 1
+ else:
+ day_increment = 0
+
+ # account for rounding up to 1000000
+ microsecond = parts.get("microsecond", 0)
+ if microsecond == 1000000:
+ microsecond = 0
+ second_increment = 1
+ else:
+ second_increment = 0
+
+ increment = timedelta(days=day_increment, seconds=second_increment)
+
+ return (
+ datetime(
+ year=parts.get("year", 1),
+ month=parts.get("month", 1),
+ day=parts.get("day", 1),
+ hour=hour,
+ minute=parts.get("minute", 0),
+ second=parts.get("second", 0),
+ microsecond=microsecond,
+ tzinfo=parts.get("tzinfo"),
+ )
+ + increment
+ )
+
+ def _parse_multiformat(self, string: str, formats: Iterable[str]) -> datetime:
+ _datetime: Optional[datetime] = None
+
+ for fmt in formats:
+ try:
+ _datetime = self.parse(string, fmt)
+ break
+ except ParserMatchError:
+ pass
+
+ if _datetime is None:
+ supported_formats = ", ".join(formats)
+ raise ParserError(
+ f"Could not match input {string!r} to any of the following formats: {supported_formats}."
+ )
+
+ return _datetime
+
+ # generates a capture group of choices separated by an OR operator
+ @staticmethod
+ def _generate_choice_re(
+ choices: Iterable[str], flags: Union[int, re.RegexFlag] = 0
+ ) -> Pattern[str]:
+ return re.compile(r"({})".format("|".join(choices)), flags=flags)
+
+
+class TzinfoParser:
+ _TZINFO_RE: ClassVar[Pattern[str]] = re.compile(
+ r"^(?:\(UTC)*([\+\-])?(\d{2})(?:\:?(\d{2}))?"
+ )
+
+ @classmethod
+ def parse(cls, tzinfo_string: str) -> dt_tzinfo:
+ tzinfo: Optional[dt_tzinfo] = None
+
+ if tzinfo_string == "local":
+ tzinfo = tz.tzlocal()
+
+ elif tzinfo_string in ["utc", "UTC", "Z"]:
+ tzinfo = tz.tzutc()
+
+ else:
+ iso_match = cls._TZINFO_RE.match(tzinfo_string)
+
+ if iso_match:
+ sign: Optional[str]
+ hours: str
+ minutes: Union[str, int, None]
+ sign, hours, minutes = iso_match.groups()
+ seconds = int(hours) * 3600 + int(minutes or 0) * 60
+
+ if sign == "-":
+ seconds *= -1
+
+ tzinfo = tz.tzoffset(None, seconds)
+
+ else:
+ tzinfo = tz.gettz(tzinfo_string)
+
+ if tzinfo is None:
+ raise ParserError(f"Could not parse timezone expression {tzinfo_string!r}.")
+
+ return tzinfo
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/py.typed b/strudel_ex/virt/Lib/site-packages/arrow/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/strudel_ex/virt/Lib/site-packages/arrow/util.py b/strudel_ex/virt/Lib/site-packages/arrow/util.py
new file mode 100644
index 00000000..f3eaa21c
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/arrow/util.py
@@ -0,0 +1,117 @@
+"""Helpful functions used internally within arrow."""
+
+import datetime
+from typing import Any, Optional, cast
+
+from dateutil.rrule import WEEKLY, rrule
+
+from arrow.constants import (
+ MAX_ORDINAL,
+ MAX_TIMESTAMP,
+ MAX_TIMESTAMP_MS,
+ MAX_TIMESTAMP_US,
+ MIN_ORDINAL,
+)
+
+
+def next_weekday(
+ start_date: Optional[datetime.date], weekday: int
+) -> datetime.datetime:
+ """Get next weekday from the specified start date.
+
+ :param start_date: Datetime object representing the start date.
+ :param weekday: Next weekday to obtain. Can be a value between 0 (Monday) and 6 (Sunday).
+ :return: Datetime object corresponding to the next weekday after start_date.
+
+ Usage::
+
+ # Get first Monday after epoch
+ >>> next_weekday(datetime(1970, 1, 1), 0)
+ 1970-01-05 00:00:00
+
+ # Get first Thursday after epoch
+ >>> next_weekday(datetime(1970, 1, 1), 3)
+ 1970-01-01 00:00:00
+
+ # Get first Sunday after epoch
+ >>> next_weekday(datetime(1970, 1, 1), 6)
+ 1970-01-04 00:00:00
+ """
+ if weekday < 0 or weekday > 6:
+ raise ValueError("Weekday must be between 0 (Monday) and 6 (Sunday).")
+ return cast(
+ datetime.datetime,
+ rrule(freq=WEEKLY, dtstart=start_date, byweekday=weekday, count=1)[0],
+ )
+
+
+def is_timestamp(value: Any) -> bool:
+ """Check if value is a valid timestamp."""
+ if isinstance(value, bool):
+ return False
+ if not isinstance(value, (int, float, str)):
+ return False
+ try:
+ float(value)
+ return True
+ except ValueError:
+ return False
+
+
+def validate_ordinal(value: Any) -> None:
+ """Raise an exception if value is an invalid Gregorian ordinal.
+
+ :param value: the input to be checked
+
+ """
+ if isinstance(value, bool) or not isinstance(value, int):
+ raise TypeError(f"Ordinal must be an integer (got type {type(value)}).")
+ if not (MIN_ORDINAL <= value <= MAX_ORDINAL):
+ raise ValueError(f"Ordinal {value} is out of range.")
+
+
+def normalize_timestamp(timestamp: float) -> float:
+ """Normalize millisecond and microsecond timestamps into normal timestamps."""
+ if timestamp > MAX_TIMESTAMP:
+ if timestamp < MAX_TIMESTAMP_MS:
+ timestamp /= 1000
+ elif timestamp < MAX_TIMESTAMP_US:
+ timestamp /= 1_000_000
+ else:
+ raise ValueError(f"The specified timestamp {timestamp!r} is too large.")
+ return timestamp
+
+
+# Credit to https://stackoverflow.com/a/1700069
+def iso_to_gregorian(iso_year: int, iso_week: int, iso_day: int) -> datetime.date:
+ """Converts an ISO week date into a datetime object.
+
+ :param iso_year: the year
+ :param iso_week: the week number, each year has either 52 or 53 weeks
+ :param iso_day: the day numbered 1 through 7, beginning with Monday
+
+ """
+
+ if not 1 <= iso_week <= 53:
+ raise ValueError("ISO Calendar week value must be between 1-53.")
+
+ if not 1 <= iso_day <= 7:
+ raise ValueError("ISO Calendar day value must be between 1-7")
+
+ # The first week of the year always contains 4 Jan.
+ fourth_jan = datetime.date(iso_year, 1, 4)
+ delta = datetime.timedelta(fourth_jan.isoweekday() - 1)
+ year_start = fourth_jan - delta
+ gregorian = year_start + datetime.timedelta(days=iso_day - 1, weeks=iso_week - 1)
+
+ return gregorian
+
+
+def validate_bounds(bounds: str) -> None:
+ if bounds != "()" and bounds != "(]" and bounds != "[)" and bounds != "[]":
+ raise ValueError(
+ "Invalid bounds. Please select between '()', '(]', '[)', or '[]'."
+ )
+
+
+__all__ = ["next_weekday", "is_timestamp", "validate_ordinal", "iso_to_gregorian"]
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/DESCRIPTION.rst b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/DESCRIPTION.rst
new file mode 100644
index 00000000..4ef00734
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/DESCRIPTION.rst
@@ -0,0 +1,152 @@
+=============================
+BinaryOrNot
+=============================
+
+.. image:: https://img.shields.io/pypi/v/binaryornot.svg?style=flat
+ :target: https://pypi.python.org/pypi/binaryornot
+
+.. image:: https://readthedocs.org/projects/binaryornot/badge/?version=latest
+ :target: http://binaryornot.readthedocs.io/en/latest/?badge=latest
+ :alt: Documentation Status
+
+
+.. image:: https://pyup.io/repos/github/audreyr/binaryornot/shield.svg
+ :target: https://pyup.io/repos/github/audreyr/binaryornot/
+ :alt: Updates
+
+Ultra-lightweight pure Python package to guess whether a file is binary or text,
+using a heuristic similar to Perl's `pp_fttext` and its analysis by @eliben.
+
+* Free software: BSD license
+* Documentation: https://binaryornot.readthedocs.io
+
+Status
+------
+
+It works, and people are using this package in various places. But it doesn't cover all edge cases yet.
+
+The code could be improved. Pull requests welcome! As of now, it is based on these snippets, but that may change:
+
+* http://stackoverflow.com/questions/898669/how-can-i-detect-if-a-file-is-binary-non-text-in-python
+* http://stackoverflow.com/questions/1446549/how-to-identify-binary-and-text-files-using-python
+* http://code.activestate.com/recipes/173220/
+* http://eli.thegreenplace.net/2011/10/19/perls-guess-if-file-is-text-or-binary-implemented-in-python/
+
+Features
+--------
+
+Has tests for these file types:
+
+* Text: .txt, .css, .json, .svg, .js, .lua, .pl, .rst
+* Binary: .png, .gif, .jpg, .tiff, .bmp, .DS_Store, .eot, .otf, .ttf, .woff, .rgb
+
+Has tests for numerous encodings.
+
+Why?
+----
+
+You may be thinking, "I can write this in 2 lines of code?!"
+
+It's actually not that easy. Here's a great article about how Perl's
+heuristic to guess file types works: http://eli.thegreenplace.net/2011/10/19/perls-guess-if-file-is-text-or-binary-implemented-in-python/
+
+And that's just where we started. Over time, we've found more edge cases and
+our heuristic has gotten more complex.
+
+Also, this package saves you from having to write and thoroughly test
+your code with all sorts of weird file types and encodings, cross-platform.
+
+Builds
+------
+
+Linux (Ubuntu 12.04 LTS Server Edition 64 bit):
+
+.. image:: https://img.shields.io/travis/audreyr/binaryornot/master.svg
+ :target: https://travis-ci.org/audreyr/binaryornot
+
+Windows (Windows Server 2012 R2 (x64)):
+
+.. image:: https://img.shields.io/appveyor/ci/audreyr/binaryornot/master.svg
+ :target: https://ci.appveyor.com/project/audreyr/binaryornot
+
+Credits
+-------
+
+* Special thanks to Eli Bendersky (@eliben) for his writeup explaining the heuristic and his implementation, which this is largely based on.
+* Source code from the portion of Perl's `pp_fttext` that checks for textiness: https://github.com/Perl/perl5/blob/v5.23.1/pp_sys.c#L3527-L3587
+
+
+
+
+History
+-------
+
+0.4.4 (2017-04-13)
+~~~~~~~~~~~~~~~~~~
+
+* Notify users for file i/o issues. Thanks @lukehinds!
+
+
+0.4.3 (2017-04-13)
+~~~~~~~~~~~~~~~~~~
+
+* Restricted chardet to anything 3.0.2 or higher due to https://github.com/chardet/chardet/issues/113. Thanks @dan-blanchard for the quick fix!
+
+0.4.2 (2017-04-12)
+~~~~~~~~~~~~~~~~~~
+
+* Restricted chardet to anything under 3.0 due to https://github.com/chardet/chardet/issues/113
+* Added pyup badge
+* Added utilities for pushing new versions up
+
+0.4.0 (2015-08-21)
+~~~~~~~~~~~~~~~~~~
+
+* Enhanced detection for some binary streams and UTF texts. (#10, 11) Thanks `@pombredanne`_.
+* Set up Appveyor for continuous testing on Windows. Thanks `@pydanny`_.
+* Update link to Perl source implementation. (#9) Thanks `@asmeurer`_ `@pombredanne`_ `@audreyr`_.
+* Handle UnicodeDecodeError in check. (#12) Thanks `@DRMacIver`_.
+* Add very simple Hypothesis based tests. (#13) Thanks `@DRMacIver`_.
+* Use setup to determine requirements and remove redundant requirements.txt. (#14) Thanks `@hackebrot`_.
+* Add documentation status badge to README.rst. (#15) Thanks `@hackebrot`_.
+* Run tox in travis.yml. Add pypy and Python 3.4 to tox environments. (#16) Thanks `@hackebrot`_ `@pydanny`_.
+* Handle LookupError when detecting encoding. (#17) Thanks `@DRMacIver`_.
+
+
+.. _`@pombredanne`: https://github.com/pombredanne
+.. _`@pydanny`: https://github.com/pydanny
+.. _`@asmeurer`: https://github.com/asmeurer
+.. _`@audreyr`: https://github.com/audreyr
+.. _`@DRMacIver`: https://github.com/DRMacIver
+.. _`@hackebrot`: https://github.com/hackebrot
+
+0.3.0 (2014-05-05)
+~~~~~~~~~~~~~~~~~~
+
+* Include tests, docs in source package. (#6) Thanks `@vincentbernat`_.
+* Drop unnecessary shebangs and executable bits. (#8) Thanks `@scop`_.
+* Generate string of printable extended ASCII bytes only once. (#7) Thanks `@scop`_.
+* Make number of bytes to read parametrizable. (#7) Thanks `@scop`_.
+
+.. _`@vincentbernat`: https://github.com/vincentbernat
+.. _`@scop`: https://github.com/scop
+
+0.2.0 (2013-09-22)
+~~~~~~~~~~~~~~~~~~
+
+* Complete rewrite of everything. Thanks `@ncoghlan`_.
+
+.. _`@ncoghlan`: https://github.com/ncoghlan
+
+0.1.1 (2013-08-17)
+~~~~~~~~~~~~~~~~~~
+
+* Tests pass under Python 2.6, 2.7, 3.3, PyPy.
+
+
+0.1.0 (2013-08-17)
+~~~~~~~~~~~~~~~~~~
+
+* First release on PyPI.
+
+
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/INSTALLER b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/METADATA b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/METADATA
new file mode 100644
index 00000000..cabfe745
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/METADATA
@@ -0,0 +1,175 @@
+Metadata-Version: 2.0
+Name: binaryornot
+Version: 0.4.4
+Summary: Ultra-lightweight pure Python package to check if a file is binary or text.
+Home-page: https://github.com/audreyr/binaryornot
+Author: Audrey Roy Greenfeld
+Author-email: aroy@alum.mit.edu
+License: BSD
+Keywords: binaryornot
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Natural Language :: English
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Requires-Dist: chardet (>=3.0.2)
+
+=============================
+BinaryOrNot
+=============================
+
+.. image:: https://img.shields.io/pypi/v/binaryornot.svg?style=flat
+ :target: https://pypi.python.org/pypi/binaryornot
+
+.. image:: https://readthedocs.org/projects/binaryornot/badge/?version=latest
+ :target: http://binaryornot.readthedocs.io/en/latest/?badge=latest
+ :alt: Documentation Status
+
+
+.. image:: https://pyup.io/repos/github/audreyr/binaryornot/shield.svg
+ :target: https://pyup.io/repos/github/audreyr/binaryornot/
+ :alt: Updates
+
+Ultra-lightweight pure Python package to guess whether a file is binary or text,
+using a heuristic similar to Perl's `pp_fttext` and its analysis by @eliben.
+
+* Free software: BSD license
+* Documentation: https://binaryornot.readthedocs.io
+
+Status
+------
+
+It works, and people are using this package in various places. But it doesn't cover all edge cases yet.
+
+The code could be improved. Pull requests welcome! As of now, it is based on these snippets, but that may change:
+
+* http://stackoverflow.com/questions/898669/how-can-i-detect-if-a-file-is-binary-non-text-in-python
+* http://stackoverflow.com/questions/1446549/how-to-identify-binary-and-text-files-using-python
+* http://code.activestate.com/recipes/173220/
+* http://eli.thegreenplace.net/2011/10/19/perls-guess-if-file-is-text-or-binary-implemented-in-python/
+
+Features
+--------
+
+Has tests for these file types:
+
+* Text: .txt, .css, .json, .svg, .js, .lua, .pl, .rst
+* Binary: .png, .gif, .jpg, .tiff, .bmp, .DS_Store, .eot, .otf, .ttf, .woff, .rgb
+
+Has tests for numerous encodings.
+
+Why?
+----
+
+You may be thinking, "I can write this in 2 lines of code?!"
+
+It's actually not that easy. Here's a great article about how Perl's
+heuristic to guess file types works: http://eli.thegreenplace.net/2011/10/19/perls-guess-if-file-is-text-or-binary-implemented-in-python/
+
+And that's just where we started. Over time, we've found more edge cases and
+our heuristic has gotten more complex.
+
+Also, this package saves you from having to write and thoroughly test
+your code with all sorts of weird file types and encodings, cross-platform.
+
+Builds
+------
+
+Linux (Ubuntu 12.04 LTS Server Edition 64 bit):
+
+.. image:: https://img.shields.io/travis/audreyr/binaryornot/master.svg
+ :target: https://travis-ci.org/audreyr/binaryornot
+
+Windows (Windows Server 2012 R2 (x64)):
+
+.. image:: https://img.shields.io/appveyor/ci/audreyr/binaryornot/master.svg
+ :target: https://ci.appveyor.com/project/audreyr/binaryornot
+
+Credits
+-------
+
+* Special thanks to Eli Bendersky (@eliben) for his writeup explaining the heuristic and his implementation, which this is largely based on.
+* Source code from the portion of Perl's `pp_fttext` that checks for textiness: https://github.com/Perl/perl5/blob/v5.23.1/pp_sys.c#L3527-L3587
+
+
+
+
+History
+-------
+
+0.4.4 (2017-04-13)
+~~~~~~~~~~~~~~~~~~
+
+* Notify users for file i/o issues. Thanks @lukehinds!
+
+
+0.4.3 (2017-04-13)
+~~~~~~~~~~~~~~~~~~
+
+* Restricted chardet to anything 3.0.2 or higher due to https://github.com/chardet/chardet/issues/113. Thanks @dan-blanchard for the quick fix!
+
+0.4.2 (2017-04-12)
+~~~~~~~~~~~~~~~~~~
+
+* Restricted chardet to anything under 3.0 due to https://github.com/chardet/chardet/issues/113
+* Added pyup badge
+* Added utilities for pushing new versions up
+
+0.4.0 (2015-08-21)
+~~~~~~~~~~~~~~~~~~
+
+* Enhanced detection for some binary streams and UTF texts. (#10, 11) Thanks `@pombredanne`_.
+* Set up Appveyor for continuous testing on Windows. Thanks `@pydanny`_.
+* Update link to Perl source implementation. (#9) Thanks `@asmeurer`_ `@pombredanne`_ `@audreyr`_.
+* Handle UnicodeDecodeError in check. (#12) Thanks `@DRMacIver`_.
+* Add very simple Hypothesis based tests. (#13) Thanks `@DRMacIver`_.
+* Use setup to determine requirements and remove redundant requirements.txt. (#14) Thanks `@hackebrot`_.
+* Add documentation status badge to README.rst. (#15) Thanks `@hackebrot`_.
+* Run tox in travis.yml. Add pypy and Python 3.4 to tox environments. (#16) Thanks `@hackebrot`_ `@pydanny`_.
+* Handle LookupError when detecting encoding. (#17) Thanks `@DRMacIver`_.
+
+
+.. _`@pombredanne`: https://github.com/pombredanne
+.. _`@pydanny`: https://github.com/pydanny
+.. _`@asmeurer`: https://github.com/asmeurer
+.. _`@audreyr`: https://github.com/audreyr
+.. _`@DRMacIver`: https://github.com/DRMacIver
+.. _`@hackebrot`: https://github.com/hackebrot
+
+0.3.0 (2014-05-05)
+~~~~~~~~~~~~~~~~~~
+
+* Include tests, docs in source package. (#6) Thanks `@vincentbernat`_.
+* Drop unnecessary shebangs and executable bits. (#8) Thanks `@scop`_.
+* Generate string of printable extended ASCII bytes only once. (#7) Thanks `@scop`_.
+* Make number of bytes to read parametrizable. (#7) Thanks `@scop`_.
+
+.. _`@vincentbernat`: https://github.com/vincentbernat
+.. _`@scop`: https://github.com/scop
+
+0.2.0 (2013-09-22)
+~~~~~~~~~~~~~~~~~~
+
+* Complete rewrite of everything. Thanks `@ncoghlan`_.
+
+.. _`@ncoghlan`: https://github.com/ncoghlan
+
+0.1.1 (2013-08-17)
+~~~~~~~~~~~~~~~~~~
+
+* Tests pass under Python 2.6, 2.7, 3.3, PyPy.
+
+
+0.1.0 (2013-08-17)
+~~~~~~~~~~~~~~~~~~
+
+* First release on PyPI.
+
+
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/RECORD b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/RECORD
new file mode 100644
index 00000000..6a44e224
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/RECORD
@@ -0,0 +1,13 @@
+binaryornot-0.4.4.dist-info/DESCRIPTION.rst,sha256=QGOp8ciWl3QJXmtUSCWTYNLFy4exWZ4IIieSuJ1YWmQ,5120
+binaryornot-0.4.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+binaryornot-0.4.4.dist-info/METADATA,sha256=ZbKKAHfl5XQchYqQmoQ6sE7ya3RfAyNBECqYmmtany8,5995
+binaryornot-0.4.4.dist-info/RECORD,,
+binaryornot-0.4.4.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110
+binaryornot-0.4.4.dist-info/metadata.json,sha256=MDiTh918QrO8YioOU2Rjh-6NO2xehibwl5nSc0NJWWg,1022
+binaryornot-0.4.4.dist-info/top_level.txt,sha256=xSk7ScGP__GIh_D2caJfJk0oRzgpyyqjWiozi5_nvms,12
+binaryornot/__init__.py,sha256=XfSXEYNIhIlBmsiUBzn8nDNSUA-2P5iseHo6sD1ZlyE,80
+binaryornot/__pycache__/__init__.cpython-312.pyc,,
+binaryornot/__pycache__/check.cpython-312.pyc,,
+binaryornot/__pycache__/helpers.cpython-312.pyc,,
+binaryornot/check.py,sha256=Doh9gd_DUYWdGpJ8CCMmu4A-bul3_kV3qnl4OsgDp10,756
+binaryornot/helpers.py,sha256=p6aDimVStPQKZeQNHKkQNneeD8jfT4qpm9hCiV_8jYU,4737
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/WHEEL b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/WHEEL
new file mode 100644
index 00000000..8b6dd1b5
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/WHEEL
@@ -0,0 +1,6 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.29.0)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/metadata.json b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/metadata.json
new file mode 100644
index 00000000..ac09fa39
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/metadata.json
@@ -0,0 +1 @@
+{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6"], "extensions": {"python.details": {"contacts": [{"email": "aroy@alum.mit.edu", "name": "Audrey Roy Greenfeld", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/audreyr/binaryornot"}}}, "extras": [], "generator": "bdist_wheel (0.29.0)", "keywords": ["binaryornot"], "license": "BSD", "metadata_version": "2.0", "name": "binaryornot", "run_requires": [{"requires": ["chardet (>=3.0.2)"]}], "summary": "Ultra-lightweight pure Python package to check if a file is binary or text.", "version": "0.4.4"}
\ No newline at end of file
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/top_level.txt b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/top_level.txt
new file mode 100644
index 00000000..62c9ba1d
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot-0.4.4.dist-info/top_level.txt
@@ -0,0 +1 @@
+binaryornot
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot/__init__.py b/strudel_ex/virt/Lib/site-packages/binaryornot/__init__.py
new file mode 100644
index 00000000..518255b1
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot/__init__.py
@@ -0,0 +1,3 @@
+__author__ = 'Audrey Roy'
+__email__ = 'audreyr@gmail.com'
+__version__ = '0.4.4'
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot/check.py b/strudel_ex/virt/Lib/site-packages/binaryornot/check.py
new file mode 100644
index 00000000..a784e3a7
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot/check.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+
+"""
+binaryornot.check
+-----------------
+
+Main code for checking if a file is binary or text.
+"""
+
+import logging
+
+from .helpers import get_starting_chunk, is_binary_string
+
+
+logger = logging.getLogger(__name__)
+
+
+def is_binary(filename):
+ """
+ :param filename: File to check.
+ :returns: True if it's a binary file, otherwise False.
+ """
+ logger.debug('is_binary: %(filename)r', locals())
+
+ # Check if the file extension is in a list of known binary types
+ binary_extensions = ['.pyc', ]
+ for ext in binary_extensions:
+ if filename.endswith(ext):
+ return True
+
+ # Check if the starting chunk is a binary string
+ chunk = get_starting_chunk(filename)
+ return is_binary_string(chunk)
diff --git a/strudel_ex/virt/Lib/site-packages/binaryornot/helpers.py b/strudel_ex/virt/Lib/site-packages/binaryornot/helpers.py
new file mode 100644
index 00000000..3f034a69
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/binaryornot/helpers.py
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+
+
+"""
+binaryornot.helpers
+-------------------
+
+Helper utilities used by BinaryOrNot.
+"""
+
+import chardet
+import logging
+
+
+logger = logging.getLogger(__name__)
+
+
+def print_as_hex(s):
+ """
+ Print a string as hex bytes.
+ """
+ print(":".join("{0:x}".format(ord(c)) for c in s))
+
+
+def get_starting_chunk(filename, length=1024):
+ """
+ :param filename: File to open and get the first little chunk of.
+ :param length: Number of bytes to read, default 1024.
+ :returns: Starting chunk of bytes.
+ """
+ # Ensure we open the file in binary mode
+ try:
+ with open(filename, 'rb') as f:
+ chunk = f.read(length)
+ return chunk
+ except IOError as e:
+ print(e)
+
+
+_control_chars = b'\n\r\t\f\b'
+if bytes is str:
+ # Python 2 means we need to invoke chr() explicitly
+ _printable_ascii = _control_chars + b''.join(map(chr, range(32, 127)))
+ _printable_high_ascii = b''.join(map(chr, range(127, 256)))
+else:
+ # Python 3 means bytes accepts integer input directly
+ _printable_ascii = _control_chars + bytes(range(32, 127))
+ _printable_high_ascii = bytes(range(127, 256))
+
+
+def is_binary_string(bytes_to_check):
+ """
+ Uses a simplified version of the Perl detection algorithm,
+ based roughly on Eli Bendersky's translation to Python:
+ http://eli.thegreenplace.net/2011/10/19/perls-guess-if-file-is-text-or-binary-implemented-in-python/
+
+ This is biased slightly more in favour of deeming files as text
+ files than the Perl algorithm, since all ASCII compatible character
+ sets are accepted as text, not just utf-8.
+
+ :param bytes: A chunk of bytes to check.
+ :returns: True if appears to be a binary, otherwise False.
+ """
+
+ # Empty files are considered text files
+ if not bytes_to_check:
+ return False
+
+ # Now check for a high percentage of ASCII control characters
+ # Binary if control chars are > 30% of the string
+ low_chars = bytes_to_check.translate(None, _printable_ascii)
+ nontext_ratio1 = float(len(low_chars)) / float(len(bytes_to_check))
+ logger.debug('nontext_ratio1: %(nontext_ratio1)r', locals())
+
+ # and check for a low percentage of high ASCII characters:
+ # Binary if high ASCII chars are < 5% of the string
+ # From: https://en.wikipedia.org/wiki/UTF-8
+ # If the bytes are random, the chances of a byte with the high bit set
+ # starting a valid UTF-8 character is only 6.64%. The chances of finding 7
+ # of these without finding an invalid sequence is actually lower than the
+ # chance of the first three bytes randomly being the UTF-8 BOM.
+
+ high_chars = bytes_to_check.translate(None, _printable_high_ascii)
+ nontext_ratio2 = float(len(high_chars)) / float(len(bytes_to_check))
+ logger.debug('nontext_ratio2: %(nontext_ratio2)r', locals())
+
+ is_likely_binary = (
+ (nontext_ratio1 > 0.3 and nontext_ratio2 < 0.05) or
+ (nontext_ratio1 > 0.8 and nontext_ratio2 > 0.8)
+ )
+ logger.debug('is_likely_binary: %(is_likely_binary)r', locals())
+
+ # then check for binary for possible encoding detection with chardet
+ detected_encoding = chardet.detect(bytes_to_check)
+ logger.debug('detected_encoding: %(detected_encoding)r', locals())
+
+ # finally use all the check to decide binary or text
+ decodable_as_unicode = False
+ if (detected_encoding['confidence'] > 0.9 and
+ detected_encoding['encoding'] != 'ascii'):
+ try:
+ try:
+ bytes_to_check.decode(encoding=detected_encoding['encoding'])
+ except TypeError:
+ # happens only on Python 2.6
+ unicode(bytes_to_check, encoding=detected_encoding['encoding']) # noqa
+ decodable_as_unicode = True
+ logger.debug('success: decodable_as_unicode: '
+ '%(decodable_as_unicode)r', locals())
+ except LookupError:
+ logger.debug('failure: could not look up encoding %(encoding)s',
+ detected_encoding)
+ except UnicodeDecodeError:
+ logger.debug('failure: decodable_as_unicode: '
+ '%(decodable_as_unicode)r', locals())
+
+ logger.debug('failure: decodable_as_unicode: '
+ '%(decodable_as_unicode)r', locals())
+ if is_likely_binary:
+ if decodable_as_unicode:
+ return False
+ else:
+ return True
+ else:
+ if decodable_as_unicode:
+ return False
+ else:
+ if b'\x00' in bytes_to_check or b'\xff' in bytes_to_check:
+ # Check for NULL bytes last
+ logger.debug('has nulls:' + repr(b'\x00' in bytes_to_check))
+ return True
+ return False
diff --git a/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/INSTALLER b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/LICENSE b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/LICENSE
new file mode 100644
index 00000000..62b076cd
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/LICENSE
@@ -0,0 +1,20 @@
+This package contains a modified version of ca-bundle.crt:
+
+ca-bundle.crt -- Bundle of CA Root Certificates
+
+This is a bundle of X.509 certificates of public Certificate Authorities
+(CA). These were automatically extracted from Mozilla's root certificates
+file (certdata.txt). This file can be found in the mozilla source tree:
+https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt
+It contains the certificates in PEM format and therefore
+can be directly used with curl / libcurl / php_curl, or with
+an Apache+mod_ssl webserver for SSL client authentication.
+Just configure this file as the SSLCACertificateFile.#
+
+***** BEGIN LICENSE BLOCK *****
+This Source Code Form is subject to the terms of the Mozilla Public License,
+v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
+one at http://mozilla.org/MPL/2.0/.
+
+***** END LICENSE BLOCK *****
+@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
diff --git a/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/METADATA b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/METADATA
new file mode 100644
index 00000000..b545f952
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/METADATA
@@ -0,0 +1,67 @@
+Metadata-Version: 2.1
+Name: certifi
+Version: 2024.6.2
+Summary: Python package for providing Mozilla's CA Bundle.
+Home-page: https://github.com/certifi/python-certifi
+Author: Kenneth Reitz
+Author-email: me@kennethreitz.com
+License: MPL-2.0
+Project-URL: Source, https://github.com/certifi/python-certifi
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
+Classifier: Natural Language :: English
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Requires-Python: >=3.6
+License-File: LICENSE
+
+Certifi: Python SSL Certificates
+================================
+
+Certifi provides Mozilla's carefully curated collection of Root Certificates for
+validating the trustworthiness of SSL certificates while verifying the identity
+of TLS hosts. It has been extracted from the `Requests`_ project.
+
+Installation
+------------
+
+``certifi`` is available on PyPI. Simply install it with ``pip``::
+
+ $ pip install certifi
+
+Usage
+-----
+
+To reference the installed certificate authority (CA) bundle, you can use the
+built-in function::
+
+ >>> import certifi
+
+ >>> certifi.where()
+ '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem'
+
+Or from the command line::
+
+ $ python -m certifi
+ /usr/local/lib/python3.7/site-packages/certifi/cacert.pem
+
+Enjoy!
+
+.. _`Requests`: https://requests.readthedocs.io/en/master/
+
+Addition/Removal of Certificates
+--------------------------------
+
+Certifi does not support any addition/removal or other modification of the
+CA trust store content. This project is intended to provide a reliable and
+highly portable root of trust to python deployments. Look to upstream projects
+for methods to use alternate trust.
diff --git a/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/RECORD b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/RECORD
new file mode 100644
index 00000000..c5339436
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/RECORD
@@ -0,0 +1,14 @@
+certifi-2024.6.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+certifi-2024.6.2.dist-info/LICENSE,sha256=6TcW2mucDVpKHfYP5pWzcPBpVgPSH2-D8FPkLPwQyvc,989
+certifi-2024.6.2.dist-info/METADATA,sha256=0JvKStGd0rn8QzECH3rN6wcw-6ZmNtR68uciKdXeVmU,2221
+certifi-2024.6.2.dist-info/RECORD,,
+certifi-2024.6.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
+certifi-2024.6.2.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8
+certifi/__init__.py,sha256=OemlOQZNxjR0BTLg7e4GIST-_QTOZsTKNgXw4v_0DwI,94
+certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243
+certifi/__pycache__/__init__.cpython-312.pyc,,
+certifi/__pycache__/__main__.cpython-312.pyc,,
+certifi/__pycache__/core.cpython-312.pyc,,
+certifi/cacert.pem,sha256=FgXQ05xeJdZ-eDjaahfc8ujGz6eQMOj7AxjjX1SVSTw,293951
+certifi/core.py,sha256=qRDDFyXVJwTB_EmoGppaXU_R9qCZvhl-EzxPMuV3nTA,4426
+certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
diff --git a/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/WHEEL b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/WHEEL
new file mode 100644
index 00000000..bab98d67
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/WHEEL
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.43.0)
+Root-Is-Purelib: true
+Tag: py3-none-any
+
diff --git a/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/top_level.txt b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/top_level.txt
new file mode 100644
index 00000000..963eac53
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi-2024.6.2.dist-info/top_level.txt
@@ -0,0 +1 @@
+certifi
diff --git a/strudel_ex/virt/Lib/site-packages/certifi/__init__.py b/strudel_ex/virt/Lib/site-packages/certifi/__init__.py
new file mode 100644
index 00000000..62b27b63
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi/__init__.py
@@ -0,0 +1,4 @@
+from .core import contents, where
+
+__all__ = ["contents", "where"]
+__version__ = "2024.06.02"
diff --git a/strudel_ex/virt/Lib/site-packages/certifi/__main__.py b/strudel_ex/virt/Lib/site-packages/certifi/__main__.py
new file mode 100644
index 00000000..8945b5da
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi/__main__.py
@@ -0,0 +1,12 @@
+import argparse
+
+from certifi import contents, where
+
+parser = argparse.ArgumentParser()
+parser.add_argument("-c", "--contents", action="store_true")
+args = parser.parse_args()
+
+if args.contents:
+ print(contents())
+else:
+ print(where())
diff --git a/strudel_ex/virt/Lib/site-packages/certifi/cacert.pem b/strudel_ex/virt/Lib/site-packages/certifi/cacert.pem
new file mode 100644
index 00000000..6e1f1a67
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi/cacert.pem
@@ -0,0 +1,4838 @@
+
+# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
+# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
+# Label: "GlobalSign Root CA"
+# Serial: 4835703278459707669005204
+# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a
+# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c
+# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
+# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
+# Label: "Entrust.net Premium 2048 Secure Server CA"
+# Serial: 946069240
+# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90
+# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31
+# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
+MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
+j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
+U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
+u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
+bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
+fF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
+# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
+# Label: "Baltimore CyberTrust Root"
+# Serial: 33554617
+# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4
+# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74
+# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
+# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
+# Label: "Entrust Root Certification Authority"
+# Serial: 1164660820
+# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
+# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
+# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+
+# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
+# Subject: CN=AAA Certificate Services O=Comodo CA Limited
+# Label: "Comodo AAA Services root"
+# Serial: 1
+# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
+# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
+# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 2"
+# Serial: 1289
+# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b
+# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7
+# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
+GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
+Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
+WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
+rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
+ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
+Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
+PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
+/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
+oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
+yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
+EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
+A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
+MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
+BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
+g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
+fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
+WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
+B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
+hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
+TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
+mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
+ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
+4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
+8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 3"
+# Serial: 1478
+# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf
+# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85
+# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35
+-----BEGIN CERTIFICATE-----
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
+4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
+H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
+8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
+vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
+mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
+btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
+T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
+WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
+c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
+4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
+VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
+CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
+aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
+czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
+A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
+Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
+7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
+d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
+4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
+t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
+DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
+k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
+zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
+Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
+mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
+4SVhM7JZG+Ju1zdXtg2pEto=
+-----END CERTIFICATE-----
+
+# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
+# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
+# Label: "XRamp Global CA Root"
+# Serial: 107108908803651509692980124233745014957
+# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1
+# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6
+# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
+gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
+MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
+UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
+NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
+dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
+dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
+38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
+KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
+DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
+qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
+JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
+PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
+BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
+jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
+eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
+vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
+IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
+i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
+O+7ETPTsJ3xCwnR8gooJybQDJbw=
+-----END CERTIFICATE-----
+
+# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
+# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
+# Label: "Go Daddy Class 2 CA"
+# Serial: 0
+# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
+# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
+# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
+MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
+YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
+MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
+ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
+MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
+ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
+PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
+wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
+EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
+avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
+sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
+/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
+IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
+OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
+TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
+dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
+ReYNnyicsbkqWletNw+vHX/bvZ8=
+-----END CERTIFICATE-----
+
+# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
+# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
+# Label: "Starfield Class 2 CA"
+# Serial: 0
+# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
+# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
+# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
+MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
+U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
+NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
+ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
+DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
+8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
+X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
+K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
+1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
+A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
+zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
+YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
+bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
+L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
+eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
+VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
+WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Assured ID Root CA"
+# Serial: 17154717934120587862167794914071425081
+# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72
+# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43
+# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root CA"
+# Serial: 10944719598952040374951832963794454346
+# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e
+# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36
+# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert High Assurance EV Root CA"
+# Serial: 3553400076410547919724730734378100087
+# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a
+# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25
+# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+
+# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
+# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
+# Label: "SwissSign Gold CA - G2"
+# Serial: 13492815561806991280
+# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93
+# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61
+# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
+biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
+76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
+bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
+6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
+emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
+MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
+MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
+MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
+FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
+aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
+gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
+qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
+lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
+8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
+45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
+UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
+O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
+bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
+GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
+77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
+hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
+92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
+Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
+ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
+Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+
+# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG
+# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG
+# Label: "SwissSign Silver CA - G2"
+# Serial: 5700383053117599563
+# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13
+# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb
+# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5
+-----BEGIN CERTIFICATE-----
+MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
+IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
+RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
+U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
+Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
+YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
+nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
+6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
+eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
+c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
+MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
+HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
+jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
+5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
+rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
+wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
+cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
+AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
+WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
+xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
+2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
+IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
+aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
+em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
+dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
+OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
+tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
+-----END CERTIFICATE-----
+
+# Issuer: CN=SecureTrust CA O=SecureTrust Corporation
+# Subject: CN=SecureTrust CA O=SecureTrust Corporation
+# Label: "SecureTrust CA"
+# Serial: 17199774589125277788362757014266862032
+# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1
+# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11
+# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Secure Global CA O=SecureTrust Corporation
+# Subject: CN=Secure Global CA O=SecureTrust Corporation
+# Label: "Secure Global CA"
+# Serial: 9751836167731051554232119481456978597
+# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de
+# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b
+# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
+
+# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
+# Subject: CN=COMODO Certification Authority O=COMODO CA Limited
+# Label: "COMODO Certification Authority"
+# Serial: 104350513648249232941998508985834464573
+# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
+# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
+# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
+MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
+/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
+PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
+QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
+SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
+IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
+zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
+BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
+ZQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
+# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
+# Label: "COMODO ECC Certification Authority"
+# Serial: 41578283867086692638256921589707938090
+# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23
+# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11
+# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certigna O=Dhimyotis
+# Subject: CN=Certigna O=Dhimyotis
+# Label: "Certigna"
+# Serial: 18364802974209362175
+# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff
+# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97
+# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
+DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
+BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
+QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
+gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
+zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
+130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
+JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
+ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
+AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
+9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
+bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
+fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
+HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
+t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+
+# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
+# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
+# Label: "ePKI Root Certification Authority"
+# Serial: 28956088682735189655030529057352760477
+# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3
+# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0
+# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
+IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
+SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
+SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
+ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
+DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
+TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
+fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
+sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
+WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
+nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
+dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
+NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
+AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
+MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
+uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
+PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
+JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
+gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
+j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
+5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
+o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
+/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
+Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
+W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
+hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+
+# Issuer: O=certSIGN OU=certSIGN ROOT CA
+# Subject: O=certSIGN OU=certSIGN ROOT CA
+# Label: "certSIGN ROOT CA"
+# Serial: 35210227249154
+# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17
+# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b
+# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
+QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
+MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
+0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
+UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
+RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
+OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
+JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
+AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
+BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
+LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
+MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
+44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
+Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
+i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
+9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+
+# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services)
+# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services)
+# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny"
+# Serial: 80544274841616
+# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88
+# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91
+# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
+EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
+MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
+dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
+pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
+b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
+IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
+lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
+AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
+VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
+ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
+BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
+U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
+bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
+uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
+XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+
+# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
+# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
+# Label: "SecureSign RootCA11"
+# Serial: 1
+# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26
+# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3
+# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr
+MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG
+A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0
+MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp
+Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD
+QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz
+i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8
+h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV
+MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9
+UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni
+8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC
+h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
+AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm
+KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ
+X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr
+QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5
+pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
+QSdJQO7e5iNEOdyhIta6A/I=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
+# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
+# Label: "Microsec e-Szigno Root CA 2009"
+# Serial: 14014712776195784473
+# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1
+# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e
+# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
+CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
+OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
+FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
+Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
+kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
+cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
+fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
+N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
+xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
+Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
+SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
+mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
+ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
+2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
+HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
+# Label: "GlobalSign Root CA - R3"
+# Serial: 4835703278459759426209954
+# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28
+# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad
+# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
+
+# Issuer: CN=Izenpe.com O=IZENPE S.A.
+# Subject: CN=Izenpe.com O=IZENPE S.A.
+# Label: "Izenpe.com"
+# Serial: 917563065490389241595536686991402621
+# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73
+# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19
+# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
+# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
+# Label: "Go Daddy Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
+# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
+# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
+
+# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Label: "Starfield Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
+# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
+# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
+MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
+Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
+nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
+HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
+Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
+dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
+HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
+CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
+sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
+4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
+8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
+mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
+
+# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Label: "Starfield Services Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2
+# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f
+# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5
+-----BEGIN CERTIFICATE-----
+MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
+ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
+MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
+VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
+ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
+dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
+OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
+8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
+Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
+hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
+6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
+AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
+bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
+ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
+qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
+iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
+0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
+sSi6
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Commercial O=AffirmTrust
+# Subject: CN=AffirmTrust Commercial O=AffirmTrust
+# Label: "AffirmTrust Commercial"
+# Serial: 8608355977964138876
+# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
+# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
+# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
+Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
+ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
+MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
+yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
+VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
+nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
+XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
+vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
+Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
+N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
+nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Networking O=AffirmTrust
+# Subject: CN=AffirmTrust Networking O=AffirmTrust
+# Label: "AffirmTrust Networking"
+# Serial: 8957382827206547757
+# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
+# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
+# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
+YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
+kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
+QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
+6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
+yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
+QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
+tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
+QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
+Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
+olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
+x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Premium O=AffirmTrust
+# Subject: CN=AffirmTrust Premium O=AffirmTrust
+# Label: "AffirmTrust Premium"
+# Serial: 7893706540734352110
+# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
+# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
+# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
+dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
+A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
+cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
+qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
+JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
+s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
+HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
+70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
+V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
+qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
+5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
+C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
+OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
+FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
+KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
+Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
+8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
+MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
+0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
+u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
+u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
+YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
+GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
+RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
+KeC2uAloGRwYQw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
+# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
+# Label: "AffirmTrust Premium ECC"
+# Serial: 8401224907861490260
+# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
+# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
+# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
+-----BEGIN CERTIFICATE-----
+MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
+cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
+BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
+VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
+0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
+ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
+A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
+aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
+flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Label: "Certum Trusted Network CA"
+# Serial: 279744
+# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
+# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
+# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+
+# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
+# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
+# Label: "TWCA Root Certification Authority"
+# Serial: 1
+# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79
+# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48
+# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44
+-----BEGIN CERTIFICATE-----
+MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
+MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
+V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
+WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
+LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
+AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
+K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
+RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
+rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
+3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
+hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
+MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
+XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
+lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
+aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
+YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
+-----END CERTIFICATE-----
+
+# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
+# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
+# Label: "Security Communication RootCA2"
+# Serial: 0
+# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43
+# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74
+# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
+DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
+dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
+YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
+OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
+zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
+VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
+hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
+ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
+awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
+OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
+coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
+okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
+t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
+1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
+SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
+-----END CERTIFICATE-----
+
+# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
+# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
+# Label: "Actalis Authentication Root CA"
+# Serial: 6271844772424770508
+# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6
+# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac
+# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66
+-----BEGIN CERTIFICATE-----
+MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
+BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
+MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
+IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
+SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
+ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
+UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
+4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
+KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
+gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
+rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
+51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
+be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
+KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
+v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
+fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
+jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
+ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
+ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
+e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
+jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
+WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
+SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
+pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
+X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
+fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
+K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
+ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
+LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
+LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
+# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
+# Label: "Buypass Class 2 Root CA"
+# Serial: 2
+# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29
+# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99
+# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
+6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
+L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
+1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
+MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
+QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
+arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
+Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
+FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
+P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
+9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
+uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
+9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
+OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
+KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
+DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
+H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
+I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
+5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
+3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
+Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
+# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
+# Label: "Buypass Class 3 Root CA"
+# Serial: 2
+# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec
+# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57
+# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
+ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
+N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
+tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
+0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
+/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
+KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
+zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
+O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
+34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
+K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
+Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
+QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
+IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
+HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
+O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
+033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
+dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
+kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
+3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
+u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
+4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
+-----END CERTIFICATE-----
+
+# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Label: "T-TeleSec GlobalRoot Class 3"
+# Serial: 1
+# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef
+# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1
+# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
+# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
+# Label: "D-TRUST Root Class 3 CA 2 2009"
+# Serial: 623603
+# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f
+# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0
+# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+
+# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
+# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
+# Label: "D-TRUST Root Class 3 CA 2 EV 2009"
+# Serial: 623604
+# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6
+# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83
+# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
+NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
+BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
+ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
+3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
+qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
+p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
+HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
+ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
+HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
+Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
+c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
+RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
+dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
+3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
+CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
+xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
+KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+
+# Issuer: CN=CA Disig Root R2 O=Disig a.s.
+# Subject: CN=CA Disig Root R2 O=Disig a.s.
+# Label: "CA Disig Root R2"
+# Serial: 10572350602393338211
+# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03
+# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71
+# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
+MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
+NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
+PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
+x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
+QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
+yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
+QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
+H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
+QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
+i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
+nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
+rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
+hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
+GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
+lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
+TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
+nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
+gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
+G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
+zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
+L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+
+# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
+# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
+# Label: "ACCVRAIZ1"
+# Serial: 6828503384748696800
+# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02
+# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17
+# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13
+-----BEGIN CERTIFICATE-----
+MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
+AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
+CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
+BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
+VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
+qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
+HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
+G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
+lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
+IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
+0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
+k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
+4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
+m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
+cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
+uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
+KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
+ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
+AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
+VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
+VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
+CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
+cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
+QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
+7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
+cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
+QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
+czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
+aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
+aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
+DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
+BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
+D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
+JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
+AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
+vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
+tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
+7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
+I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
+h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
+d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
+pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
+-----END CERTIFICATE-----
+
+# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
+# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
+# Label: "TWCA Global Root CA"
+# Serial: 3262
+# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96
+# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65
+# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
+EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
+VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
+NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
+B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
+10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
+0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
+MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
+zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
+46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
+yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
+laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
+oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
+BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
+qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
+4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
+1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
+H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
+RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
+15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
+6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
+nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
+wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
+aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
+KwbQBM0=
+-----END CERTIFICATE-----
+
+# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera
+# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera
+# Label: "TeliaSonera Root CA v1"
+# Serial: 199041966741090107964904287217786801558
+# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c
+# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37
+# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
+NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
+b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
+VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
+VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
+7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
+Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
+/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
+81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
+dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
+Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
+sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
+pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
+slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
+arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
+9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
+dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
+TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
+Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
+Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
+OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
+vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
+t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
+HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
+SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+
+# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Label: "T-TeleSec GlobalRoot Class 2"
+# Serial: 1
+# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a
+# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9
+# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Atos TrustedRoot 2011 O=Atos
+# Subject: CN=Atos TrustedRoot 2011 O=Atos
+# Label: "Atos TrustedRoot 2011"
+# Serial: 6643877497813316402
+# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56
+# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21
+# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
+AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
+EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
+FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
+REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
+Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
+VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
+SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
+4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
+cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
+eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
+A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
+DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
+vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
+DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
+maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
+lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
+KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 1 G3"
+# Serial: 687049649626669250736271037606554624078720034195
+# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab
+# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67
+# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
+MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
+wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
+rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
+68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
+4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
+UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
+abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
+3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
+KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
+hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
+Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
+zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
+ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
+cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
+qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
+YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
+b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
+8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
+NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
+ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
+q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
+nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 2 G3"
+# Serial: 390156079458959257446133169266079962026824725800
+# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06
+# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36
+# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 3 G3"
+# Serial: 268090761170461462463995952157327242137089239581
+# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7
+# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d
+# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Assured ID Root G2"
+# Serial: 15385348160840213938643033620894905419
+# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d
+# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f
+# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Assured ID Root G3"
+# Serial: 15459312981008553731928384953135426796
+# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb
+# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89
+# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root G2"
+# Serial: 4293743540046975378534879503202253541
+# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
+# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
+# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root G3"
+# Serial: 7089244469030293291760083333884364146
+# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
+# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
+# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Trusted Root G4"
+# Serial: 7451500558977370777930084869016614236
+# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49
+# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4
+# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+
+# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited
+# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited
+# Label: "COMODO RSA Certification Authority"
+# Serial: 101909084537582093308941363524873193117
+# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18
+# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4
+# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
+hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
+BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
+EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
+6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
+pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
+9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
+/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
+Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
+qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
+SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
+u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
+Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
+crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
+/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
+wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
+4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
+2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
+FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
+CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
+boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
+jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
+S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
+QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
+0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
+NVOFBkpdn627G190
+-----END CERTIFICATE-----
+
+# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
+# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
+# Label: "USERTrust RSA Certification Authority"
+# Serial: 2645093764781058787591871645665788717
+# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
+# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
+# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
+
+# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
+# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
+# Label: "USERTrust ECC Certification Authority"
+# Serial: 123013823720199481456569720443997572134
+# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1
+# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0
+# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
+eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
+JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
+VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
+I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
+o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
+A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
+zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
+RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
+# Label: "GlobalSign ECC Root CA - R5"
+# Serial: 32785792099990507226680698011560947931244
+# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08
+# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa
+# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+
+# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
+# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
+# Label: "IdenTrust Commercial Root CA 1"
+# Serial: 13298821034946342390520003877796839426
+# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7
+# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25
+# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
+VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
+MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
+JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
+3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
+S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
+bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
+T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
+vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
+Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
+dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
+c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
+l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
+iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
+ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
+LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
+nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
+W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
+AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
+l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
+4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
+mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
+7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+
+# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
+# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
+# Label: "IdenTrust Public Sector Root CA 1"
+# Serial: 13298821034946342390521976156843933698
+# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba
+# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd
+# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
+VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
+MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
+MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7
+ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy
+RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS
+bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF
+/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R
+3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw
+EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy
+9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V
+GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ
+2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV
+WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD
+W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN
+AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
+t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV
+DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9
+TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G
+lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW
+mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df
+WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ
+tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
+GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
+8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
+# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
+# Label: "Entrust Root Certification Authority - G2"
+# Serial: 1246989352
+# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2
+# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4
+# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
+cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
+IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
+dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
+NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
+dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
+dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
+aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
+RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
+cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
+wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
+U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
+jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
+BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
+jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
+1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
+nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
+VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
+# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
+# Label: "Entrust Root Certification Authority - EC1"
+# Serial: 51543124481930649114116133369
+# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc
+# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47
+# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
+d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
+dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
+RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
+MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
+VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
+L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
+Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
+A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
+ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
+Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
+R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
+hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+
+# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority
+# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority
+# Label: "CFCA EV ROOT"
+# Serial: 407555286
+# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30
+# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83
+# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD
+TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx
+MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j
+aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP
+T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03
+sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL
+TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5
+/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp
+7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz
+EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt
+hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP
+a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot
+aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg
+TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV
+PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv
+cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL
+tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd
+BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
+ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT
+ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL
+jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS
+ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy
+P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19
+xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d
+Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN
+5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe
+/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z
+AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ
+5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
+-----END CERTIFICATE-----
+
+# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
+# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
+# Label: "OISTE WISeKey Global Root GB CA"
+# Serial: 157768595616588414422159278966750757568
+# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d
+# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed
+# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
+MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
+Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
+YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x
+CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG
+b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
+bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3
+HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx
+WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX
+1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk
+u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P
+99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r
+M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB
+BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh
+cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5
+gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
+ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
+aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+
+# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
+# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
+# Label: "SZAFIR ROOT CA2"
+# Serial: 357043034767186914217277344587386743377558296292
+# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99
+# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de
+# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
+ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
+NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
+cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg
+Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN
+QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT
+3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw
+3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6
+3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5
+BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN
+XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF
+AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw
+8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG
+nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
+oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
+d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
+LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Label: "Certum Trusted Network CA 2"
+# Serial: 44979900017204383099463764357512596969
+# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2
+# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92
+# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04
+-----BEGIN CERTIFICATE-----
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
+gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
+QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
+A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz
+OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ
+VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3
+b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA
+DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn
+0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB
+OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE
+fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E
+Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m
+o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i
+sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW
+OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez
+Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS
+adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n
+3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ
+F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf
+CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29
+XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm
+djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/
+WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb
+AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq
+P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko
+b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
+XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
+5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
+DrW5viSP
+-----END CERTIFICATE-----
+
+# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Label: "Hellenic Academic and Research Institutions RootCA 2015"
+# Serial: 0
+# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce
+# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6
+# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36
+-----BEGIN CERTIFICATE-----
+MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix
+DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k
+IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT
+N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v
+dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG
+A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh
+ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx
+QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA
+4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0
+AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10
+4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C
+ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV
+9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD
+gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6
+Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq
+NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko
+LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
+Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd
+ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I
+XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI
+M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot
+9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V
+Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea
+j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh
+X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ
+l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf
+bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4
+pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK
+e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0
+vm9qp/UsQu0yrbYhnr68
+-----END CERTIFICATE-----
+
+# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015"
+# Serial: 0
+# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef
+# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66
+# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33
+-----BEGIN CERTIFICATE-----
+MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN
+BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl
+bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv
+b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ
+BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj
+YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5
+MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0
+dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg
+QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa
+jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC
+MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi
+C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep
+lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof
+TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
+-----END CERTIFICATE-----
+
+# Issuer: CN=ISRG Root X1 O=Internet Security Research Group
+# Subject: CN=ISRG Root X1 O=Internet Security Research Group
+# Label: "ISRG Root X1"
+# Serial: 172886928669790476064670243504169061120
+# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
+# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
+# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
+WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
+ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
+h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
+0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
+A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
+T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
+B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
+B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
+KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
+OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
+jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
+qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
+rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
+hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
+ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
+3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
+NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
+ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
+TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
+jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
+oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
+4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
+mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
+emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
+-----END CERTIFICATE-----
+
+# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM
+# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM
+# Label: "AC RAIZ FNMT-RCM"
+# Serial: 485876308206448804701554682760554759
+# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d
+# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20
+# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
+CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
+WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
+BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG
+Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/
+yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf
+BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz
+WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF
+tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z
+374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC
+IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL
+mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7
+wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS
+MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2
+ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet
+UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H
+YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3
+LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
+nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1
+RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM
+LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf
+77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N
+JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm
+fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
+6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp
+1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B
+9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
+RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
+uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 1 O=Amazon
+# Subject: CN=Amazon Root CA 1 O=Amazon
+# Label: "Amazon Root CA 1"
+# Serial: 143266978916655856878034712317230054538369994
+# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6
+# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16
+# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e
+-----BEGIN CERTIFICATE-----
+MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
+ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
+9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
+IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
+VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
+93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
+jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
+A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
+U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
+N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
+o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
+5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
+rqXRfboQnoZsG4q5WTP468SQvvG5
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 2 O=Amazon
+# Subject: CN=Amazon Root CA 2 O=Amazon
+# Label: "Amazon Root CA 2"
+# Serial: 143266982885963551818349160658925006970653239
+# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66
+# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a
+# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
+gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
+W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
+1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
+8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
+2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
+z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
+8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
+mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
+7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
+0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
+UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
+LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
+k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
+7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
+btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
+urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
+n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
+76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
+9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
+4PsJYGw=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 3 O=Amazon
+# Subject: CN=Amazon Root CA 3 O=Amazon
+# Label: "Amazon Root CA 3"
+# Serial: 143266986699090766294700635381230934788665930
+# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87
+# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e
+# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4
+-----BEGIN CERTIFICATE-----
+MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
+ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
+ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
+BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
+YyRIHN8wfdVoOw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 4 O=Amazon
+# Subject: CN=Amazon Root CA 4 O=Amazon
+# Label: "Amazon Root CA 4"
+# Serial: 143266989758080763974105200630763877849284878
+# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd
+# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be
+# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
+9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
+M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
+MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
+CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
+1KyLa2tJElMzrdfkviT8tQp21KW8EA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
+# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
+# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
+# Serial: 1
+# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49
+# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca
+# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16
+-----BEGIN CERTIFICATE-----
+MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
+GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
+bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
+KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0
+BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy
+dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG
+EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll
+IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU
+QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT
+TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg
+LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7
+a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr
+LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr
+N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X
+YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/
+iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f
+AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH
+V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
+AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf
+IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
+lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
+8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
+lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
+# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
+# Label: "GDCA TrustAUTH R5 ROOT"
+# Serial: 9009899650740120186
+# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4
+# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4
+# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93
+-----BEGIN CERTIFICATE-----
+MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
+BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ
+IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0
+MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV
+BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w
+HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj
+Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj
+TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u
+KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj
+qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm
+MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12
+ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP
+zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk
+L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC
+jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA
+HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC
+AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg
+p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm
+DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5
+COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry
+L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf
+JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg
+IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io
+2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV
+09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ
+XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq
+T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe
+MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
+# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
+# Label: "SSL.com Root Certification Authority RSA"
+# Serial: 8875640296558310041
+# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29
+# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb
+# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
+BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
+DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
+OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
+bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
+xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
+qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
+C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
+6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
+/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
+YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
+JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
+US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
+ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
+M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
+A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
+cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
+Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
+PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
+q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
+cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
+a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
+H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
+K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
+nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
+oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
+Ic2wBlX7Jz9TkHCpBB5XJ7k=
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
+# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
+# Label: "SSL.com Root Certification Authority ECC"
+# Serial: 8495723813297216424
+# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e
+# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a
+# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65
+-----BEGIN CERTIFICATE-----
+MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz
+WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0
+b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS
+b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI
+7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg
+CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud
+EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
+VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
+kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
+gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
+# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
+# Label: "SSL.com EV Root Certification Authority RSA R2"
+# Serial: 6248227494352943350
+# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95
+# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a
+# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
+BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
+CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
+MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
+A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD
+DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq
+M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf
+OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa
+4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9
+HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR
+aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA
+b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ
+Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV
+PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO
+pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu
+UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY
+MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
+HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4
+9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW
+s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5
+Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg
+cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM
+79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz
+/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt
+ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm
+Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK
+QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
+w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
+S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
+mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
+# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
+# Label: "SSL.com EV Root Certification Authority ECC"
+# Serial: 3182246526754555285
+# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90
+# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d
+# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8
+-----BEGIN CERTIFICATE-----
+MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
+NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
+bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
+VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
+WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
+5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
+ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
+h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6
+# Label: "GlobalSign Root CA - R6"
+# Serial: 1417766617973444989252670301619537
+# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae
+# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1
+# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
+MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
+MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
+MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
+xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
+ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
+aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
+LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
+1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
+k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
+SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
+bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
+WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
+rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
+MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
+bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
+nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
+Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
+55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
+vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
+cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
+oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
+nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
+pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
+JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
+8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
+5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
+-----END CERTIFICATE-----
+
+# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed
+# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed
+# Label: "OISTE WISeKey Global Root GC CA"
+# Serial: 44084345621038548146064804565436152554
+# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23
+# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31
+# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d
+-----BEGIN CERTIFICATE-----
+MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw
+CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91
+bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg
+Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ
+BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu
+ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS
+b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni
+eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W
+p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T
+rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
+57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
+Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
+-----END CERTIFICATE-----
+
+# Issuer: CN=UCA Global G2 Root O=UniTrust
+# Subject: CN=UCA Global G2 Root O=UniTrust
+# Label: "UCA Global G2 Root"
+# Serial: 124779693093741543919145257850076631279
+# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8
+# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a
+# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9
+MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH
+bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x
+CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds
+b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr
+b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9
+kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm
+VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R
+VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc
+C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj
+tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY
+D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv
+j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl
+NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6
+iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP
+O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV
+ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj
+L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5
+1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl
+1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU
+b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV
+PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj
+y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb
+EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg
+DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI
++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy
+YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX
+UB+K+wb1whnw0A==
+-----END CERTIFICATE-----
+
+# Issuer: CN=UCA Extended Validation Root O=UniTrust
+# Subject: CN=UCA Extended Validation Root O=UniTrust
+# Label: "UCA Extended Validation Root"
+# Serial: 106100277556486529736699587978573607008
+# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2
+# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a
+# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH
+MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF
+eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx
+MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV
+BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog
+D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS
+sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop
+O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk
+sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi
+c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj
+VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz
+KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/
+TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G
+sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs
+1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD
+fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T
+AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN
+l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR
+ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ
+VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5
+c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp
+4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s
+t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj
+2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO
+vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C
+xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx
+cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM
+fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
+# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
+# Label: "Certigna Root CA"
+# Serial: 269714418870597844693661054334862075617
+# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77
+# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43
+# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68
+-----BEGIN CERTIFICATE-----
+MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
+WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
+MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
+MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD
+VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX
+BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO
+ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M
+CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu
+I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm
+TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh
+C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf
+ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz
+IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT
+Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k
+JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5
+hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB
+GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
+1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov
+L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo
+dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr
+aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq
+hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L
+6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG
+HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6
+0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB
+lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi
+o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1
+gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v
+faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
+Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
+jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
+3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
+-----END CERTIFICATE-----
+
+# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI
+# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI
+# Label: "emSign Root CA - G1"
+# Serial: 235931866688319308814040
+# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac
+# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c
+# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
+VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
+ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
+MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO
+MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv
+Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz
+f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO
+8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq
+d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM
+tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt
+Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB
+o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x
+PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM
+wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d
+GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
+6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
+RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
+iN66zB+Afko=
+-----END CERTIFICATE-----
+
+# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI
+# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI
+# Label: "emSign ECC Root CA - G3"
+# Serial: 287880440101571086945156
+# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40
+# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1
+# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b
+-----BEGIN CERTIFICATE-----
+MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
+EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
+bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
+RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
+TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
+b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
+WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
+fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
+zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
+hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
+CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
++JbNR6iC8hZVdyR+EhCVBCyj
+-----END CERTIFICATE-----
+
+# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI
+# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI
+# Label: "emSign Root CA - C1"
+# Serial: 825510296613316004955058
+# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68
+# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01
+# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f
+-----BEGIN CERTIFICATE-----
+MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG
+A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg
+SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw
+MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln
+biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v
+dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ
+BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ
+HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH
+3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH
+GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c
+xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1
+aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq
+TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87
+/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4
+kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG
+YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT
++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo
+WXzhriKi4gp6D/piq1JM4fHfyr6DDUI=
+-----END CERTIFICATE-----
+
+# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI
+# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI
+# Label: "emSign ECC Root CA - C3"
+# Serial: 582948710642506000014504
+# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5
+# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66
+# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3
+-----BEGIN CERTIFICATE-----
+MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG
+EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx
+IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw
+MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln
+biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND
+IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci
+MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti
+sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O
+BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
+Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c
+3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J
+0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post
+# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post
+# Label: "Hongkong Post Root CA 3"
+# Serial: 46170865288971385588281144162979347873371282084
+# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0
+# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02
+# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6
+-----BEGIN CERTIFICATE-----
+MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL
+BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ
+SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n
+a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5
+NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT
+CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u
+Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO
+dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI
+VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV
+9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY
+2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY
+vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt
+bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb
+x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+
+l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK
+TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj
+Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e
+i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw
+DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG
+7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk
+MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr
+gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk
+GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS
+3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm
+Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+
+l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c
+JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP
+L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa
+LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG
+mpv0
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only
+# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only
+# Label: "Entrust Root Certification Authority - G4"
+# Serial: 289383649854506086828220374796556676440
+# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88
+# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01
+# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw
+gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL
+Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg
+MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw
+BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0
+MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1
+c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ
+bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg
+Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ
+2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E
+T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j
+5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM
+C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T
+DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX
+wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A
+2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm
+nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8
+dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl
+N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj
+c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS
+5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS
+Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr
+hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/
+B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI
+AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw
+H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+
+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk
+2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol
+IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk
+5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY
+n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation
+# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation
+# Label: "Microsoft ECC Root Certificate Authority 2017"
+# Serial: 136839042543790627607696632466672567020
+# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67
+# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5
+# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02
+-----BEGIN CERTIFICATE-----
+MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD
+VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
+MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV
+UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy
+b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR
+ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb
+hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3
+FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV
+L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB
+iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation
+# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation
+# Label: "Microsoft RSA Root Certificate Authority 2017"
+# Serial: 40975477897264996090493496164228220339
+# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47
+# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74
+# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0
+-----BEGIN CERTIFICATE-----
+MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl
+MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
+NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
+IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG
+EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N
+aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ
+Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0
+ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1
+HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm
+gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ
+jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc
+aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG
+YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6
+W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K
+UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH
++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q
+W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC
+LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC
+gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6
+tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh
+SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2
+TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3
+pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR
+xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp
+GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9
+dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN
+AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB
+RA+GsCyRxj3qrg+E
+-----END CERTIFICATE-----
+
+# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd.
+# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd.
+# Label: "e-Szigno Root CA 2017"
+# Serial: 411379200276854331539784714
+# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98
+# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1
+# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99
+-----BEGIN CERTIFICATE-----
+MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
+BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
+LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
+b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ
+BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg
+THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v
+IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv
+xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H
+Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
+eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
+jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
++efcMQ==
+-----END CERTIFICATE-----
+
+# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2
+# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2
+# Label: "certSIGN Root CA G2"
+# Serial: 313609486401300475190
+# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7
+# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32
+# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g
+Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ
+BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ
+R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF
+dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw
+vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ
+uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp
+n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs
+cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW
+xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P
+rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF
+DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx
+DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy
+LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C
+eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ
+d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq
+kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC
+b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl
+qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0
+OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c
+NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk
+ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO
+pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj
+03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk
+PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE
+1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX
+QRBdJ3NghVdJIgc=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.
+# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.
+# Label: "Trustwave Global Certification Authority"
+# Serial: 1846098327275375458322922162
+# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e
+# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5
+# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x
+ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1
+c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx
+OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI
+SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI
+b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn
+swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu
+7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8
+1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW
+80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP
+JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l
+RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw
+hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10
+coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc
+BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n
+twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud
+DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W
+0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe
+uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q
+lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB
+aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE
+sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT
+MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe
+qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh
+VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8
+h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9
+EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK
+yeC2nOnOcXHebD8WpHk=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.
+# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.
+# Label: "Trustwave Global ECC P256 Certification Authority"
+# Serial: 4151900041497450638097112925
+# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54
+# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf
+# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4
+-----BEGIN CERTIFICATE-----
+MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG
+SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN
+FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w
+DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw
+CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh
+DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
+-----END CERTIFICATE-----
+
+# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.
+# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.
+# Label: "Trustwave Global ECC P384 Certification Authority"
+# Serial: 2704997926503831671788816187
+# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6
+# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2
+# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97
+-----BEGIN CERTIFICATE-----
+MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ
+j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF
+1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G
+A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3
+AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC
+MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu
+Sw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.
+# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.
+# Label: "NAVER Global Root Certification Authority"
+# Serial: 9013692873798656336226253319739695165984492813
+# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b
+# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1
+# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65
+-----BEGIN CERTIFICATE-----
+MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM
+BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG
+T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx
+CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD
+b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA
+iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH
+38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE
+HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz
+kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP
+szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq
+vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf
+nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG
+YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo
+0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a
+CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K
+AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I
+36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
+Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN
+qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj
+cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm
++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL
+hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe
+lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7
+p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8
+piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR
+LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX
+5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
+dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
+9XXeifdy
+-----END CERTIFICATE-----
+
+# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres
+# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres
+# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS"
+# Serial: 131542671362353147877283741781055151509
+# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb
+# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a
+# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb
+-----BEGIN CERTIFICATE-----
+MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw
+CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw
+FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S
+Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5
+MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL
+DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS
+QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH
+sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK
+Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu
+SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC
+MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy
+v+c=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa
+# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa
+# Label: "GlobalSign Root R46"
+# Serial: 1552617688466950547958867513931858518042577
+# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef
+# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90
+# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA
+MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD
+VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy
+MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt
+c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ
+OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG
+vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud
+316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo
+0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE
+y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF
+zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE
++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN
+I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs
+x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa
+ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC
+4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4
+7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg
+JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti
+2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk
+pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF
+FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt
+rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk
+ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5
+u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP
+4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6
+N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
+vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa
+# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa
+# Label: "GlobalSign Root E46"
+# Serial: 1552617690338932563915843282459653771421763
+# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f
+# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84
+# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58
+-----BEGIN CERTIFICATE-----
+MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx
+CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD
+ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw
+MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
+HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq
+R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd
+yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
+7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8
++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH
+# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH
+# Label: "GLOBALTRUST 2020"
+# Serial: 109160994242082918454945253
+# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8
+# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2
+# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a
+-----BEGIN CERTIFICATE-----
+MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG
+A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw
+FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx
+MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u
+aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b
+RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z
+YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3
+QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw
+yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+
+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ
+SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH
+r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0
+4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me
+dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw
+q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2
+nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu
+H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
+VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC
+XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd
+6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf
++I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi
+kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7
+wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB
+TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C
+MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn
+4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I
+aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy
+qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz
+# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz
+# Label: "ANF Secure Server Root CA"
+# Serial: 996390341000653745
+# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96
+# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74
+# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99
+-----BEGIN CERTIFICATE-----
+MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV
+BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk
+YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV
+BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN
+MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF
+UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD
+VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v
+dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj
+cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q
+yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH
+2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX
+H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL
+zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR
+p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz
+W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/
+SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn
+LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3
+n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B
+u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj
+o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
+AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L
+9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej
+rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK
+pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0
+vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq
+OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ
+/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9
+2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI
++PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2
+MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo
+tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
+# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
+# Label: "Certum EC-384 CA"
+# Serial: 160250656287871593594747141429395092468
+# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1
+# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed
+# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6
+-----BEGIN CERTIFICATE-----
+MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw
+CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw
+JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT
+EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0
+WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT
+LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX
+BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE
+KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm
+Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8
+EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J
+UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn
+nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
+# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
+# Label: "Certum Trusted Root CA"
+# Serial: 40870380103424195783807378461123655149
+# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29
+# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5
+# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd
+-----BEGIN CERTIFICATE-----
+MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6
+MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu
+MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV
+BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw
+MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg
+U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ
+n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q
+p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq
+NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF
+8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3
+HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa
+mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi
+7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF
+ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P
+qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ
+v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6
+Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1
+vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD
+ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4
+WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo
+zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR
+5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ
+GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf
+5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq
+0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D
+P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM
+qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP
+0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf
+E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
+-----END CERTIFICATE-----
+
+# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique
+# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique
+# Label: "TunTrust Root CA"
+# Serial: 108534058042236574382096126452369648152337120275
+# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4
+# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb
+# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL
+BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg
+Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv
+b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG
+EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u
+IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ
+n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd
+2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF
+VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ
+GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF
+li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU
+r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2
+eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb
+MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg
+jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB
+7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW
+5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE
+ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0
+90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z
+xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu
+QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4
+FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH
+22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP
+xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn
+dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5
+Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b
+nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ
+CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH
+u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj
+d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
+-----END CERTIFICATE-----
+
+# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA
+# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA
+# Label: "HARICA TLS RSA Root CA 2021"
+# Serial: 76817823531813593706434026085292783742
+# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91
+# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d
+# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d
+-----BEGIN CERTIFICATE-----
+MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs
+MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg
+Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL
+MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
+YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv
+b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l
+mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE
+4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv
+a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M
+pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw
+Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b
+LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY
+AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB
+AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq
+E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr
+W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ
+CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE
+AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU
+X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3
+f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja
+H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP
+JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P
+zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt
+jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0
+/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT
+BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79
+aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW
+xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU
+63ZTGI0RmLo=
+-----END CERTIFICATE-----
+
+# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA
+# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA
+# Label: "HARICA TLS ECC Root CA 2021"
+# Serial: 137515985548005187474074462014555733966
+# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0
+# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48
+# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01
+-----BEGIN CERTIFICATE-----
+MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw
+CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
+cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v
+dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG
+A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
+aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg
+Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7
+KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y
+STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD
+AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw
+SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN
+nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
+-----END CERTIFICATE-----
+
+# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
+# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
+# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
+# Serial: 1977337328857672817
+# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3
+# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe
+# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
+MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc
+tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd
+IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j
+b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC
+AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw
+ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m
+iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF
+Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ
+hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P
+Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE
+EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV
+1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t
+CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
+5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw
+f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
+ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
+GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
+-----END CERTIFICATE-----
+
+# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd.
+# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd.
+# Label: "vTrus ECC Root CA"
+# Serial: 630369271402956006249506845124680065938238527194
+# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85
+# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1
+# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3
+-----BEGIN CERTIFICATE-----
+MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw
+RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY
+BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz
+MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u
+LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0
+v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd
+e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD
+VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw
+V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA
+AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG
+GJTO
+-----END CERTIFICATE-----
+
+# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd.
+# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd.
+# Label: "vTrus Root CA"
+# Serial: 387574501246983434957692974888460947164905180485
+# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc
+# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7
+# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87
+-----BEGIN CERTIFICATE-----
+MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL
+BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x
+FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx
+MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s
+THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc
+IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU
+AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+
+GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9
+8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH
+flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt
+J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim
+0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN
+pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ
+UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW
+OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB
+AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet
+8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd
+nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j
+bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM
+Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv
+TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS
+S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr
+I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9
+b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB
+UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P
+Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven
+sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s=
+-----END CERTIFICATE-----
+
+# Issuer: CN=ISRG Root X2 O=Internet Security Research Group
+# Subject: CN=ISRG Root X2 O=Internet Security Research Group
+# Label: "ISRG Root X2"
+# Serial: 87493402998870891108772069816698636114
+# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5
+# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af
+# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70
+-----BEGIN CERTIFICATE-----
+MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
+CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
+R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
+MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
+ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
+EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
+ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
+zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
+tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
+/q4AaOeMSQ+2b1tbFfLn
+-----END CERTIFICATE-----
+
+# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd.
+# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd.
+# Label: "HiPKI Root CA - G1"
+# Serial: 60966262342023497858655262305426234976
+# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3
+# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60
+# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc
+-----BEGIN CERTIFICATE-----
+MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa
+Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3
+YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw
+qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv
+Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6
+lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz
+Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ
+KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK
+FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj
+HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr
+y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ
+/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM
+a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6
+fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG
+SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi
+7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc
+SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza
+ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc
+XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg
+iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho
+L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF
+Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr
+kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+
+vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU
+YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
+# Label: "GlobalSign ECC Root CA - R4"
+# Serial: 159662223612894884239637590694
+# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc
+# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28
+# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
+VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
+MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g
+UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT
+BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx
+uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
+HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
+bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
+-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
+# Subject: CN=GTS Root R1 O=Google Trust Services LLC
+# Label: "GTS Root R1"
+# Serial: 159662320309726417404178440727
+# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40
+# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a
+# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
+27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
+Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
+TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
+qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
+szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
+Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
+MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
+wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
+aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
+VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
+C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
+QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
+h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
+7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
+ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
+MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
+Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
+6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
+0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
+2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
+bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
+-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R2 O=Google Trust Services LLC
+# Subject: CN=GTS Root R2 O=Google Trust Services LLC
+# Label: "GTS Root R2"
+# Serial: 159662449406622349769042896298
+# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc
+# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94
+# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt
+nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY
+6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu
+MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k
+RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg
+f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV
++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo
+dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW
+Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa
+G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq
+gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H
+vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8
+0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC
+B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u
+NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg
+yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev
+HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6
+xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR
+TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg
+JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV
+7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl
+6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL
+-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R3 O=Google Trust Services LLC
+# Subject: CN=GTS Root R3 O=Google Trust Services LLC
+# Label: "GTS Root R3"
+# Serial: 159662495401136852707857743206
+# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73
+# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46
+# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD
+VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
+A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
+WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
+IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G
+jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2
+4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7
+VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm
+ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X
+-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
+# Subject: CN=GTS Root R4 O=Google Trust Services LLC
+# Label: "GTS Root R4"
+# Serial: 159662532700760215368942768210
+# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8
+# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47
+# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
+VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
+A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
+WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
+IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
+QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
+HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
+9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
+p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
+-----END CERTIFICATE-----
+
+# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj
+# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj
+# Label: "Telia Root CA v2"
+# Serial: 7288924052977061235122729490515358
+# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48
+# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd
+# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx
+CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE
+AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1
+NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ
+MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq
+AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9
+vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9
+lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD
+n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT
+7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o
+6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC
+TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6
+WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R
+DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI
+pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj
+YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy
+rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
+AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ
+8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi
+0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM
+A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS
+SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K
+TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF
+6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er
+3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt
+Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT
+VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW
+ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA
+rBPuUBQemMc=
+-----END CERTIFICATE-----
+
+# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH
+# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH
+# Label: "D-TRUST BR Root CA 1 2020"
+# Serial: 165870826978392376648679885835942448534
+# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed
+# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67
+# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw
+CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
+VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5
+NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
+A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS
+zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0
+QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/
+VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
+PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf
+Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
+dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
+c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
+PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW
+wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV
+dWNbFJWcHwHP2NVypw87
+-----END CERTIFICATE-----
+
+# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH
+# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH
+# Label: "D-TRUST EV Root CA 1 2020"
+# Serial: 126288379621884218666039612629459926992
+# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e
+# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07
+# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw
+CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
+VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5
+NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
+A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC
+/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD
+wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3
+OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
+PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf
+Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
+dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
+c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
+PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA
+y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb
+gfM0agPnIjhQW+0ZT0MW
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc.
+# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc.
+# Label: "DigiCert TLS ECC P384 Root G5"
+# Serial: 13129116028163249804115411775095713523
+# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed
+# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee
+# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05
+-----BEGIN CERTIFICATE-----
+MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp
+Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2
+MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
+bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS
+7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp
+0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS
+B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49
+BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ
+LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4
+DXZDjC5Ty3zfDBeWUA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc.
+# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc.
+# Label: "DigiCert TLS RSA4096 Root G5"
+# Serial: 11930366277458970227240571539258396554
+# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1
+# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35
+# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN
+MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT
+HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
+NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
+IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+
+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0
+2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp
+wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM
+pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD
+nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po
+sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx
+Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd
+Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX
+KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe
+XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL
+tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv
+TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
+AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw
+GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H
+PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF
+O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ
+REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik
+AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv
+/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+
+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw
+MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF
+qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK
+ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certainly Root R1 O=Certainly
+# Subject: CN=Certainly Root R1 O=Certainly
+# Label: "Certainly Root R1"
+# Serial: 188833316161142517227353805653483829216
+# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12
+# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af
+# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw
+PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy
+dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0
+YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2
+1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT
+vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed
+aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0
+1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5
+r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5
+cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ
+wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ
+6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA
+2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH
+Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR
+eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB
+/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u
+d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr
+PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d
+8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi
+1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd
+rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di
+taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7
+lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj
+yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn
+Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy
+yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n
+wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6
+OV+KmalBWQewLK8=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certainly Root E1 O=Certainly
+# Subject: CN=Certainly Root E1 O=Certainly
+# Label: "Certainly Root E1"
+# Serial: 8168531406727139161245376702891150584
+# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9
+# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b
+# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2
+-----BEGIN CERTIFICATE-----
+MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw
+CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu
+bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ
+BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s
+eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK
++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2
+QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4
+hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm
+ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
+BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
+-----END CERTIFICATE-----
+
+# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD.
+# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD.
+# Label: "Security Communication RootCA3"
+# Serial: 16247922307909811815
+# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26
+# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a
+# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94
+-----BEGIN CERTIFICATE-----
+MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV
+BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw
+JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2
+MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
+U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg
+Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r
+CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA
+lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG
+TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7
+9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7
+8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4
+g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we
+GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst
++3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M
+0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ
+T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw
+HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS
+YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA
+FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd
+9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI
+UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+
+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke
+gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf
+iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV
+nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD
+2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//
+1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad
+TdJ0MN1kURXbg4NR16/9M51NZg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD.
+# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD.
+# Label: "Security Communication ECC RootCA1"
+# Serial: 15446673492073852651
+# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86
+# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41
+# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11
+-----BEGIN CERTIFICATE-----
+MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT
+AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD
+VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx
+NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT
+HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5
+IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl
+dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK
+ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu
+9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O
+be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k=
+-----END CERTIFICATE-----
+
+# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY
+# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY
+# Label: "BJCA Global Root CA1"
+# Serial: 113562791157148395269083148143378328608
+# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90
+# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a
+# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU
+MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI
+T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz
+MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF
+SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh
+bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z
+xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ
+spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5
+58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR
+at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll
+5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq
+nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK
+V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/
+pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO
+z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn
+jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+
+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF
+7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4
+YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli
+awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u
++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88
+X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN
+SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo
+P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI
++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz
+znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9
+eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2
+YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy
+r/6zcCwupvI=
+-----END CERTIFICATE-----
+
+# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY
+# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY
+# Label: "BJCA Global Root CA2"
+# Serial: 58605626836079930195615843123109055211
+# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c
+# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6
+# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82
+-----BEGIN CERTIFICATE-----
+MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw
+CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ
+VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy
+MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ
+TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS
+b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B
+IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+
++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK
+sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA
+94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B
+43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited
+# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited
+# Label: "Sectigo Public Server Authentication Root E46"
+# Serial: 88989738453351742415770396670917916916
+# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01
+# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a
+# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
+CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
+ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
+MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
+A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
+ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
+WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
+6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
+Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
+qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
+4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited
+# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited
+# Label: "Sectigo Public Server Authentication Root R46"
+# Serial: 156256931880233212765902055439220583700
+# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5
+# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38
+# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06
+-----BEGIN CERTIFICATE-----
+MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
+Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
+HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY
+MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp
+YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa
+ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz
+SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf
+iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X
+ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3
+IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS
+VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE
+SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu
++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt
+8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L
+HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt
+zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P
+AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c
+mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ
+YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52
+gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA
+Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB
+JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX
+DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui
+TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5
+dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
+LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
+0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
+QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation
+# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation
+# Label: "SSL.com TLS RSA Root CA 2022"
+# Serial: 148535279242832292258835760425842727825
+# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da
+# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca
+# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed
+-----BEGIN CERTIFICATE-----
+MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO
+MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD
+DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX
+DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw
+b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP
+L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY
+t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins
+S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3
+PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO
+L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3
+R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w
+dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS
++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS
+d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG
+AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f
+gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
+BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z
+NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt
+hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM
+QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf
+R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ
+DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW
+P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy
+lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq
+bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w
+AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q
+r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji
+Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU
+98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA=
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation
+# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation
+# Label: "SSL.com TLS ECC Root CA 2022"
+# Serial: 26605119622390491762507526719404364228
+# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5
+# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39
+# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw
+CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT
+U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2
+MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh
+dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm
+acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN
+SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME
+GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW
+uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp
+15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN
+b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos
+# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos
+# Label: "Atos TrustedRoot Root CA ECC TLS 2021"
+# Serial: 81873346711060652204712539181482831616
+# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8
+# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd
+# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8
+-----BEGIN CERTIFICATE-----
+MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
+LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
+CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
+MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF
+Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X
+tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4
+AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2
+KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
+aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
+CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
+9H1/IISpQuQo
+-----END CERTIFICATE-----
+
+# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos
+# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos
+# Label: "Atos TrustedRoot Root CA RSA TLS 2021"
+# Serial: 111436099570196163832749341232207667876
+# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2
+# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48
+# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f
+-----BEGIN CERTIFICATE-----
+MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM
+MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx
+MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00
+MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD
+QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z
+4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv
+Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ
+kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs
+GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln
+nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh
+3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD
+0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy
+geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8
+ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB
+c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI
+pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS
+4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs
+o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ
+qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw
+xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM
+rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4
+AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR
+0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY
+o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5
+dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE
+oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc.
+# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc.
+# Label: "TrustAsia Global Root CA G3"
+# Serial: 576386314500428537169965010905813481816650257167
+# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04
+# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7
+# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08
+-----BEGIN CERTIFICATE-----
+MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM
+BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp
+ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe
+Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw
+IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU
+cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS
+T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK
+AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1
+nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep
+qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA
+yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs
+hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX
+zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv
+kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT
+f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA
+uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB
+o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih
+MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E
+BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4
+wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2
+XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1
+JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j
+ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV
+VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx
+xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on
+AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d
+7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj
+gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV
++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo
+FGWsJwt0ivKH
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc.
+# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc.
+# Label: "TrustAsia Global Root CA G4"
+# Serial: 451799571007117016466790293371524403291602933463
+# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb
+# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a
+# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c
+-----BEGIN CERTIFICATE-----
+MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw
+WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
+IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y
+MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD
+VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz
+dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx
+s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw
+LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij
+YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD
+pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE
+AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR
+UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj
+/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=CommScope Public Trust ECC Root-01 O=CommScope
+# Subject: CN=CommScope Public Trust ECC Root-01 O=CommScope
+# Label: "CommScope Public Trust ECC Root-01"
+# Serial: 385011430473757362783587124273108818652468453534
+# MD5 Fingerprint: 3a:40:a7:fc:03:8c:9c:38:79:2f:3a:a2:6c:b6:0a:16
+# SHA1 Fingerprint: 07:86:c0:d8:dd:8e:c0:80:98:06:98:d0:58:7a:ef:de:a6:cc:a2:5d
+# SHA256 Fingerprint: 11:43:7c:da:7b:b4:5e:41:36:5f:45:b3:9a:38:98:6b:0d:e0:0d:ef:34:8e:0c:7b:b0:87:36:33:80:0b:c3:8b
+-----BEGIN CERTIFICATE-----
+MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMw
+TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t
+bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNa
+Fw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv
+cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDEw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLxeP0C
+flfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJE
+hRGnSjot6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggq
+hkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg
+2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liWpDVfG2XqYZpwI7UNo5uS
+Um9poIyNStDuiw7LR47QjRE=
+-----END CERTIFICATE-----
+
+# Issuer: CN=CommScope Public Trust ECC Root-02 O=CommScope
+# Subject: CN=CommScope Public Trust ECC Root-02 O=CommScope
+# Label: "CommScope Public Trust ECC Root-02"
+# Serial: 234015080301808452132356021271193974922492992893
+# MD5 Fingerprint: 59:b0:44:d5:65:4d:b8:5c:55:19:92:02:b6:d1:94:b2
+# SHA1 Fingerprint: 3c:3f:ef:57:0f:fe:65:93:86:9e:a0:fe:b0:f6:ed:8e:d1:13:c7:e5
+# SHA256 Fingerprint: 2f:fb:7f:81:3b:bb:b3:c8:9a:b4:e8:16:2d:0f:16:d7:15:09:a8:30:cc:9d:73:c2:62:e5:14:08:75:d1:ad:4a
+-----BEGIN CERTIFICATE-----
+MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMw
+TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t
+bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRa
+Fw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv
+cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDIw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/MMDAL
+j2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmU
+v4RDsNuESgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggq
+hkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/n
+ich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs73u1Z/GtMMH9ZzkXpc2AV
+mkzw5l4lIhVtwodZ0LKOag==
+-----END CERTIFICATE-----
+
+# Issuer: CN=CommScope Public Trust RSA Root-01 O=CommScope
+# Subject: CN=CommScope Public Trust RSA Root-01 O=CommScope
+# Label: "CommScope Public Trust RSA Root-01"
+# Serial: 354030733275608256394402989253558293562031411421
+# MD5 Fingerprint: 0e:b4:15:bc:87:63:5d:5d:02:73:d4:26:38:68:73:d8
+# SHA1 Fingerprint: 6d:0a:5f:f7:b4:23:06:b4:85:b3:b7:97:64:fc:ac:75:f5:33:f2:93
+# SHA256 Fingerprint: 02:bd:f9:6e:2a:45:dd:9b:f1:8f:c7:e1:db:df:21:a0:37:9b:a3:c9:c2:61:03:44:cf:d8:d6:06:fe:c1:ed:81
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQEL
+BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi
+Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1
+NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t
+U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt
+MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45FtnYSk
+YZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslh
+suitQDy6uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0al
+DrJLpA6lfO741GIDuZNqihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3Oj
+WiE260f6GBfZumbCk6SP/F2krfxQapWsvCQz0b2If4b19bJzKo98rwjyGpg/qYFl
+P8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/cZip8UlF1y5mO6D1cv547
+KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTifBSeolz7p
+UcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/
+kQO9lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JO
+Hg9O5j9ZpSPcPYeoKFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkB
+Ea801M/XrmLTBQe0MXXgDW1XT2mH+VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6U
+CBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm45P3luG0wDQYJ
+KoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6
+NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQ
+nmhUQo8mUuJM3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+
+QgvfKNmwrZggvkN80V4aCRckjXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2v
+trV0KnahP/t1MJ+UXjulYPPLXAziDslg+MkfFoom3ecnf+slpoq9uC02EJqxWE2a
+aE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/WNyVntHKLr4W96ioD
+j8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+o/E4
+Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0w
+lREQKC6/oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHn
+YfkUyq+Dj7+vsQpZXdxc1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVoc
+icCMb3SgazNNtQEo/a2tiRc7ppqEvOuM6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw
+-----END CERTIFICATE-----
+
+# Issuer: CN=CommScope Public Trust RSA Root-02 O=CommScope
+# Subject: CN=CommScope Public Trust RSA Root-02 O=CommScope
+# Label: "CommScope Public Trust RSA Root-02"
+# Serial: 480062499834624527752716769107743131258796508494
+# MD5 Fingerprint: e1:29:f9:62:7b:76:e2:96:6d:f3:d4:d7:0f:ae:1f:aa
+# SHA1 Fingerprint: ea:b0:e2:52:1b:89:93:4c:11:68:f2:d8:9a:ac:22:4c:a3:8a:57:ae
+# SHA256 Fingerprint: ff:e9:43:d7:93:42:4b:4f:7c:44:0c:1c:3d:64:8d:53:63:f3:4b:82:dc:87:aa:7a:9f:11:8f:c5:de:e1:01:f1
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQEL
+BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi
+Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2
+NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t
+U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt
+MDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3VrCLE
+NQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0
+kyI9p+Kx7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1C
+rWDaSWqVcN3SAOLMV2MCe5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxz
+hkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2WWy09X6GDRl224yW4fKcZgBzqZUPckXk2
+LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rpM9kzXzehxfCrPfp4sOcs
+n/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIfhs1w/tku
+FT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5
+kQMreyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3
+wNemKfrb3vOTlycEVS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6v
+wQcQeKwRoi9C8DfF8rhW3Q5iLc4tVn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs
+5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7GxcJXvYXowDQYJ
+KoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB
+KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3
++VGXu6TwYofF1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbyme
+APnCKfWxkxlSaRosTKCL4BWaMS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3Nyq
+pgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xdgSGn2rtO/+YHqP65DSdsu3BaVXoT
+6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2OHG1QAk8mGEPej1WF
+sQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+NmYWvt
+PjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2d
+lklyALKrdVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670
+v64fG9PiO/yzcnMcmyiQiRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17O
+rg3bhzjlP1v9mxnhMUF6cKojawHhRUzNlM47ni3niAIi9G7oyOzWPPO5std3eqx7
+-----END CERTIFICATE-----
+
+# Issuer: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH
+# Subject: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH
+# Label: "Telekom Security TLS ECC Root 2020"
+# Serial: 72082518505882327255703894282316633856
+# MD5 Fingerprint: c1:ab:fe:6a:10:2c:03:8d:bc:1c:22:32:c0:85:a7:fd
+# SHA1 Fingerprint: c0:f8:96:c5:a9:3b:01:06:21:07:da:18:42:48:bc:e9:9d:88:d5:ec
+# SHA256 Fingerprint: 57:8a:f4:de:d0:85:3f:4e:59:98:db:4a:ea:f9:cb:ea:8d:94:5f:60:b6:20:a3:8d:1a:3c:13:b2:bc:7b:a8:e1
+-----BEGIN CERTIFICATE-----
+MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw
+CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH
+bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw
+MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx
+JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE
+AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O
+tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP
+f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA
+MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di
+z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn
+27iQ7t0l
+-----END CERTIFICATE-----
+
+# Issuer: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH
+# Subject: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH
+# Label: "Telekom Security TLS RSA Root 2023"
+# Serial: 44676229530606711399881795178081572759
+# MD5 Fingerprint: bf:5b:eb:54:40:cd:48:71:c4:20:8d:7d:de:0a:42:f2
+# SHA1 Fingerprint: 54:d3:ac:b3:bd:57:56:f6:85:9d:ce:e5:c3:21:e2:d4:ad:83:d0:93
+# SHA256 Fingerprint: ef:c6:5c:ad:bb:59:ad:b6:ef:e8:4d:a2:23:11:b3:56:24:b7:1b:3b:1e:a0:da:8b:66:55:17:4e:c8:97:86:46
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj
+MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0
+eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy
+MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC
+REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG
+A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9
+cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV
+cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA
+U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6
+Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug
+BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy
+8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J
+co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg
+8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8
+rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12
+mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg
++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX
+gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
+p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ
+pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm
+9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw
+M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd
+GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+
+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t
+xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+
+w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK
+L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj
+X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q
+ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm
+dTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
+-----END CERTIFICATE-----
+
+# Issuer: CN=FIRMAPROFESIONAL CA ROOT-A WEB O=Firmaprofesional SA
+# Subject: CN=FIRMAPROFESIONAL CA ROOT-A WEB O=Firmaprofesional SA
+# Label: "FIRMAPROFESIONAL CA ROOT-A WEB"
+# Serial: 65916896770016886708751106294915943533
+# MD5 Fingerprint: 82:b2:ad:45:00:82:b0:66:63:f8:5f:c3:67:4e:ce:a3
+# SHA1 Fingerprint: a8:31:11:74:a6:14:15:0d:ca:77:dd:0e:e4:0c:5d:58:fc:a0:72:a5
+# SHA256 Fingerprint: be:f2:56:da:f2:6e:9c:69:bd:ec:16:02:35:97:98:f3:ca:f7:18:21:a0:3e:01:82:57:c5:3c:65:61:7f:3d:4a
+-----BEGIN CERTIFICATE-----
+MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQsw
+CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE
+YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB
+IFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2WhcNNDcwMzMxMDkwMTM2WjBuMQsw
+CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE
+YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB
+IFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zf
+e9MEkVz6iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6C
+cyvHZpsKjECcfIr28jlgst7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB
+/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FDY1w8ndYn81LsF7Kpryz3dvgwHQYDVR0O
+BBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO
+PQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFw
+hVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dG
+XSaQpYXFuXqUPoeovQA=
+-----END CERTIFICATE-----
diff --git a/strudel_ex/virt/Lib/site-packages/certifi/core.py b/strudel_ex/virt/Lib/site-packages/certifi/core.py
new file mode 100644
index 00000000..91f538bb
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/certifi/core.py
@@ -0,0 +1,114 @@
+"""
+certifi.py
+~~~~~~~~~~
+
+This module returns the installation location of cacert.pem or its contents.
+"""
+import sys
+import atexit
+
+def exit_cacert_ctx() -> None:
+ _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr]
+
+
+if sys.version_info >= (3, 11):
+
+ from importlib.resources import as_file, files
+
+ _CACERT_CTX = None
+ _CACERT_PATH = None
+
+ def where() -> str:
+ # This is slightly terrible, but we want to delay extracting the file
+ # in cases where we're inside of a zipimport situation until someone
+ # actually calls where(), but we don't want to re-extract the file
+ # on every call of where(), so we'll do it once then store it in a
+ # global variable.
+ global _CACERT_CTX
+ global _CACERT_PATH
+ if _CACERT_PATH is None:
+ # This is slightly janky, the importlib.resources API wants you to
+ # manage the cleanup of this file, so it doesn't actually return a
+ # path, it returns a context manager that will give you the path
+ # when you enter it and will do any cleanup when you leave it. In
+ # the common case of not needing a temporary file, it will just
+ # return the file system location and the __exit__() is a no-op.
+ #
+ # We also have to hold onto the actual context manager, because
+ # it will do the cleanup whenever it gets garbage collected, so
+ # we will also store that at the global level as well.
+ _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem"))
+ _CACERT_PATH = str(_CACERT_CTX.__enter__())
+ atexit.register(exit_cacert_ctx)
+
+ return _CACERT_PATH
+
+ def contents() -> str:
+ return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii")
+
+elif sys.version_info >= (3, 7):
+
+ from importlib.resources import path as get_path, read_text
+
+ _CACERT_CTX = None
+ _CACERT_PATH = None
+
+ def where() -> str:
+ # This is slightly terrible, but we want to delay extracting the
+ # file in cases where we're inside of a zipimport situation until
+ # someone actually calls where(), but we don't want to re-extract
+ # the file on every call of where(), so we'll do it once then store
+ # it in a global variable.
+ global _CACERT_CTX
+ global _CACERT_PATH
+ if _CACERT_PATH is None:
+ # This is slightly janky, the importlib.resources API wants you
+ # to manage the cleanup of this file, so it doesn't actually
+ # return a path, it returns a context manager that will give
+ # you the path when you enter it and will do any cleanup when
+ # you leave it. In the common case of not needing a temporary
+ # file, it will just return the file system location and the
+ # __exit__() is a no-op.
+ #
+ # We also have to hold onto the actual context manager, because
+ # it will do the cleanup whenever it gets garbage collected, so
+ # we will also store that at the global level as well.
+ _CACERT_CTX = get_path("certifi", "cacert.pem")
+ _CACERT_PATH = str(_CACERT_CTX.__enter__())
+ atexit.register(exit_cacert_ctx)
+
+ return _CACERT_PATH
+
+ def contents() -> str:
+ return read_text("certifi", "cacert.pem", encoding="ascii")
+
+else:
+ import os
+ import types
+ from typing import Union
+
+ Package = Union[types.ModuleType, str]
+ Resource = Union[str, "os.PathLike"]
+
+ # This fallback will work for Python versions prior to 3.7 that lack the
+ # importlib.resources module but relies on the existing `where` function
+ # so won't address issues with environments like PyOxidizer that don't set
+ # __file__ on modules.
+ def read_text(
+ package: Package,
+ resource: Resource,
+ encoding: str = 'utf-8',
+ errors: str = 'strict'
+ ) -> str:
+ with open(where(), encoding=encoding) as data:
+ return data.read()
+
+ # If we don't have importlib.resources, then we will just do the old logic
+ # of assuming we're on the filesystem and munge the path directly.
+ def where() -> str:
+ f = os.path.dirname(__file__)
+
+ return os.path.join(f, "cacert.pem")
+
+ def contents() -> str:
+ return read_text("certifi", "cacert.pem", encoding="ascii")
diff --git a/strudel_ex/virt/Lib/site-packages/certifi/py.typed b/strudel_ex/virt/Lib/site-packages/certifi/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/INSTALLER b/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/LICENSE b/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/LICENSE
new file mode 100644
index 00000000..4362b491
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/LICENSE
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/METADATA b/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/METADATA
new file mode 100644
index 00000000..3ec4d797
--- /dev/null
+++ b/strudel_ex/virt/Lib/site-packages/chardet-5.2.0.dist-info/METADATA
@@ -0,0 +1,97 @@
+Metadata-Version: 2.1
+Name: chardet
+Version: 5.2.0
+Summary: Universal encoding detector for Python 3
+Home-page: https://github.com/chardet/chardet
+Author: Mark Pilgrim
+Author-email: mark@diveintomark.org
+Maintainer: Daniel Blanchard
+Maintainer-email: dan.blanchard@gmail.com
+License: LGPL
+Project-URL: Documentation, https://chardet.readthedocs.io/
+Project-URL: GitHub Project, https://github.com/chardet/chardet
+Project-URL: Issue Tracker, https://github.com/chardet/chardet/issues
+Keywords: encoding,i18n,xml
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Text Processing :: Linguistic
+Requires-Python: >=3.7
+License-File: LICENSE
+
+Chardet: The Universal Character Encoding Detector
+--------------------------------------------------
+
+.. image:: https://img.shields.io/travis/chardet/chardet/stable.svg
+ :alt: Build status
+ :target: https://travis-ci.org/chardet/chardet
+
+.. image:: https://img.shields.io/coveralls/chardet/chardet/stable.svg
+ :target: https://coveralls.io/r/chardet/chardet
+
+.. image:: https://img.shields.io/pypi/v/chardet.svg
+ :target: https://warehouse.python.org/project/chardet/
+ :alt: Latest version on PyPI
+
+.. image:: https://img.shields.io/pypi/l/chardet.svg
+ :alt: License
+
+
+Detects
+ - ASCII, UTF-8, UTF-16 (2 variants), UTF-32 (4 variants)
+ - Big5, GB2312, EUC-TW, HZ-GB-2312, ISO-2022-CN (Traditional and Simplified Chinese)
+ - EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP (Japanese)
+ - EUC-KR, ISO-2022-KR, Johab (Korean)
+ - KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251 (Cyrillic)
+ - ISO-8859-5, windows-1251 (Bulgarian)
+ - ISO-8859-1, windows-1252, MacRoman (Western European languages)
+ - ISO-8859-7, windows-1253 (Greek)
+ - ISO-8859-8, windows-1255 (Visual and Logical Hebrew)
+ - TIS-620 (Thai)
+
+.. note::
+ Our ISO-8859-2 and windows-1250 (Hungarian) probers have been temporarily
+ disabled until we can retrain the models.
+
+Requires Python 3.7+.
+
+Installation
+------------
+
+Install from `PyPI