import { AttributionKey } from '@fluidframework/runtime-definitions';
import { IChannelStorageService } from '@fluidframework/datastore-definitions';
import { IEventThisPlaceHolder } from '@fluidframework/core-interfaces';
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
import { IFluidHandle } from '@fluidframework/core-interfaces';
import { IFluidSerializer } from '@fluidframework/shared-object-base';
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
import { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils';

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare function addProperties(oldProps: PropertySet | undefined, newProps: PropertySet, op?: ICombiningOp, seq?: number): PropertySet;

/**
 * @alpha
 */
export declare function appendToMergeTreeDeltaRevertibles(deltaArgs: IMergeTreeDeltaCallbackArgs, revertibles: MergeTreeDeltaRevertible[]): void;

/**
 * Implements policy dictating which kinds of operations should be attributed and how.
 * @alpha
 * @sealed
 */
export declare interface AttributionPolicy {
    /* Excluded from this release type: attach */
    /* Excluded from this release type: detach */
    /* Excluded from this release type: isAttached */
    /* Excluded from this release type: serializer */
}

export declare abstract class BaseSegment extends MergeNode implements ISegment {
    clientId: number;
    seq: number;
    removedSeq?: number;
    removedClientIds?: number[];
    readonly segmentGroups: SegmentGroupCollection;
    readonly trackingCollection: TrackingGroupCollection;
    /**
     * @alpha
     */
    attribution?: IAttributionCollection<AttributionKey>;
    propertyManager?: PropertiesManager;
    properties?: PropertySet;
    localRefs?: LocalReferenceCollection;
    abstract readonly type: string;
    localSeq?: number;
    localRemovedSeq?: number;
    addProperties(newProps: PropertySet, op?: ICombiningOp, seq?: number, collabWindow?: CollaborationWindow, rollback?: PropertiesRollback): PropertySet | undefined;
    hasProperty(key: string): boolean;
    isLeaf(): boolean;
    protected cloneInto(b: ISegment): void;
    canAppend(segment: ISegment): boolean;
    protected addSerializedProps(jseg: IJSONSegment): void;
    abstract toJSONObject(): any;
    ack(segmentGroup: SegmentGroup, opArgs: IMergeTreeDeltaOpArgs): boolean;
    splitAt(pos: number): ISegment | undefined;
    private copyPropertiesTo;
    abstract clone(): ISegment;
    append(other: ISegment): void;
    protected abstract createSplitSegmentAt(pos: number): BaseSegment | undefined;
}

export declare class Client extends TypedEventEmitter<IClientEvents> {
    readonly specToSegment: (spec: IJSONSegment) => ISegment;
    readonly logger: ITelemetryLoggerExt;
    longClientId: string | undefined;
    private readonly _mergeTree;
    private readonly clientNameToIds;
    private readonly shortClientIdMap;
    private readonly pendingConsensus;
    constructor(specToSegment: (spec: IJSONSegment) => ISegment, logger: ITelemetryLoggerExt, options?: PropertySet);
    /**
     * The merge tree maintains a queue of segment groups for each local operation.
     * These segment groups track segments modified by an operation.
     * This method peeks the tail of that queue, and returns the segments groups there.
     * It is used to get the segment group(s) for the previous operations.
     * @param count - The number segment groups to get peek from the tail of the queue. Default 1.
     */
    peekPendingSegmentGroups(count?: number): SegmentGroup | SegmentGroup[] | undefined;
    /**
     * Annotate a marker and call the callback on consensus.
     * @param marker - The marker to annotate
     * @param props - The properties to annotate the marker with
     * @param consensusCallback - The callback called when consensus is reached
     * @returns The annotate op if valid, otherwise undefined
     */
    annotateMarkerNotifyConsensus(marker: Marker, props: PropertySet, consensusCallback: (m: Marker) => void): IMergeTreeAnnotateMsg | undefined;
    /**
     * Annotates the markers with the provided properties
     * @param marker - The marker to annotate
     * @param props - The properties to annotate the marker with
     * @param combiningOp - Optional. Specifies how to combine values for the property, such as "incr" for increment.
     * @returns The annotate op if valid, otherwise undefined
     */
    annotateMarker(marker: Marker, props: PropertySet, combiningOp?: ICombiningOp): IMergeTreeAnnotateMsg | undefined;
    /**
     * Annotates the range with the provided properties
     * @param start - The inclusive start position of the range to annotate
     * @param end - The exclusive end position of the range to annotate
     * @param props - The properties to annotate the range with
     * @param combiningOp - Specifies how to combine values for the property, such as "incr" for increment.
     * @returns The annotate op if valid, otherwise undefined
     */
    annotateRangeLocal(start: number, end: number, props: PropertySet, combiningOp: ICombiningOp | undefined): IMergeTreeAnnotateMsg | undefined;
    /**
     * Removes the range
     *
     * @param start - The inclusive start of the range to remove
     * @param end - The exclusive end of the range to remove
     */
    removeRangeLocal(start: number, end: number): IMergeTreeRemoveMsg;
    /**
     * @param pos - The position to insert the segment at
     * @param segment - The segment to insert
     */
    insertSegmentLocal(pos: number, segment: ISegment): IMergeTreeInsertMsg | undefined;
    /**
     * @param refPos - The reference position to insert the segment at
     * @param segment - The segment to insert
     */
    insertAtReferencePositionLocal(refPos: ReferencePosition, segment: ISegment): IMergeTreeInsertMsg | undefined;
    walkSegments<TClientData>(handler: ISegmentAction<TClientData>, start: number | undefined, end: number | undefined, accum: TClientData, splitRange?: boolean): void;
    walkSegments<undefined>(handler: ISegmentAction<undefined>, start?: number, end?: number, accum?: undefined, splitRange?: boolean): void;
    protected walkAllSegments<TClientData>(action: (segment: ISegment, accum?: TClientData) => boolean, accum?: TClientData): boolean;
    /**
     * Serializes the data required for garbage collection. The IFluidHandles stored in all segments that haven't
     * been removed represent routes to other objects. We serialize the data in these segments using the passed in
     * serializer which keeps track of all serialized handles.
     */
    serializeGCData(handle: IFluidHandle, handleCollectingSerializer: IFluidSerializer): void;
    getCollabWindow(): CollaborationWindow;
    /**
     * Returns the current position of a segment, and -1 if the segment
     * does not exist in this merge tree
     * @param segment - The segment to get the position of
     */
    getPosition(segment: ISegment | undefined, localSeq?: number): number;
    /**
     * Creates a `LocalReferencePosition` on this client. If the refType does not include ReferenceType.Transient,
     * the returned reference will be added to the localRefs on the provided segment.
     * @param segment - Segment to add the local reference on
     * @param offset - Offset on the segment at which to place the local reference
     * @param refType - ReferenceType for the created local reference
     * @param properties - PropertySet to place on the created local reference
     * @param canSlideToEndpoint - Whether or not the created local reference can
     * slide onto one of the special endpoint segments denoting the position
     * before the start of or after the end of the tree
     */
    createLocalReferencePosition(segment: ISegment | "start" | "end", offset: number | undefined, refType: ReferenceType, properties: PropertySet | undefined, slidingPreference?: SlidingPreference, canSlideToEndpoint?: boolean): LocalReferencePosition;
    /**
     * Removes a `LocalReferencePosition` from this client.
     */
    removeLocalReferencePosition(lref: LocalReferencePosition): LocalReferencePosition | undefined;
    /**
     * Resolves a `ReferencePosition` into a character position using this client's perspective.
     */
    localReferencePositionToPosition(lref: ReferencePosition): number;
    /**
     * Given a position specified relative to a marker id, lookup the marker
     * and convert the position to a character position.
     * @param relativePos - Id of marker (may be indirect) and whether position is before or after marker.
     */
    posFromRelativePos(relativePos: IRelativePosition): number;
    getMarkerFromId(id: string): ISegment | undefined;
    /**
     * Revert an op
     */
    rollback?(op: any, localOpMetadata: unknown): void;
    /**
     * Performs the remove based on the provided op
     * @param opArgs - The ops args for the op
     * @returns True if the remove was applied. False if it could not be.
     */
    private applyRemoveRangeOp;
    /**
     * Performs the annotate based on the provided op
     * @param opArgs - The ops args for the op
     * @returns True if the annotate was applied. False if it could not be.
     */
    private applyAnnotateRangeOp;
    /**
     * Performs the insert based on the provided op
     * @param opArgs - The ops args for the op
     * @returns True if the insert was applied. False if it could not be.
     */
    private applyInsertOp;
    /**
     * Returns a valid range for the op, or undefined
     * @param op - The op to generate the range for
     * @param clientArgs - The client args for the op
     */
    private getValidOpRange;
    /**
     * Gets the client args from the op if remote, otherwise uses the local clients info
     * @param sequencedMessage - The sequencedMessage to get the client sequence args for
     */
    private getClientSequenceArgsForMessage;
    /**
     * Gets the client args from the op if remote, otherwise uses the local clients info
     * @param opArgs - The op arg to get the client sequence args for
     */
    private getClientSequenceArgs;
    private ackPendingSegment;
    cloneFromSegments(): Client;
    getOrAddShortClientId(longClientId: string): number;
    getShortClientId(longClientId: string): number;
    getLongClientId(shortClientId: number): string;
    addLongClientId(longClientId: string): void;
    private getOrAddShortClientIdFromMessage;
    /**
     * During reconnect, we must find the positions to pending segments
     * relative to other pending segments. This methods computes that
     * position relative to a localSeq. Pending segments above the localSeq
     * will be ignored.
     *
     * @param segment - The segment to find the position for
     * @param localSeq - The localSeq to find the position of the segment at
     */
    findReconnectionPosition(segment: ISegment, localSeq: number): number;
    private resetPendingDeltaToOps;
    private applyRemoteOp;
    applyStashedOp(op: IMergeTreeDeltaOp): SegmentGroup;
    applyStashedOp(op: IMergeTreeGroupMsg): SegmentGroup[];
    applyStashedOp(op: IMergeTreeOp): SegmentGroup | SegmentGroup[];
    applyMsg(msg: ISequencedDocumentMessage, local?: boolean): void;
    updateSeqNumbers(min: number, seq: number): void;
    /**
     * Resolves a remote client's position against the local sequence
     * and returns the remote client's position relative to the local
     * sequence
     * @param remoteClientPosition - The remote client's position to resolve
     * @param remoteClientRefSeq - The reference sequence number of the remote client
     * @param remoteClientId - The client id of the remote client
     */
    resolveRemoteClientPosition(remoteClientPosition: number, remoteClientRefSeq: number, remoteClientId: string): number | undefined;
    private lastNormalizationRefSeq;
    private pendingRebase;
    /**
     * Given an pending operation and segment group, regenerate the op, so it
     * can be resubmitted
     * @param resetOp - The op to reset
     * @param segmentGroup - The segment group associated with the op
     */
    regeneratePendingOp(resetOp: IMergeTreeOp, segmentGroup: SegmentGroup | SegmentGroup[]): IMergeTreeOp;
    createTextHelper(): IMergeTreeTextHelper;
    summarize(runtime: IFluidDataStoreRuntime, handle: IFluidHandle, serializer: IFluidSerializer, catchUpMsgs: ISequencedDocumentMessage[]): ISummaryTreeWithStats;
    load(runtime: IFluidDataStoreRuntime, storage: IChannelStorageService, serializer: IFluidSerializer): Promise<{
        catchupOpsP: Promise<ISequencedDocumentMessage[]>;
    }>;
    /**
     * @deprecated this functionality is no longer supported and will be removed
     */
    getStackContext(startPos: number, rangeLabels: string[]): RangeStackMap;
    private getLocalSequenceNumber;
    localTransaction(groupOp: IMergeTreeGroupMsg): void;
    updateConsensusProperty(op: IMergeTreeAnnotateMsg, msg: ISequencedDocumentMessage): void;
    updateMinSeq(minSeq: number): void;
    getContainingSegment<T extends ISegment>(pos: number, sequenceArgs?: Pick<ISequencedDocumentMessage, "referenceSequenceNumber" | "clientId">, localSeq?: number): {
        segment: T | undefined;
        offset: number | undefined;
    };
    getPropertiesAtPosition(pos: number): PropertySet | undefined;
    getRangeExtentsOfPosition(pos: number): {
        posStart: number | undefined;
        posAfterEnd: number | undefined;
    };
    getCurrentSeq(): number;
    getClientId(): number;
    getLength(): number;
    startOrUpdateCollaboration(longClientId: string | undefined, minSeq?: number, currentSeq?: number): void;
    /**
     * @deprecated Use searchForMarker instead.
     */
    findTile(startPos: number, tileLabel: string, preceding?: boolean): {
        tile: ReferencePosition;
        pos: number;
    } | undefined;
    /**
     * Searches a string for the nearest marker in either direction to a given start position.
     * The search will include the start position, so markers at the start position are valid
     * results of the search. Makes use of block-accelerated search functions for log(n) complexity.
     *
     * @param startPos - Position at which to start the search
     * @param markerLabel - Label of the marker to search for
     * @param forwards - Whether the desired marker comes before (false) or after (true) `startPos`
     */
    searchForMarker(startPos: number, markerLabel: string, forwards?: boolean): Marker | undefined;
}

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare function clone<T>(extension: MapLike<T> | undefined): MapLike<T> | undefined;

export declare class CollaborationWindow {
    clientId: number;
    collaborating: boolean;
    minSeq: number;
    currentSeq: number;
    localSeq: number;
    loadFrom(a: CollaborationWindow): void;
}

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare function combine(combiningInfo: ICombiningOp, currentValue: any, newValue: any, seq?: number): any;

export declare const compareNumbers: (a: number, b: number) => number;

export declare function compareReferencePositions(a: ReferencePosition, b: ReferencePosition): number;

export declare const compareStrings: (a: string, b: string) => number;

/* Excluded from this release type: ConflictAction */

/**
 * Creates the op for annotating the markers with the provided properties
 * @param marker - The marker to annotate
 * @param props - The properties to annotate the marker with
 * @param combiningOp - Optional. Specifies how to combine values for the property, such as "incr" for increment.
 * @returns The annotate op
 */
export declare function createAnnotateMarkerOp(marker: Marker, props: PropertySet, combiningOp?: ICombiningOp): IMergeTreeAnnotateMsg | undefined;

/**
 * Creates the op for annotating the range with the provided properties
 * @param start - The inclusive start position of the range to annotate
 * @param end - The exclusive end position of the range to annotate
 * @param props - The properties to annotate the range with
 * @param combiningOp - Optional. Specifies how to combine values for the property, such as "incr" for increment.
 * @returns The annotate op
 */
export declare function createAnnotateRangeOp(start: number, end: number, props: PropertySet, combiningOp: ICombiningOp | undefined): IMergeTreeAnnotateMsg;

export declare function createDetachedLocalReferencePosition(refType?: ReferenceType): LocalReferencePosition;

/**
 *
 * @param ops - The ops to group
 *
 * @deprecated The ability to create group ops will be removed in an upcoming release, as group ops are redundant with he native batching capabilities of the runtime
 */
export declare function createGroupOp(...ops: IMergeTreeDeltaOp[]): IMergeTreeGroupMsg;

/**
 * @returns An {@link AttributionPolicy} which tracks only insertion of content.
 *
 * @alpha
 */
export declare function createInsertOnlyAttributionPolicy(): AttributionPolicy;

export declare function createInsertOp(pos: number, segSpec: any): IMergeTreeInsertMsg;

/**
 *
 * @param pos - The position to insert the segment at
 * @param segment - The segment to insert
 */
export declare function createInsertSegmentOp(pos: number, segment: ISegment): IMergeTreeInsertMsg;

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare function createMap<T>(): MapLike<T>;

/**
 * Creates the op to remove a range
 *
 * @param start - The inclusive start of the range to remove
 * @param end - The exclusive end of the range to remove
 */
export declare function createRemoveRangeOp(start: number, end: number): IMergeTreeRemoveMsg;

export declare function debugMarkerToString(marker: Marker): string;

export declare const DetachedReferencePosition = -1;

/* Excluded from this release type: Dictionary */

/**
 * @alpha
 */
export declare function discardMergeTreeDeltaRevertible(revertibles: MergeTreeDeltaRevertible[]): void;

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare function extend<T>(base: MapLike<T>, extension: MapLike<T> | undefined, combiningOp?: ICombiningOp, seq?: number): MapLike<T>;

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare function extendIfUndefined<T>(base: MapLike<T>, extension: MapLike<T> | undefined): MapLike<T>;

/* Excluded from this release type: getSlideToSegoff */

/**
 * @alpha
 */
export declare interface IAttributionCollection<T> {
    /**
     * Retrieves the attribution key associated with the provided offset.
     * @param channel - When specified, gets an attribution key associated with a particular channel.
     */
    getAtOffset(offset: number, channel?: string): AttributionKey | undefined;
    /**
     * Total length of all attribution keys in this collection.
     */
    readonly length: number;
    readonly channelNames: Iterable<string>;
    /* Excluded from this release type: getAll */
    /* Excluded from this release type: splitAt */
    /* Excluded from this release type: append */
    /* Excluded from this release type: clone */
    /* Excluded from this release type: update */
}

/* Excluded from this release type: IAttributionCollectionSerializer */

/* Excluded from this release type: IAttributionCollectionSpec */

/* Excluded from this release type: IClientEvents */

export declare interface ICombiningOp {
    name: string;
    defaultValue?: any;
    minValue?: any;
    maxValue?: any;
}

export declare interface IConsensusInfo {
    marker: Marker;
    callback: (m: Marker) => void;
}

export declare interface IConsensusValue {
    seq: number;
    value: any;
}

/* Excluded from this release type: IIntegerRange */

export declare interface IJSONMarkerSegment extends IJSONSegment {
    marker: IMarkerDef;
}

export declare interface IJSONSegment {
    props?: Record<string, any>;
}

export declare interface IJSONTextSegment extends IJSONSegment {
    text: string;
}

export declare interface IMarkerDef {
    refType?: ReferenceType;
}

export declare interface IMarkerModifiedAction {
    (marker: Marker): void;
}

/**
 * Common properties for a node in a merge tree.
 */
export declare interface IMergeNodeCommon {
    /**
     * The index of this node in its parent's list of children.
     */
    index: number;
    /**
     * A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.
     * `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.
     */
    ordinal: string;
    isLeaf(): this is ISegment;
}

export declare interface IMergeTreeAnnotateMsg extends IMergeTreeDelta {
    type: typeof MergeTreeDeltaType.ANNOTATE;
    pos1?: number;
    relativePos1?: IRelativePosition;
    pos2?: number;
    relativePos2?: IRelativePosition;
    props: Record<string, any>;
    combiningOp?: ICombiningOp;
}

export declare interface IMergeTreeAttributionOptions {
    /**
     * If enabled, segments will store attribution keys which can be used with the runtime to determine
     * attribution information (i.e. who created the content and when it was created).
     *
     * This flag only applied to new documents: if a snapshot is loaded, whether or not attribution keys
     * are tracked is determined by the presence of existing attribution keys in the snapshot.
     *
     * default: false
     * @alpha
     */
    track?: boolean;
    /**
     * Provides a policy for how to track attribution data on segments.
     * This option must be provided if either:
     * - `track` is set to true
     * - a document containing existing attribution information is loaded
     * @alpha
     */
    policyFactory?: () => AttributionPolicy;
}

export declare interface IMergeTreeClientSequenceArgs {
    readonly clientId: number;
    readonly referenceSequenceNumber: number;
    readonly sequenceNumber: number;
}

export declare interface IMergeTreeDelta {
    /**
     * Type of this change.
     */
    type: MergeTreeDeltaType;
}

export declare interface IMergeTreeDeltaCallbackArgs<TOperationType extends MergeTreeDeltaOperationTypes = MergeTreeDeltaOperationType> {
    readonly operation: TOperationType;
    readonly deltaSegments: IMergeTreeSegmentDelta[];
}

export declare type IMergeTreeDeltaOp = IMergeTreeInsertMsg | IMergeTreeRemoveMsg | IMergeTreeAnnotateMsg;

export declare interface IMergeTreeDeltaOpArgs {
    /**
     * The group op which contains the operation
     * if there operation is part of a group op.
     */
    readonly groupOp?: IMergeTreeGroupMsg;
    /**
     * The merge tree operation
     */
    readonly op: IMergeTreeOp;
    /**
     * Get the sequence message, should only be null if the
     * Delta op args are for an unacked local change
     */
    readonly sequencedMessage?: ISequencedDocumentMessage;
    /**
     * If the operation is being applied as a stashed op, which means it may have been previously submitted, and therefore should not be resubmitted
     */
    readonly stashed?: boolean;
}

/**
 * @deprecated The ability to create group ops will be removed in an upcoming release, as group ops are redundant with the native batching capabilities of the runtime
 */
export declare interface IMergeTreeGroupMsg extends IMergeTreeDelta {
    type: typeof MergeTreeDeltaType.GROUP;
    ops: IMergeTreeDeltaOp[];
}

export declare interface IMergeTreeInsertMsg extends IMergeTreeDelta {
    type: typeof MergeTreeDeltaType.INSERT;
    pos1?: number;
    relativePos1?: IRelativePosition;
    pos2?: number;
    relativePos2?: IRelativePosition;
    seg?: any;
}

export declare interface IMergeTreeMaintenanceCallbackArgs extends IMergeTreeDeltaCallbackArgs<MergeTreeMaintenanceType> {
}

export declare type IMergeTreeOp = IMergeTreeDeltaOp | IMergeTreeGroupMsg;

export declare interface IMergeTreeOptions {
    catchUpBlobName?: string;
    /**
     * Whether or not reference positions can slide to special endpoint segments
     * denoting the positions immediately before the start and immediately after
     * the end of the string.
     *
     * This is primarily useful in the case of interval stickiness.
     *
     * @alpha
     */
    mergeTreeReferencesCanSlideToEndpoint?: boolean;
    mergeTreeSnapshotChunkSize?: number;
    /**
     * Whether to use the SnapshotV1 format over SnapshotLegacy.
     *
     * SnapshotV1 stores a view of the merge-tree at the current sequence number, preserving merge metadata
     * (e.g. clientId, seq, etc.) only for segment changes within the collab window.
     *
     * SnapshotLegacy stores a view of the merge-tree at the minimum sequence number along with the ops between
     * the minimum sequence number and the current sequence number.
     *
     * Both formats merge segments where possible (see {@link ISegment.canAppend})
     *
     * default: false
     *
     * @remarks
     * Despite the "legacy"/"V1" naming, both formats are actively used at the time of writing. SharedString
     * uses legacy and Matrix uses V1.
     */
    newMergeTreeSnapshotFormat?: boolean;
    /**
     * Options related to attribution
     */
    attribution?: IMergeTreeAttributionOptions;
}

export declare interface IMergeTreeRemoveMsg extends IMergeTreeDelta {
    type: typeof MergeTreeDeltaType.REMOVE;
    pos1?: number;
    relativePos1?: IRelativePosition;
    pos2?: number;
    relativePos2?: IRelativePosition;
}

export declare interface IMergeTreeSegmentDelta {
    segment: ISegment;
    propertyDeltas?: PropertySet;
}

export declare interface IMergeTreeTextHelper {
    getText(refSeq: number, clientId: number, placeholder: string, start?: number, end?: number): string;
}

/**
 * @deprecated This functionality is deprecated and will be removed in a future release.
 */
export declare function internedSpaces(n: number): string;

/* Excluded from this release type: IRBAugmentation */

/* Excluded from this release type: IRBMatcher */

declare interface IRefsAtOffset {
    before?: List<LocalReference>;
    at?: List<LocalReference>;
    after?: List<LocalReference>;
}

/**
 * A position specified relative to a segment.
 */
export declare interface IRelativePosition {
    /**
     * String identifier specifying a segment.
     */
    id?: string;
    /**
     * If true, insert before the specified segment.  If false or not defined,
     * insert after the specified segment.
     */
    before?: boolean;
    /**
     * A positive number \>= 1.  If before is false, offset is added to the position.
     * If before is true, offset is subtracted from the position.
     */
    offset?: number;
}

/**
 * Contains removal information associated to an {@link ISegment}.
 */
export declare interface IRemovalInfo {
    /**
     * Local seq at which this segment was removed, if the removal is yet-to-be acked.
     */
    localRemovedSeq?: number;
    /**
     * Seq at which this segment was removed.
     */
    removedSeq: number;
    /**
     * List of client IDs that have removed this segment.
     * The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first
     * client in this list. Other clients in the list have all issued concurrent ops to remove the segment.
     * @remarks When this list has length \> 1, this is referred to as the "overlapping remove" case.
     */
    removedClientIds: number[];
}

/**
 * A segment representing a portion of the merge tree.
 * Segments are leaf nodes of the merge tree and contain data.
 */
export declare interface ISegment extends IMergeNodeCommon, Partial<IRemovalInfo> {
    readonly type: string;
    readonly segmentGroups: SegmentGroupCollection;
    readonly trackingCollection: TrackingGroupCollection;
    /**
     * Whether or not this segment is a special segment denoting the start or
     * end of the tree
     *
     * Endpoint segments are imaginary segments positioned immediately before or
     * after the tree. These segments cannot be referenced by regular operations
     * and exist primarily as a bucket for local references to slide onto during
     * deletion of regular segments.
     */
    readonly endpointType?: "start" | "end";
    /**
     * The length of the contents of the node.
     */
    cachedLength: number;
    /**
     * Stores attribution keys associated with offsets of this segment.
     * This data is only persisted if MergeTree's `attributions.track` flag is set to true.
     * Pending segments (i.e. ones that only exist locally and haven't been acked by the server) also have
     * `attribution === undefined` until ack.
     *
     * Keys can be used opaquely with an IAttributor or a container runtime that provides attribution.
     *
     * @alpha
     *
     * @remarks There are plans to make the shape of the data stored extensible in a couple ways:
     *
     * 1. Injection of custom attribution information associated with the segment (ex: copy-paste of
     * content but keeping the old attribution information).
     *
     * 2. Storage of multiple "channels" of information (ex: track property changes separately from insertion,
     * or only attribute certain property modifications, etc.)
     */
    attribution?: IAttributionCollection<AttributionKey>;
    /**
     * Manages pending local state for properties on this segment.
     */
    propertyManager?: PropertiesManager;
    /**
     * Local seq at which this segment was inserted. If this is defined, `seq` will be UnassignedSequenceNumber.
     * Once the segment is acked, this field is cleared.
     */
    localSeq?: number;
    /**
     * Local seq at which this segment was removed. If this is defined, `removedSeq` will initially be set to
     * UnassignedSequenceNumber. However, if another client concurrently removes the same segment, `removedSeq`
     * will be updated to the seq at which that client removed this segment.
     *
     * Like `localSeq`, this field is cleared once the local removal of the segment is acked.
     */
    localRemovedSeq?: number;
    /**
     * Seq at which this segment was inserted.
     * If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.
     */
    seq?: number;
    /**
     * Short clientId for the client that inserted this segment.
     */
    clientId: number;
    /**
     * Local references added to this segment.
     */
    localRefs?: LocalReferenceCollection;
    /**
     * Properties that have been added to this segment via annotation.
     */
    properties?: PropertySet;
    addProperties(newProps: PropertySet, op?: ICombiningOp, seq?: number, collabWindow?: CollaborationWindow, rollback?: PropertiesRollback): PropertySet | undefined;
    clone(): ISegment;
    canAppend(segment: ISegment): boolean;
    append(segment: ISegment): void;
    splitAt(pos: number): ISegment | undefined;
    toJSONObject(): any;
    /**
     * Acks the current segment against the segment group, op, and merge tree.
     *
     * @param segmentGroup - Pending segment group associated with this op.
     * @param opArgs - Information about the op that was acked
     * @returns `true` if the op modifies the segment, otherwise `false`.
     * The only current false case is overlapping remove, where a segment is removed
     * by a previously sequenced operation before the current operation is acked.
     * @throws - error if the segment state doesn't match segment group or op.
     * E.g. if the segment group is not first in the pending queue, or
     * an inserted segment does not have unassigned sequence number.
     */
    ack(segmentGroup: SegmentGroup, opArgs: IMergeTreeDeltaOpArgs): boolean;
}

export declare interface ISegmentAction<TClientData> {
    (segment: ISegment, pos: number, refSeq: number, clientId: number, start: number, end: number, accum: TClientData): boolean;
}

/**
 * Tests whether x is a MergeTreeDeltaRevertible
 *
 * @alpha
 */
export declare function isMergeTreeDeltaRevertible(x: unknown): x is MergeTreeDeltaRevertible;

export declare interface ITrackingGroup {
    tracked: readonly Trackable[];
    size: number;
    has(trackable: Trackable): boolean;
    link(trackable: Trackable): void;
    unlink(trackable: Trackable): boolean;
}

/* Excluded from this release type: KeyComparer */

declare class List<T> implements Iterable<ListNode<T>>, Partial<ListNodeRange<T>>, Pick<ListNode<T>[], "pop" | "shift" | "length" | "includes"> {
    find(predicate: (value: ListNode<T>, obj: List<T>) => unknown): ListNode<T> | undefined;
    map<U>(callbackfn: (value: ListNode<T>) => U): Iterable<U>;
    insertAfter(preceding: ListNode<T>, ...items: T[]): ListNodeRange<T>;
    pop(): ListNode<T> | undefined;
    push(...items: T[]): ListNodeRange<T>;
    shift(): ListNode<T> | undefined;
    unshift(...items: T[]): ListNodeRange<T>;
    splice(start: ListNode<T>, countOrEnd?: ListNode<T> | number): List<T>;
    includes(node: ListNode<T> | undefined): node is ListNode<T>;
    private _includes;
    private _remove;
    remove(node: ListNode<T> | undefined): ListNode<T> | undefined;
    [Symbol.iterator](): IterableIterator<ListNode<T>>;
    private _len;
    private readonly headNode;
    get length(): number;
    get empty(): boolean;
    get first(): ListNode<T> | undefined;
    get last(): ListNode<T> | undefined;
}

declare interface ListNode<T> {
    readonly list: List<T> | undefined;
    readonly data: T;
    readonly next: ListNode<T> | undefined;
    readonly prev: ListNode<T> | undefined;
}

declare interface ListNodeRange<T> {
    first: ListNode<T>;
    last: ListNode<T>;
}

export declare const LocalClientId = -1;

/* Excluded from this release type: LocalReference */

/**
 * Represents a collection of {@link LocalReferencePosition}s associated with one segment in a merge-tree.
 */
export declare class LocalReferenceCollection {
    /** Segment this `LocalReferenceCollection` is associated to. */
    private readonly segment;
    static append(seg1: ISegment, seg2: ISegment): void;
    /* Excluded from this release type: hierRefCount */
    private readonly refsByOffset;
    private refCount;
    /* Excluded from this release type: __constructor */
    /* Excluded from this release type: [Symbol.iterator] */
    /* Excluded from this release type: clear */
    /* Excluded from this release type: empty */
    /* Excluded from this release type: createLocalRef */
    /* Excluded from this release type: addLocalRef */
    /* Excluded from this release type: removeLocalRef */
    /* Excluded from this release type: append */
    /* Excluded from this release type: has */
    /* Excluded from this release type: split */
    /* Excluded from this release type: addBeforeTombstones */
    /* Excluded from this release type: addAfterTombstones */
    /* Excluded from this release type: isAfterTombstone */
    /* Excluded from this release type: walkReferences */
}

/**
 * @sealed
 */
export declare interface LocalReferencePosition extends ReferencePosition {
    callbacks?: Partial<Record<"beforeSlide" | "afterSlide", (ref: LocalReferencePosition) => void>>;
    readonly trackingCollection: TrackingGroupCollection;
    /**
     * Whether or not this reference position can slide onto one of the two
     * special segments representing the position before or after the tree
     */
    readonly canSlideToEndpoint?: boolean;
}

export declare interface MapLike<T> {
    [index: string]: T;
}

export declare class Marker extends BaseSegment implements ReferencePosition {
    refType: ReferenceType;
    static readonly type = "Marker";
    static is(segment: ISegment): segment is Marker;
    readonly type = "Marker";
    static make(refType: ReferenceType, props?: PropertySet): Marker;
    constructor(refType: ReferenceType);
    toJSONObject(): IJSONMarkerSegment;
    static fromJSONObject(spec: any): Marker | undefined;
    clone(): Marker;
    getSegment(): this;
    getOffset(): number;
    hasSimpleType(simpleTypeName: string): boolean;
    getProperties(): PropertySet | undefined;
    getId(): string | undefined;
    toString(): string;
    protected createSplitSegmentAt(pos: number): undefined;
    canAppend(segment: ISegment): boolean;
    append(): void;
}

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare function matchProperties(a: PropertySet | undefined, b: PropertySet | undefined): boolean;

export declare function maxReferencePosition<T extends ReferencePosition>(a: T, b: T): T;

export declare class MergeNode implements IMergeNodeCommon {
    index: number;
    ordinal: string;
    cachedLength: number;
    isLeaf(): this is ISegment;
}

export declare type MergeTreeDeltaCallback = (opArgs: IMergeTreeDeltaOpArgs, deltaArgs: IMergeTreeDeltaCallbackArgs) => void;

export declare type MergeTreeDeltaOperationType = typeof MergeTreeDeltaType.ANNOTATE | typeof MergeTreeDeltaType.INSERT | typeof MergeTreeDeltaType.REMOVE;

export declare type MergeTreeDeltaOperationTypes = MergeTreeDeltaOperationType | MergeTreeMaintenanceType;

/**
 * @alpha
 */
export declare type MergeTreeDeltaRevertible = {
    operation: typeof MergeTreeDeltaType.INSERT;
    trackingGroup: ITrackingGroup;
} | {
    operation: typeof MergeTreeDeltaType.REMOVE;
    trackingGroup: ITrackingGroup;
} | {
    operation: typeof MergeTreeDeltaType.ANNOTATE;
    trackingGroup: ITrackingGroup;
    propertyDeltas: PropertySet;
};

export declare const MergeTreeDeltaType: {
    readonly INSERT: 0;
    readonly REMOVE: 1;
    readonly ANNOTATE: 2;
    /**
     * @deprecated The ability to create group ops will be removed in an upcoming release, as group ops are redundant with he native batching capabilities of the runtime
     */
    readonly GROUP: 3;
};

export declare type MergeTreeDeltaType = (typeof MergeTreeDeltaType)[keyof typeof MergeTreeDeltaType];

export declare type MergeTreeMaintenanceCallback = (MaintenanceArgs: IMergeTreeMaintenanceCallbackArgs, opArgs: IMergeTreeDeltaOpArgs | undefined) => void;

/**
 * Enum-like constant defining the types of "maintenance" events on a merge tree.
 * Maintenance events correspond to structural segment changes or acks of pending segments.
 *
 * Note: these values are assigned negative integers to avoid clashing with `MergeTreeDeltaType`.
 */
export declare const MergeTreeMaintenanceType: {
    /**
     * Notification that a segment "append" has occurred, i.e. two adjacent segments have been merged.
     * BEWARE: `deltaSegments` on the corresponding event will contain both the merged segment and the latter
     * segment, pre-merge.
     * For example, if the merge tree originally had two adjacent segments [A][B] and called A.append(B) to get
     * segment [AB], `deltaSegments` would contain [AB] and [B].
     */
    readonly APPEND: -1;
    /**
     * Notification that a segment has been split in two.
     * `deltaSegments` on the corresponding event will contain the resulting two segments.
     */
    readonly SPLIT: -2;
    /**
     * Notification that a segment has been unlinked (i.e. removed) from the MergeTree.
     * This occurs on leaf segments during Zamboni when the segment's tracking collection is empty
     * (e.g., not being tracked for undo/redo).
     * It also occurs on internal merge tree segments when re-packing children to maintain tree balancing invariants.
     */
    readonly UNLINK: -3;
    /**
     * Notification that a local change has been acknowledged by the server.
     * This means that it has made the round trip to the server and has had a sequence number assigned.
     */
    readonly ACKNOWLEDGED: -4;
};

export declare type MergeTreeMaintenanceType = (typeof MergeTreeMaintenanceType)[keyof typeof MergeTreeMaintenanceType];

/**
 * @alpha
 */
export declare interface MergeTreeRevertibleDriver {
    insertFromSpec(pos: number, spec: IJSONSegment): any;
    removeRange(start: number, end: number): any;
    annotateRange(start: number, end: number, props: PropertySet): any;
}

export declare function minReferencePosition<T extends ReferencePosition>(a: T, b: T): T;

export declare const NonCollabClient = -2;

export declare class PropertiesManager {
    private pendingKeyUpdateCount;
    private pendingRewriteCount;
    constructor();
    ackPendingProperties(annotateOp: IMergeTreeAnnotateMsg): void;
    private decrementPendingCounts;
    addProperties(oldProps: PropertySet, newProps: PropertySet, op?: ICombiningOp, seq?: number, collaborating?: boolean, rollback?: PropertiesRollback): PropertySet | undefined;
    copyTo(oldProps: PropertySet, newProps: PropertySet | undefined, newManager: PropertiesManager): PropertySet | undefined;
    hasPendingProperties(): boolean;
    hasPendingProperty(key: string): boolean;
}

export declare enum PropertiesRollback {
    /** Not in a rollback */
    None = 0,
    /** Rollback */
    Rollback = 1,
    /** Rollback of a rewrite */
    Rewrite = 2
}

/* Excluded from this release type: Property */

/* Excluded from this release type: PropertyAction */

export declare type PropertySet = MapLike<any>;

/* Excluded from this release type: QProperty */

/**
 * @deprecated This functionality is deprecated and will be removed in a future release.
 */
export declare type RangeStackMap = MapLike<Stack<ReferencePosition>>;

/* Excluded from this release type: RBColor */

/* Excluded from this release type: RBNode */

/* Excluded from this release type: RBNodeActions */

/* Excluded from this release type: RedBlackTree */

/**
 * Represents a reference to a place within a merge tree. This place conceptually remains stable over time
 * by referring to a particular segment and offset within that segment.
 * Thus, this reference's character position changes as the tree is edited.
 */
export declare interface ReferencePosition {
    /**
     * @returns Properties associated with this reference
     */
    properties?: PropertySet;
    /**
     * Defaults to forward
     */
    slidingPreference?: SlidingPreference;
    refType: ReferenceType;
    /**
     * Gets the segment that this reference position is semantically associated with. Returns undefined iff the
     * reference became detached from the string.
     */
    getSegment(): ISegment | undefined;
    /**
     * Gets the offset for this reference position within its associated segment.
     *
     * @example
     *
     * If a merge-tree has 3 leaf segments ["hello", " ", "world"] and a ReferencePosition refers to the "l"
     * in "world", that reference's offset would be 3 as "l" is the character at index 3 within "world".
     */
    getOffset(): number;
    /**
     * @param newProps - Properties to add to this reference.
     * @param op - Combining semantics for changed properties. By default, property changes are last-write-wins.
     * @remarks Note that merge-tree does not broadcast changes to other clients. It is up to the consumer
     * to ensure broadcast happens if that is desired.
     */
    addProperties(newProps: PropertySet, op?: ICombiningOp): void;
    isLeaf(): this is ISegment;
}

/**
 * Flags enum that dictates behavior of a ReferencePosition
 */
export declare enum ReferenceType {
    Simple = 0,
    /**
     * Allows this reference to be located using the `findTile` API on merge-tree.
     */
    Tile = 1,
    /**
     * @deprecated this functionality is no longer supported and will be removed
     */
    NestBegin = 2,
    /**
     * @deprecated this functionality is no longer supported and will be removed
     */
    NestEnd = 4,
    RangeBegin = 16,
    RangeEnd = 32,
    /**
     * When a segment is marked removed (locally or with ack), this reference will slide to the first
     * valid option of:
     * 1. the start of the next furthest segment
     * 2. the end of the next nearest segment
     * 3. DetachedReferencePosition
     */
    SlideOnRemove = 64,
    /**
     * When a segment is marked removed (locally or with ack), this reference will remain on that segment.
     */
    StayOnRemove = 128,
    /**
     * Specifies that the reference position should never be added to the segment it refers to.
     * This is useful for comparison/iteration purposes
     */
    Transient = 256
}

/**
 * @deprecated This functionality is deprecated and will be removed in a future release.
 */
export declare const refGetRangeLabels: (refPos: ReferencePosition) => string[] | undefined;

export declare const refGetTileLabels: (refPos: ReferencePosition) => string[] | undefined;

/**
 * @deprecated This functionality is deprecated and will be removed in a future release.
 */
export declare function refHasRangeLabel(refPos: ReferencePosition, label: string): boolean;

/**
 * @deprecated This functionality is deprecated and will be removed in a future release.
 */
export declare function refHasRangeLabels(refPos: ReferencePosition): boolean;

export declare function refHasTileLabel(refPos: ReferencePosition, label: string): boolean;

export declare function refHasTileLabels(refPos: ReferencePosition): boolean;

export declare function refTypeIncludesFlag(refPosOrType: ReferencePosition | ReferenceType, flags: ReferenceType): boolean;

export declare const reservedMarkerIdKey = "markerId";

export declare const reservedMarkerSimpleTypeKey = "markerSimpleType";

export declare const reservedRangeLabelsKey = "referenceRangeLabels";

export declare const reservedTileLabelsKey = "referenceTileLabels";

/**
 * @alpha
 */
export declare function revertMergeTreeDeltaRevertibles(driver: MergeTreeRevertibleDriver, revertibles: MergeTreeDeltaRevertible[]): void;

export declare interface SegmentAccumulator {
    segments: ISegment[];
}

export declare interface SegmentGroup {
    segments: ISegment[];
    previousProps?: PropertySet[];
    localSeq: number;
    refSeq: number;
}

export declare class SegmentGroupCollection {
    private readonly segment;
    private readonly segmentGroups;
    constructor(segment: ISegment);
    get size(): number;
    get empty(): boolean;
    enqueue(segmentGroup: SegmentGroup): void;
    dequeue(): SegmentGroup | undefined;
    pop?(): SegmentGroup | undefined;
    copyTo(segment: ISegment): void;
    private enqueueOnCopy;
}

/* Excluded from this release type: SequenceOffsets */

/* Excluded from this release type: SerializedAttributionCollection */

/**
 * Dictates the preferential direction for a {@link ReferencePosition} to slide
 * in a merge-tree
 */
export declare const SlidingPreference: {
    /**
     * Prefer sliding towards the start of the tree
     */
    readonly BACKWARD: 0;
    /**
     * Prefer sliding towards the end of the tree
     */
    readonly FORWARD: 1;
};

/**
 * Dictates the preferential direction for a {@link ReferencePosition} to slide
 * in a merge-tree
 */
export declare type SlidingPreference = (typeof SlidingPreference)[keyof typeof SlidingPreference];

/* Excluded from this release type: SortedDictionary */

/**
 * Stores a unique and sorted set of segments, or objects with segments
 *
 * This differs from a normal sorted set in that the keys are not fixed.
 * The segments are sorted via their ordinals which can change as the merge tree is modified.
 * Even though the values of the ordinals can change their ordering and uniqueness cannot, so the order of a set of
 * segments ordered by their ordinals will always have the same order even if the ordinal values on
 * the segments changes. This invariant allows us to ensure the segments stay
 * ordered and unique, and that new segments can be inserted into that order.
 */
export declare class SortedSegmentSet<T extends SortedSegmentSetItem = ISegment> extends SortedSet<T, string> {
    protected getKey(item: T): string;
    protected findItemPosition(item: T): {
        exists: boolean;
        index: number;
    };
}

export declare type SortedSegmentSetItem = ISegment | LocalReferencePosition | {
    readonly segment: ISegment;
};

export declare abstract class SortedSet<T, U extends string | number> {
    protected abstract getKey(t: T): U;
    protected readonly keySortedItems: T[];
    get size(): number;
    get items(): readonly T[];
    addOrUpdate(newItem: T, update?: (existingItem: T, newItem: T) => void): void;
    remove(item: T): boolean;
    has(item: T): boolean;
    protected findItemPosition(item: T): {
        exists: boolean;
        index: number;
    };
}

/**
 * @deprecated This functionality was not intended for public export and will
 * be removed in a future release.
 */
export declare class Stack<T> {
    items: T[];
    push(val: T): void;
    empty(): boolean;
    top(): T | undefined;
    pop(): T | undefined;
}

export declare class TextSegment extends BaseSegment {
    text: string;
    static readonly type = "TextSegment";
    static is(segment: ISegment): segment is TextSegment;
    static make(text: string, props?: PropertySet): TextSegment;
    static fromJSONObject(spec: any): TextSegment | undefined;
    readonly type = "TextSegment";
    constructor(text: string);
    toJSONObject(): string | {
        text: string;
        props: PropertySet;
    };
    clone(start?: number, end?: number): TextSegment;
    canAppend(segment: ISegment): boolean;
    toString(): string;
    append(segment: ISegment): void;
    removeRange(start: number, end: number): boolean;
    protected createSplitSegmentAt(pos: number): TextSegment | undefined;
}

export declare function toRemovalInfo(maybe: Partial<IRemovalInfo> | undefined): IRemovalInfo | undefined;

export declare type Trackable = ISegment | LocalReferencePosition;

export declare class TrackingGroup implements ITrackingGroup {
    private readonly trackedSet;
    constructor();
    get tracked(): readonly Trackable[];
    get size(): number;
    has(trackable: Trackable): boolean;
    link(trackable: Trackable): void;
    unlink(trackable: Trackable): boolean;
}

export declare class TrackingGroupCollection {
    private readonly trackable;
    private readonly _trackingGroups;
    get trackingGroups(): Set<TrackingGroup>;
    constructor(trackable: Trackable);
    link(trackingGroup: ITrackingGroup): void;
    unlink(trackingGroup: ITrackingGroup): boolean;
    copyTo(trackable: Trackable): void;
    get empty(): boolean;
    matches(trackingCollection: TrackingGroupCollection): boolean;
}

export declare const TreeMaintenanceSequenceNumber = -2;

/* Excluded from this release type: TypedEventEmitter */

export declare const UnassignedSequenceNumber = -1;

/**
 * Sequence numbers for shared segments start at 1 or greater.  Every segment marked
 * with sequence number zero will be counted as part of the requested string.
 */
export declare const UniversalSequenceNumber = 0;

export { }
