Inspector for IWA archives (Keynote, Numbers, Pages) https://sheetjs.com/tools/iwa-inspector
Go to file
2023-09-24 02:05:06 -04:00
misc release 2023-05-16 21:56:27 -04:00
patches mobile 2023-05-17 20:39:46 -04:00
public iwa 13.2 2023-09-24 02:05:06 -04:00
src iwa 13.2 2023-09-24 02:05:06 -04:00
.eslintrc.cjs release 2023-05-16 21:56:27 -04:00
.gitignore release 2023-05-16 21:56:27 -04:00
index.html mobile 2023-05-17 20:39:46 -04:00
Makefile mobile 2023-05-17 20:39:46 -04:00
package.json README 2023-07-25 20:12:12 -04:00
README.md iwa 13.2 2023-09-24 02:05:06 -04:00
tsconfig.json release 2023-05-16 21:56:27 -04:00
tsconfig.node.json release 2023-05-16 21:56:27 -04:00
types.ts release 2023-05-16 21:56:27 -04:00
vite.config.ts release 2023-05-16 21:56:27 -04:00

iwa-inspector

source for https://sheetjs.com/tools/iwa-inspector

iwa-inspector is a tool for inspecting iWork archives.

https://oss.sheetjs.com/notes/iwa/ covers the high-level structure of files. This inspector performs the top-level extraction of messages and parses using extracted Protocol Buffer definitions.

Usage

The sections are separated by a light gray horizontal line and a light gray vertical line. Panels can be resized by click-dragging the line.

Selecting a File

The file input element in the top-left corner of the page is limited to the IWA file types: .numbers, .key, and .pages.

The site automatically fetches a sample file on load.

Message Table

The message table is shown just below the header bar. The column headers are:

name description
id Message ID
type Numeric Message Type
message Absolute Message Type
path Location of Message

The table can be sorted by clicking on the column headers.

Searching for Messages

The search text box in the top-right corner of the page is a plaintext search over the parsed messages. Searches will match field names, string values and UUID fields of message type .TSP.UUID.

Selecting a Message

When a row in the table is selected, the bottom-left panel will display the Protocol Buffers definition for the message and the bottom-right panel will display the parsed contents.

Message Structure

The bottom-right panel shows the following information:

  • "Message": parsed information following the message definition
  • "Metadata": parsed information from the message metadata
  • "Dependents": list of messages that list the current message as a dependency.

Clicking on a message name in the inspector will show the message definition in the left pane. A "Return" link returns to the base message definition.

Clicking on a .TSP.Reference ID will jump to the referenced message.

Exporting Data

Right-clicking a custom message type will show a context menu with options to copy the raw byte representation (array of numbers) or parsed object (JSON).

Development

make dev starts the dev server.

make build generates the static site.

Refreshing Protos and Messages

make deps requires a SIP-disabled Intel Mac with Keynote + Numbers + Pages.

The last run was on 2023-09-24 against version 13.2 (7038.0.87)

Each app should be run at least once before refreshing artifacts.

Developer Tools error

Note: Runs may fail with an error like

error: Uncaught (in promise) "Could not find map!"

Developer tools permissions must be granted. Running the command a second time typically shows a popup asking for Touch ID or password. After authorization, the build should run successfully.

Protocol Buffer Details

Note that the message field is absolute. For example, TSTArchives.proto specifies the .TST.TileStorage as follows:

package TST;

message TileStorage {
  message Tile {
    required uint32 tileid = 1;
    required .TSP.Reference tile = 2;
  }
  repeated .TST.TileStorage.Tile tiles = 1;
  optional uint32 tile_size = 2;
  optional bool should_use_wide_rows = 3;
}

The protobuf extractor rewrites the message names using the absolute form:

message .TST.TileStorage {
  message Tile {
    required uint32 tileid = 1;
    required .TSP.Reference tile = 2;
  }
  repeated .TST.TileStorage.Tile tiles = 1;
  optional uint32 tile_size = 2;
  optional bool should_use_wide_rows = 3;
}