Fast, openpyxl-compatible Excel I/O with Rust backend and built-in formula engine (35 functions, VLOOKUP, SUMIF, INDEX/MATCH)
Project description
WolfXL
The fastest openpyxl-compatible Excel library for Python.
Drop-in replacement backed by Rust — up to 5x faster with zero code changes.
Replaces openpyxl. One import change.
- from openpyxl import load_workbook, Workbook
- from openpyxl.styles import Font, PatternFill, Alignment, Border
+ from wolfxl import load_workbook, Workbook, Font, PatternFill, Alignment, Border
Your existing code works as-is. Same ws["A1"].value, same Font(bold=True), same wb.save().
Measured with ExcelBench on Apple M1 Pro, Python 3.12, median of 3 runs.
Install
pip install wolfxl
Quick Start
from wolfxl import load_workbook, Workbook, Font, PatternFill
# Write a styled spreadsheet
wb = Workbook()
ws = wb.active
ws["A1"].value = "Product"
ws["A1"].font = Font(bold=True, color="FFFFFF")
ws["A1"].fill = PatternFill(fill_type="solid", fgColor="336699")
ws["A2"].value = "Widget"
ws["B2"].value = 9.99
wb.save("report.xlsx")
# Read it back — styles included
wb = load_workbook("report.xlsx")
ws = wb[wb.sheetnames[0]]
for row in ws.iter_rows(values_only=False):
for cell in row:
print(cell.coordinate, cell.value, cell.font.bold)
wb.close()
Three Modes
| Mode | Usage | Engine | What it does |
|---|---|---|---|
| Read | load_workbook(path) |
calamine-styles | Parse XLSX with full style extraction |
| Write | Workbook() |
rust_xlsxwriter | Create new XLSX files from scratch |
| Modify | load_workbook(path, modify=True) |
XlsxPatcher | Surgical ZIP patch — only changed cells are rewritten |
Modify mode preserves everything it doesn't touch: charts, macros, images, pivot tables, VBA.
Supported Features
| Category | Features |
|---|---|
| Data | Cell values (string, number, date, bool), formulas, hyperlinks, comments |
| Styling | Font (bold, italic, underline, color, size), fills, borders, number formats, alignment |
| Structure | Multiple sheets, merged cells, named ranges, freeze panes, tables |
| Advanced | Data validation, conditional formatting |
Performance at Scale
| Scale | File size | WolfXL Read | openpyxl Read | WolfXL Write | openpyxl Write |
|---|---|---|---|---|---|
| 100K cells | 400 KB | 0.11s | 0.42s | 0.06s | 0.28s |
| 1M cells | 3 MB | 1.1s | 4.0s | 0.9s | 2.9s |
| 5M cells | 25 MB | 6.0s | 20.9s | 3.2s | 15.5s |
| 10M cells | 45 MB | 13.0s | 47.8s | 6.7s | 31.8s |
Throughput stays flat as files grow — no hidden O(n^2) pathology.
How WolfXL Compares
Every Rust-backed Python Excel project picks a different slice of the problem. WolfXL is the only one that covers all three: formatting, modify mode, and openpyxl API compatibility.
| Library | Read | Write | Modify | Styling | openpyxl API |
|---|---|---|---|---|---|
| fastexcel | Yes | — | — | — | — |
| python-calamine | Yes | — | — | — | — |
| FastXLSX | Yes | Yes | — | — | — |
| rustpy-xlsxwriter | — | Yes | — | Partial | — |
| WolfXL | Yes | Yes | Yes | Yes | Yes |
- Styling = reads and writes fonts, fills, borders, alignment, number formats
- Modify = open an existing file, change cells, save back — without rebuilding from scratch
- openpyxl API = same
load_workbook,Workbook,Cell,Font,PatternFillobjects
Upstream calamine does not parse styles. WolfXL's read engine uses calamine-styles, a fork that adds Font/Fill/Border/Alignment/NumberFormat extraction from OOXML.
Batch APIs for Maximum Speed
For write-heavy workloads, use append() or write_rows() instead of cell-by-cell access. These APIs buffer rows as raw Python lists and flush them to Rust in a single call at save time, bypassing per-cell FFI overhead entirely.
from wolfxl import Workbook
wb = Workbook()
ws = wb.active
# append() — fast sequential writes (3.7x faster than cell-by-cell)
ws.append(["Name", "Amount", "Date"])
for row in data:
ws.append(row)
# write_rows() — fast writes at arbitrary positions
ws.write_rows(header_grid, start_row=1, start_col=1)
ws.write_rows(data_grid, start_row=5, start_col=1)
wb.save("output.xlsx")
For reads, iter_rows(values_only=True) uses a fast bulk path that reads all values in a single Rust call (6.7x faster than openpyxl):
wb = load_workbook("data.xlsx")
ws = wb[wb.sheetnames[0]]
for row in ws.iter_rows(values_only=True):
process(row) # row is a tuple of plain Python values
| API | vs openpyxl | How |
|---|---|---|
ws.append(row) |
3.7x faster write | Buffers rows, single Rust call at save |
ws.write_rows(grid) |
3.7x faster write | Same mechanism, arbitrary start position |
ws.iter_rows(values_only=True) |
6.7x faster read | Single Rust call, no Cell objects |
ws.cell(r, c, value=v) |
1.6x faster write | Per-cell FFI (compatible but slower) |
Case Study: SynthGL
SynthGL switched from openpyxl to WolfXL for their GL journal exports (14-column financial data, 1K-50K rows). Results: 4x faster writes, 9x faster reads at scale. 50K-row exports dropped from 7.6s to 1.3s. Read the full case study.
How It Works
WolfXL is a thin Python layer over compiled Rust engines, connected via PyO3. The Python side uses lazy cell proxies — opening a 10M-cell file is instant. Values and styles are fetched from Rust only when you access them. On save, dirty cells are flushed in one batch, avoiding per-cell FFI overhead.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wolfxl-0.2.1.tar.gz.
File metadata
- Download URL: wolfxl-0.2.1.tar.gz
- Upload date:
- Size: 224.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0fc56ba9c6dc9b1aa7c7022fb29f35f67a4bd2baf40ec9f36f3e3a164a5cc24
|
|
| MD5 |
e8b4a9dd00702dbe5ec967f7dd5d3972
|
|
| BLAKE2b-256 |
c4b30f870e73c783c65e0732d72ca8d4917f46966198220a4cb44be7ca38eeb9
|
File details
Details for the file wolfxl-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5295df5a17ce39da9a4737110f48e7308560d7d71bfe20962b00335b9a388415
|
|
| MD5 |
8ad894692289618d7638767a15bf13d2
|
|
| BLAKE2b-256 |
ad1f0ad31f0308b02108ab59c8cee9dd6437b8a75c0b2a6a87b7aaf924dcbac0
|
File details
Details for the file wolfxl-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.13, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01a3f6c1a2b429495db35924e824cad6c5f8a72d6912a9ace36e7a651d892160
|
|
| MD5 |
81773f7480ca034fa6b7df61bdbd9f6f
|
|
| BLAKE2b-256 |
ec89c8723007731b405d752dcce49954f3d7e19e766e982f9a9a5ea84f085fcb
|
File details
Details for the file wolfxl-0.2.1-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa62df469fbf89a26fc1c1388ad0eac15225152a759337ba1cdf21c0af510208
|
|
| MD5 |
80e71cb238a769eb58725bf51638af21
|
|
| BLAKE2b-256 |
2de869801330b0fa3c5ce441311f0c37ca8a26920d210000471e9a4c5a4d3a2d
|
File details
Details for the file wolfxl-0.2.1-cp313-cp313-macosx_10_12_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp313-cp313-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.13, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69baf3ec2f1516998cb41d4e35a7cb0689dbebedb1b881dfc0ee2bfc12ec1e43
|
|
| MD5 |
edcb1983ff855051eaed31e3e16236aa
|
|
| BLAKE2b-256 |
042a28877de058fb7ed78b7d2aad98a0f61e7a81aed0a7c49335746a4369292b
|
File details
Details for the file wolfxl-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcb1e443e1de6c01fa9ce32d8bc3e1f9a4d6b9acb59b140fb45fc501d4cae8e0
|
|
| MD5 |
0cd7d99a758f6b33eac7917eee82d9d0
|
|
| BLAKE2b-256 |
f8d54f020a407990b40600a312f192cc55bbb7797013f70fde4053a02750c3b6
|
File details
Details for the file wolfxl-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2818dd1369673400b31fbe8c6776bdf4db73cac15c888952e3d1ce184ca70e88
|
|
| MD5 |
5a74a5c836ecdf889bae28371080b4cd
|
|
| BLAKE2b-256 |
8c4f66bf0537d6e91ab03c4f0bf39f51e2b71aa1318f826b67fd88a005eb1020
|
File details
Details for the file wolfxl-0.2.1-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a063cec151c56903f1a984dd0adb78e30a1b4e268407a0feb5d2b7a3dc346ec
|
|
| MD5 |
77ed46ed8d9c60e315f7ee0b33ced790
|
|
| BLAKE2b-256 |
d521944f3813f25721abec27949fdefc8eb3b57364f9e6c60b0f78d7b0778f64
|
File details
Details for the file wolfxl-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a42a766469f3d31b3ebe9de763b6707973b8d621123efc14d2c27a5e209df562
|
|
| MD5 |
cf246d4e63b450eb3e5effc0b73b043f
|
|
| BLAKE2b-256 |
657e942998a781a7c95b42eb9942ee4ae22adbedcf1b7ec92ac2c2c813875949
|
File details
Details for the file wolfxl-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9778f8a47ec06d8f488396e145d6b082a0fbe67d9d1883802fbad5da058ec7db
|
|
| MD5 |
024c7f4dfe53b631b937b08439e416c8
|
|
| BLAKE2b-256 |
833dacd4de92eb07359124d808379d7580608cb5db0645396185bb93a92902cd
|
File details
Details for the file wolfxl-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66b8875cd993f8f11bae553f6589d70ede80c8c774d5a7e4f0b122336e7dae3d
|
|
| MD5 |
d58358a4b0b99e7d53ba0d74a291b34f
|
|
| BLAKE2b-256 |
b34268f782c1ecf072d2bc9eb2ab952ae4b1aed051a806b20a0e6a340de94878
|
File details
Details for the file wolfxl-0.2.1-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40dc8f97f31ce6397921181b104bbb2e9f16038f118b9bad9dce4ca765cff628
|
|
| MD5 |
bb332a7cad20bbdf4b2492c8f6e17c51
|
|
| BLAKE2b-256 |
d6e1c73a722140c20f205ee34c30f5049c8b897ac8d20ddb76b26a7cfdbc41df
|
File details
Details for the file wolfxl-0.2.1-cp311-cp311-macosx_10_12_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp311-cp311-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.11, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb4f0ac9b06a1484d0b9d4c8c42081e73c77f999e9899362864b66c995d24384
|
|
| MD5 |
77d5f343cad90a89bf9736ea92feb2ac
|
|
| BLAKE2b-256 |
9519b25dc0a810a9ca4584a5933c2c635398009282a7a16e7b2517293b9ed1ea
|
File details
Details for the file wolfxl-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da3e7e88f4623367e00cd445b48989e949a22ded0a812b9d4b463527b0d72e66
|
|
| MD5 |
11429e9a119a0ea84c7d192c55616eaa
|
|
| BLAKE2b-256 |
dd299fdc76c02832cc7b13acfcdf6c01fd5f3e5b0a00848947e183ff8f22edc6
|
File details
Details for the file wolfxl-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.10, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c89a4a73b2bbb1f645a9f644ce8c0c2beb11e97c849e6f4a912a72757ec2e1c7
|
|
| MD5 |
827104570a2cc3de2b8c40fe67b1e0ed
|
|
| BLAKE2b-256 |
6b3ad6e8c18b34b34fb00dc114887048831efb72aab36f27494f641b2c64002b
|
File details
Details for the file wolfxl-0.2.1-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
307201a1979f7dfdf1fb2cc9b1faca93d04e321295d303285dbbd57cd91637aa
|
|
| MD5 |
251ffee4db78d3da07d7ed47ad5144a7
|
|
| BLAKE2b-256 |
94f2b322b9bbee59b68c5724795c3a34861b9381a0f74188a51fe55c4022259a
|
File details
Details for the file wolfxl-0.2.1-cp310-cp310-macosx_10_12_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp310-cp310-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.10, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b477dfc23fbdf0b9f048d35215fcc311ed28fbae0554b98f0ae080062cafe4b
|
|
| MD5 |
c4a6d5699aa3f2526acd0bf7cefda476
|
|
| BLAKE2b-256 |
7771b5d26ce1d1ef32261deeeca879830afd3277793c97f69f7f219d699e17f5
|
File details
Details for the file wolfxl-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.9, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a31acb6d5c6657e104dd10c5ae4fcde8d4ad677cc333e79ea3f87549994cf02
|
|
| MD5 |
41ac948bcbb8e29cdbbb9ee4c507d06d
|
|
| BLAKE2b-256 |
c485af446c1c744013a41566c0d9ceba8e93b75faa16bc2fe4ccb973e40e4234
|
File details
Details for the file wolfxl-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.9, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
20d73de59dadbf48ea2151ae08c5e728af05eea17f11c237a3d59cfd70b9f1ca
|
|
| MD5 |
7f092496cf3f7554be3f2fe5ec2f94f6
|
|
| BLAKE2b-256 |
fb15fc500ea1924ef6b605c1dca1ab1a5bc769af9c62758761aa44a28858ae2b
|
File details
Details for the file wolfxl-0.2.1-cp39-cp39-macosx_11_0_arm64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp39-cp39-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.9, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8de55dfa8fa72e56e53a24eed72cbdc6cf89a7d7882058af0039da118dcb42b
|
|
| MD5 |
b5c62c73ea602a64fa9f4cdfd7d78b59
|
|
| BLAKE2b-256 |
180355b3fc60f3d58deee56c354eea2ab3ff356a0cb52c358d35f04746dc32ef
|
File details
Details for the file wolfxl-0.2.1-cp39-cp39-macosx_10_12_x86_64.whl.
File metadata
- Download URL: wolfxl-0.2.1-cp39-cp39-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.9, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0ccd23b381cd1c242c1262c3eb0300bb6c621199d66a99d1ea31a501064ea7a
|
|
| MD5 |
74750890d98f7fe7123273f00fde8705
|
|
| BLAKE2b-256 |
00ff2d643bba2c86fe3bbfd878cdc41c65b10dc7d8315238a18be7964bbc3b82
|