import { ImageService, ImageSize, ContentResource, Service as Service$1, ImageTile, ImageProfile, IIIFExternalWebResource } from '@iiif/presentation-3';

/**
 * Get canonical service url
 * Ensures an image service id contains the /info.json on the end of it.
 *
 * @param serviceId
 */
declare function canonicalServiceUrl(serviceId: string): string;

declare const STANFORD_IIIF_IMAGE_COMPLIANCE_0 = "http://library.stanford.edu/iiif/image-api/compliance.html#level0";
declare const STANFORD_IIIF_IMAGE_COMPLIANCE_1 = "http://library.stanford.edu/iiif/image-api/compliance.html#level1";
declare const STANFORD_IIIF_IMAGE_COMPLIANCE_2 = "http://library.stanford.edu/iiif/image-api/compliance.html#level2";
declare const STANFORD_IIIF_IMAGE_CONFORMANCE_0 = "http://library.stanford.edu/iiif/image-api/conformance.html#level0";
declare const STANFORD_IIIF_IMAGE_CONFORMANCE_1 = "http://library.stanford.edu/iiif/image-api/conformance.html#level1";
declare const STANFORD_IIIF_IMAGE_CONFORMANCE_2 = "http://library.stanford.edu/iiif/image-api/conformance.html#level2";
declare const STANFORD_IIIF_1_IMAGE_COMPLIANCE_0 = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0";
declare const STANFORD_IIIF_1_IMAGE_COMPLIANCE_1 = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1";
declare const STANFORD_IIIF_1_IMAGE_COMPLIANCE_2 = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2";
declare const STANFORD_IIIF_1_IMAGE_CONFORMANCE_0 = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level0";
declare const STANFORD_IIIF_1_IMAGE_CONFORMANCE_1 = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1";
declare const STANFORD_IIIF_1_IMAGE_CONFORMANCE_2 = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2";
declare const IIIF_1_IMAGE_LEVEL_0 = "http://iiif.io/api/image/1/level0.json";
declare const IIIF_1_IMAGE_LEVEL_0_PROFILE = "http://iiif.io/api/image/1/profiles/level0.json";
declare const IIIF_1_IMAGE_LEVEL_1 = "http://iiif.io/api/image/1/level1.json";
declare const IIIF_1_IMAGE_LEVEL_1_PROFILE = "http://iiif.io/api/image/1/profiles/level1.json";
declare const IIIF_1_IMAGE_LEVEL_2 = "http://iiif.io/api/image/1/level2.json";
declare const IIIF_1_IMAGE_LEVEL_2_PROFILE = "http://iiif.io/api/image/1/profiles/level2.json";
declare const IIIF_2_IMAGE_LEVEL_0 = "http://iiif.io/api/image/2/level0.json";
declare const IIIF_2_IMAGE_LEVEL_0_PROFILE = "http://iiif.io/api/image/2/profiles/level0.json";
declare const IIIF_2_IMAGE_LEVEL_1 = "http://iiif.io/api/image/2/level1.json";
declare const IIIF_2_IMAGE_LEVEL_1_PROFILE = "http://iiif.io/api/image/2/profiles/level1.json";
declare const IIIF_2_IMAGE_LEVEL_2 = "http://iiif.io/api/image/2/level2.json";
declare const IIIF_2_IMAGE_LEVEL_2_PROFILE = "http://iiif.io/api/image/2/profiles/level2.json";
declare const IIIF_3_IMAGE_LEVEL_0 = "level0";
declare const IIIF_3_IMAGE_LEVEL_1 = "level1";
declare const IIIF_3_IMAGE_LEVEL_2 = "level2";
declare const IIIF_2_IMAGE_LEVEL_0_NO_JSON = "http://iiif.io/api/image/2/level0";
declare const IIIF_2_IMAGE_LEVEL_1_NO_JSON = "http://iiif.io/api/image/2/level1";
declare const IIIF_2_IMAGE_LEVEL_2_NO_JSON = "http://iiif.io/api/image/2/level2";
declare const IIIF_1_IMAGE_LEVEL_0_COMPLIANCE = "https://iiif.io/api/image/1.1/compliance/#level0";
declare const IIIF_1_IMAGE_LEVEL_1_COMPLIANCE = "https://iiif.io/api/image/1.1/compliance/#level1";
declare const IIIF_1_IMAGE_LEVEL_2_COMPLIANCE = "https://iiif.io/api/image/1.1/compliance/#level2";
declare const level2Support: string[];
declare const level1Support: string[];
declare const imageServiceProfiles: string[];
declare const level0Support: string[];
type Profile = {
    extraFormats: string[];
    extraQualities: string[];
    extraFeatures: ExtraFeature[];
    maxArea?: number;
    maxHeight?: number;
    maxWidth?: number;
};
declare const level0: Profile;
declare const level1: Profile;
declare const level2: Profile;
declare const extraFeatures: readonly ["baseUriRedirect", "canonicalLinkHeader", "cors", "jsonldMediaType", "mirroring", "profileLinkHeader", "regionByPct", "regionByPx", "regionSquare", "rotationArbitrary", "rotationBy90s", "sizeByConfinedWh", "sizeByH", "sizeByPct", "sizeByW", "sizeByWh", "sizeUpscaling", "sizeByWhListed", "sizeByDistortedWh", "sizeByForcedWh"];
type ExtraFeature = typeof extraFeatures extends ReadonlyArray<infer ElementType> ? ElementType : never;

declare function combineProfiles(service: ImageService): Profile;

type Service = ImageService & {
    real?: false;
};
type FixedSizeImage = {
    id: string;
    type: 'fixed';
    width: number;
    height: number;
    unsafe?: boolean;
};
type FixedSizeImageService = {
    id: string;
    type: 'fixed-service';
    width: number;
    height: number;
    level?: number | null;
    version?: number;
};
type VariableSizeImage = {
    id: string;
    type: 'variable';
    minWidth: number;
    maxWidth: number;
    minHeight: number;
    maxHeight: number;
    level?: number | null;
    version?: number;
};
type UnknownSizeImage = {
    id: string;
    type: 'unknown';
};
type ImageCandidate = FixedSizeImage | VariableSizeImage | UnknownSizeImage | FixedSizeImageService;
type ImageCandidateRequest = {
    width?: number;
    height?: number;
    maxWidth?: number;
    maxHeight?: number;
    minWidth?: number;
    minHeight?: number;
    fallback?: boolean;
    atAnyCost?: boolean;
    unsafeImageService?: boolean;
    returnAllOptions?: boolean;
    allowUnsafe?: boolean;
    preferFixedSize?: boolean;
    explain?: boolean;
};
/**
 * Size parameter
 *
 * Represents the {size} parameter of a IIIF image request.
 * see https://iiif.io/api/image/3.0/#42-size
 * Port of https://github.com/digirati-co-uk/iiif-net/blob/main/src/IIIF/IIIF/ImageApi/SizeParameter.cs
 */
type SizeParameter = {
    height?: number;
    width?: number;
    max: boolean;
    serialiseAsFull?: boolean;
    upscaled: boolean;
    confined: boolean;
    percentScale?: number;
    version?: 2 | 3;
};
/**
 * Region parameter
 *
 * Represents the {region} parameter of a IIIF image request.
 * see https://iiif.io/api/image/3.0/#41-region
 * Port of https://github.com/digirati-co-uk/iiif-net/blob/main/src/IIIF/IIIF/ImageApi/RegionParameter.cs
 */
type RegionParameter = {
    x?: number;
    y?: number;
    w?: number;
    h?: number;
    full?: boolean;
    square?: boolean;
    percent?: boolean;
};
/**
 * Rotation parameter
 *
 * Represents the {rotation} parameter of a IIIF image request.
 * see https://iiif.io/api/image/3.0/#43-rotation
 * Port of https://github.com/digirati-co-uk/iiif-net/blob/main/src/IIIF/IIIF/ImageApi/RotationParameter.cs
 */
type RotationParameter = {
    mirror?: boolean;
    angle: number;
};
type ImageServiceImageRequest = {
    type: 'base';
    scheme: string;
    server: string;
    prefix: string;
    identifier: string;
} | {
    type: 'info';
    scheme: string;
    server: string;
    prefix: string;
    identifier: string;
} | {
    type: 'image';
    scheme: string;
    server: string;
    prefix: string;
    identifier: string;
    region: RegionParameter;
    size: SizeParameter;
    rotation: RotationParameter;
    quality: string;
    format: string;
    originalPath: string;
};

declare function createImageServiceRequest(imageService: ImageService): ImageServiceImageRequest;

/**
 * Extract fixed size scales
 *
 * Given a source width and height and a list of sizes of that same image,
 * it will return an ordered list of scales.
 *
 * @param width
 * @param height
 * @param sizes
 */
declare function extractFixedSizeScales(width: number, height: number, sizes: ImageSize[]): number[];

/**
 * Fixed sizes from scales.
 *
 * Given a width and height of an image and a list of scales, this will return
 * an ordered list of widths and heights of the image at those scales.
 *
 * @param width
 * @param height
 * @param scales
 */
declare function fixedSizesFromScales(width: number, height: number, scales: number[]): ImageSize[];

/**
 * Get custom size from service
 *
 * Given an image service – usually a full one, de-referenced or embedded – this
 * will return a list of available image sizes (min and max width and height) that
 * can be used to construct a IIIF query to get an image at any size within those
 * bounds. This is only supported by some image services. If unsupported, this will
 * return an empty list.
 *
 * @param service
 */
declare function getCustomSizeFromService(service: Service): ImageCandidate[];

/**
 * Get fixed size from image
 *
 * Given a content resource, usually the body of a painting annotation, this will
 * return the URL to the image, and the height and width. The resource may also
 * be a string / direct link to the image. The height and width may be inferred from
 * a IIIF Image API endpoint, otherwise the return image candidate will have a type
 * of unknown.
 *
 * @param contentResource
 */
declare function getFixedSizeFromImage(contentResource: ContentResource | string): ImageCandidate | null;

/**
 * Get fixed sizes from service.
 *
 * Given an image service, this will extract the images from the sizes field of
 * the service. These are usually cached and great options for thumbnails.
 *
 * @param service
 */
declare function getFixedSizesFromService(service: Service$1): FixedSizeImageService[];

declare function getId(resource: any): any;

type ImageServer = {
    root: string;
    server: string | null;
    sampledId: string;
    verifications: number;
    verified: boolean;
    preLoaded: boolean;
    malformed: boolean;
    result: {
        context: string | string[];
        resourceServiceRatio: number;
        sampledSizes: ImageSize[];
        sizeRatios: number[];
        sampledTiles: ImageTile[];
        sampledProfile: ImageProfile | ImageProfile[];
    };
};
type ImageServiceRequest = {
    id: string;
    width: number;
    height: number;
    source?: ImageService;
};
type LoadedImageService = Service & {
    real: boolean;
};
type ImageServiceLoaderConfig = {
    verificationsRequired: number;
    approximateServices: boolean;
    enableFetching: boolean;
    disableThrottling: boolean;
};
declare class ImageServiceLoader {
    constructor(options?: Partial<ImageServiceLoaderConfig>);
    config: ImageServiceLoaderConfig;
    fetchingCount: number;
    imageServices: {
        [k: string]: LoadedImageService;
    };
    knownImageServers: {
        [k: string]: ImageServer;
    };
    /**
     * Preload image service
     *
     * This will preload an image service, fetching details and recording the image server that served
     * the request. Based on this it will make a template for predicting other image sources from this
     * server. You can optionally pass in other ids to verify that the prediction is accurate.
     *
     */
    setConfig(config: Partial<ImageServiceLoaderConfig>): void;
    /**
     * Sample pre-fetched service
     *
     * If you have already fetched an image service, or are creating a viewer that only talks to a single
     * image server and want to avoid calls, you can sample a service up-front. This will allow you to make
     * completely synchronous calls to `loadServiceSync` and avoid any network calls for image services.
     *
     * @param service
     * @param preLoaded Mark this as being pre-loaded (default: true)
     */
    sample(service: Service, imageServiceRequest?: ImageServiceRequest, preLoaded?: boolean): true | Promise<boolean>;
    /**
     * Preload an image server
     *
     * Similar to sample, but faster. This will bypass any checks and the logic contained in this implementation
     * allowing you to correct mistakes this implementation might have made.
     *
     * @param server
     * @param forceVerify
     */
    preLoad(server: ImageServer, forceVerify?: boolean): void;
    /**
     * Predict
     *
     * Predicts what the image service will be for a content resource.
     *
     * @param resource
     * @param verify
     * @param force
     */
    predict(resource: ImageServiceRequest, verify?: boolean, force?: boolean): Service | null;
    getThumbnailFromResource(unknownResource: ContentResource | undefined, request: ImageCandidateRequest, dereference?: boolean, otherCandidates?: ImageCandidate[]): Promise<{
        best: ImageCandidate | null;
        fallback: ImageCandidate[];
        log: string[];
    }>;
    getImageCandidates(unknownResource: ContentResource, dereference?: boolean): Promise<ImageCandidate[]>;
    /**
     * Verify approximation
     *
     * Given an image service, it will dereference that image service and compare the result with what
     * would have been generated if we used internal guessing.
     *
     * @param resource
     * @return Promise<boolean>
     */
    verify(resource: ImageServiceRequest): Promise<boolean>;
    canLoadSync(service: ImageServiceRequest | Service | string): boolean;
    /**
     * Mark image service as malformed
     *
     * If you run into issues requesting images, you can mark an image service as malformed, and it will
     * return you a new one. Future image services will also be requested fresh, and the system will have
     * failed. Report a bug if this happens.
     *
     * @param resource
     */
    markAsMalformed(resource: ImageServiceRequest): Promise<Service>;
    /**
     * Fetch an image service (use loadService instead)
     *
     * @param serviceId
     * @param forceFresh
     */
    fetchService(serviceId: string, forceFresh?: boolean): Promise<Service & {
        real: boolean;
    }>;
    fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
    /**
     * Load an image service
     *
     * @param resource
     * @param forceFresh
     *
     * @todo make this batched, so only the maximum required can be done at once, to allow
     *       for the prediction engine to kick in.
     */
    loadService(resource: ImageServiceRequest, forceFresh?: boolean): Promise<Service>;
    /**
     * Load service synchronously
     *
     * If you know that the image service you are
     * @param resource
     */
    loadServiceSync(resource: ImageServiceRequest): Service | null;
}
declare const imageServiceLoader: ImageServiceLoader;

/**
 * Get image candidates
 *
 * Given an unknown resource, and optionally an image service loader, it will
 * try to get all of the possible options for images at a specific size.
 *
 * Note: if you are wanting to depend on external web resources, then you have
 * to either preload these, or prepare the image loader for predicting them.
 *
 * @param unknownResource
 * @param dereference
 * @param loader
 */
declare function getImageCandidates(unknownResource: ContentResource, dereference: boolean | undefined, loader: ImageServiceLoader): ImageCandidate[];

declare function getImageCandidatesFromService(service: Service[]): ImageCandidate[];

declare function getImageFromTileSource(image: FixedSizeImageService, targetWidth: number, targetHeight?: number): FixedSizeImage;

/**
 * Get image server from ID.
 *
 * Normalises image service URLs to extract identity of the image server.
 *
 * @param url
 */
declare function getImageServerFromId(url: string): string;

/**
 * Given a resource, will return only the image services on that resource.
 *
 * @param resource
 */
declare function getImageServices(resource: IIIFExternalWebResource): Service[];

/**
 * Returns a fixed size image using the tile using the largest available size,
 * or the smallest scale factor.
 *
 * @param service
 */
declare function getSmallestScaleFactorAsSingleImage(service: Service): FixedSizeImageService | null;

declare function getType(resource: any): any;

declare function imageServiceRequestToString(req: ImageServiceImageRequest, service?: ImageService): string;

declare function imageServiceSupportsFormat(imageService: ImageService, format: string): readonly [false, "Not a valid image service"] | readonly [false, `Max area is ${number}`] | readonly [false, `Max width is ${number}`] | readonly [false, `Max height is ${number}`] | readonly [false, `Missing features: ${string}`] | readonly [false, `Missing formats: ${string}`] | readonly [false, `Missing qualities: ${string}`] | readonly [true];

declare function imageServiceSupportsRequest(imageService: ImageService, request: ImageServiceImageRequest): readonly [true] | boolean[] | readonly [false, "Not a valid image service" | `Max area is ${number}` | `Max width is ${number}` | `Max height is ${number}` | `Missing features: ${string}` | `Missing formats: ${string}` | `Missing qualities: ${string}`];

/**
 * Extracts the height and width from an image URL
 *
 * @param image
 */
declare function inferSizeFromUrl(image: string): ImageCandidate;

declare function isBestMatch(request: Required<ImageCandidateRequest>, current: FixedSizeImage | null, candidate: FixedSizeImage): boolean;

declare function isImageService(service: any): service is ImageService;

declare function levelToProfile(levelProfile: string): Profile;

declare function parseImageServiceRequest(input: string, _prefix?: string): ImageServiceImageRequest;

declare function parseImageServiceUrl(canonicalId: string, prefix?: string): {
    scheme: string;
    server: string;
    path: string;
    prefix: string;
};

declare function parseRegionParameter(pathPart: string): RegionParameter;

declare function parseRotationParameter(pathPart: string): RotationParameter;

declare function parseSizeParameter(pathPart: string): SizeParameter;

/**
 * Pick best from candidates
 *
 * Takes in a list of candidate lists. The order should be in preference. This algorithm will try to pick
 * from the first list, with a best fit size. If not it will fallback to the other lists. It may come back
 * around to the first list and provide a fallback.
 *
 * @param inputRequest
 * @param candidates
 */
declare function pickBestFromCandidates(inputRequest: ImageCandidateRequest, candidates: Array<() => ImageCandidate[]>): {
    best: ImageCandidate | null;
    fallback: ImageCandidate[];
    log: string[];
};

declare function regionParameterToString({ x, y, w, h, full, square, percent }: RegionParameter): string;

declare function rotationParameterToString(rotationParameter: RotationParameter): string;

declare function sampledTilesToTiles(width: number, height: number, sampledTiles: ImageTile[]): ImageTile[];

declare function sizeParameterToString({ max, percentScale, upscaled, confined, width, height, serialiseAsFull, version, }: SizeParameter): string;

declare function sizesMatch(sizesA: ImageSize[], sizesB: ImageSize[]): boolean;

declare function supports(service: Service, req: Partial<Profile> & {
    exactSize?: {
        width?: number;
        height?: number;
    };
}): readonly [false, "Not a valid image service"] | readonly [false, `Max area is ${number}`] | readonly [false, `Max width is ${number}`] | readonly [false, `Max height is ${number}`] | readonly [false, `Missing features: ${string}`] | readonly [false, `Missing formats: ${string}`] | readonly [false, `Missing qualities: ${string}`] | readonly [true];

declare function supportsCustomSizes(service: Service): boolean;

export { type ExtraFeature, type FixedSizeImage, type FixedSizeImageService, IIIF_1_IMAGE_LEVEL_0, IIIF_1_IMAGE_LEVEL_0_COMPLIANCE, IIIF_1_IMAGE_LEVEL_0_PROFILE, IIIF_1_IMAGE_LEVEL_1, IIIF_1_IMAGE_LEVEL_1_COMPLIANCE, IIIF_1_IMAGE_LEVEL_1_PROFILE, IIIF_1_IMAGE_LEVEL_2, IIIF_1_IMAGE_LEVEL_2_COMPLIANCE, IIIF_1_IMAGE_LEVEL_2_PROFILE, IIIF_2_IMAGE_LEVEL_0, IIIF_2_IMAGE_LEVEL_0_NO_JSON, IIIF_2_IMAGE_LEVEL_0_PROFILE, IIIF_2_IMAGE_LEVEL_1, IIIF_2_IMAGE_LEVEL_1_NO_JSON, IIIF_2_IMAGE_LEVEL_1_PROFILE, IIIF_2_IMAGE_LEVEL_2, IIIF_2_IMAGE_LEVEL_2_NO_JSON, IIIF_2_IMAGE_LEVEL_2_PROFILE, IIIF_3_IMAGE_LEVEL_0, IIIF_3_IMAGE_LEVEL_1, IIIF_3_IMAGE_LEVEL_2, type ImageCandidate, type ImageCandidateRequest, type ImageServer, type ImageServiceImageRequest, ImageServiceLoader, type ImageServiceLoaderConfig, type ImageServiceRequest, type Profile, type RegionParameter, type RotationParameter, STANFORD_IIIF_1_IMAGE_COMPLIANCE_0, STANFORD_IIIF_1_IMAGE_COMPLIANCE_1, STANFORD_IIIF_1_IMAGE_COMPLIANCE_2, STANFORD_IIIF_1_IMAGE_CONFORMANCE_0, STANFORD_IIIF_1_IMAGE_CONFORMANCE_1, STANFORD_IIIF_1_IMAGE_CONFORMANCE_2, STANFORD_IIIF_IMAGE_COMPLIANCE_0, STANFORD_IIIF_IMAGE_COMPLIANCE_1, STANFORD_IIIF_IMAGE_COMPLIANCE_2, STANFORD_IIIF_IMAGE_CONFORMANCE_0, STANFORD_IIIF_IMAGE_CONFORMANCE_1, STANFORD_IIIF_IMAGE_CONFORMANCE_2, type Service, type SizeParameter, type UnknownSizeImage, type VariableSizeImage, canonicalServiceUrl, combineProfiles, createImageServiceRequest, extraFeatures, extractFixedSizeScales, fixedSizesFromScales, getCustomSizeFromService, getFixedSizeFromImage, getFixedSizesFromService, getId, getImageCandidates, getImageCandidatesFromService, getImageFromTileSource, getImageServerFromId, getImageServices, getSmallestScaleFactorAsSingleImage, getType, imageServiceLoader, imageServiceProfiles, imageServiceRequestToString, imageServiceSupportsFormat, imageServiceSupportsRequest, inferSizeFromUrl, isBestMatch, isImageService, level0, level0Support, level1, level1Support, level2, level2Support, levelToProfile, parseImageServiceRequest, parseImageServiceUrl, parseRegionParameter, parseRotationParameter, parseSizeParameter, pickBestFromCandidates, regionParameterToString, rotationParameterToString, sampledTilesToTiles, sizeParameterToString, sizesMatch, supports, supportsCustomSizes };
