Z ZPI 文档 v0.3.8
介绍页

源码

packages/desktop/src/renderer/presentation/reference.ts

typescript43 行查看原文
import type { ConversationSelection } from "@zpi-dev/ui";
import type { PresentationPageElement } from "./types.ts";

export async function fingerprintPresentationBytes(bytes: Uint8Array): Promise<string> {
  const digest = await crypto.subtle.digest("SHA-256", new Uint8Array(bytes));
  return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
}

/** Preserve exact OOXML identity and original fingerprints in the existing removable context wire format. */
export async function createPresentationSelection(options: {
  path: string;
  bytes: Uint8Array;
  element: PresentationPageElement;
  comment: string;
  selectedText?: string;
}): Promise<ConversationSelection> {
  const { path, bytes, element, comment } = options;
  const reference = {
    sourcePath: path,
    sourceFingerprint: await fingerprintPresentationBytes(bytes),
    slideIndex: element.slideIndex,
    slidePart: element.slidePart,
    nodeId: element.nodeId,
    nodePath: element.nodePath,
    nodeType: element.nodeType,
    rowIndex: element.rowIndex,
    cellIndex: element.cellIndex,
    bounds: element.bounds,
    text: element.text ?? "",
    textFingerprint: await fingerprintPresentationBytes(new TextEncoder().encode(element.text ?? "")),
    selectedText: options.selectedText ?? element.text ?? "",
    comment: comment.trim(),
  };
  return {
    id: crypto.randomUUID(),
    path,
    sourceTitle: `${path.split(/[\\/]/).at(-1)} · 第 ${element.slideIndex + 1} 页`,
    sourceKey: `${path}:${element.slidePart}:${element.nodeId}:${element.rowIndex ?? ""}:${element.cellIndex ?? ""}`,
    contentType: "tool",
    text: `Presentation element comment (apply this comment only to this element):\n${JSON.stringify(reference, null, 2)}`,
  };
}