Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
530 changes: 138 additions & 392 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"devDependencies": {
"@biomejs/biome": "^2.2.4",
"@biomejs/biome": "^2.3.1",
"@eslint/js": "^9.18.0",
"husky": "^9.1.7",
"lint-staged": "^15.4.1"
Expand Down
92 changes: 92 additions & 0 deletions playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# 🎮 Interactive Playground Snippets

> **Try these examples instantly in your browser** - No setup, no installation required!

These are ready-to-run code snippets for the [Nutrient Web SDK](https://www.nutrient.io/web-sdk/) that you can open directly in the [Nutrient Playground](https://www.nutrient.io/playground). Each example demonstrates a specific feature with working code you can experiment with immediately.

## 🚀 How to Use

1. Click any example link below
2. The Nutrient Playground opens with the code pre-loaded
3. Modify the code and see changes instantly
4. Copy the code into your own project

---

## 📋 Example Categories

### 🎨 Annotations
[**View Annotations Examples**](./web-annotations.md) — Add, customize, and manage PDF annotations including watermarks, highlighting, and bulk operations.

**Popular examples:**
- Watermark from text annotation
- Flatten annotation on creation
- Bulk delete all annotations
- Straighten freeform highlights

---

### 🔒 Redaction
[**View Redaction Examples**](./web-redaction.md) — Permanently remove sensitive content from PDFs.

---

### ✍️ Signing
[**View Signing Examples**](./web-signing.md) — Electronic and digital signatures for PDF documents.

---

### 📝 Forms
[**View Forms Examples**](./web-forms.md) — PDF form filling and management.

---

### 🎨 Form Creator
[**View Form Creator Examples**](./web-form-creator.md) — Create and customize interactive PDF forms.

---

### 👁️ Viewer
[**View Viewer Examples**](./web-viewer.md) — PDF viewing, navigation, and display customization.

---

### 📄 Document Editor
[**View Document Editor Examples**](./web-document-editor.md) — Page manipulation, extraction, and editing.

---

### 💬 Comments
[**View Comments Examples**](./web-comments.md) — Collaborative commenting workflows.

---

### ✏️ Content Editor
[**View Content Editor Examples**](./web-content-editor.md) — Direct PDF content editing capabilities.

---

### 🎛️ Toolbars & Menus
[**View Toolbars & Menus Examples**](./web-toolbars-menus.md) — UI customization and toolbar configuration.

---

### 🔍 Text Comparison
[**View Text Comparison Examples**](./web-text-comparison.md) — Compare document versions and track changes.

---

## 💻 Want More?

- **Full Projects**: For complete, runnable applications, see [/web](../../web) directory
- **Framework Integration**: [React](https://github.com/PSPDFKit/nutrient-web-examples/tree/main/examples/react), [Angular](https://github.com/PSPDFKit/nutrient-web-examples/tree/main/examples/angular), [Next.js](https://github.com/PSPDFKit/nutrient-web-examples/tree/main/examples/nextjs)
- **Documentation**: [Nutrient Guides](https://www.nutrient.io/guides/)
- **API Reference**: [Web SDK API](https://www.nutrient.io/api/web/)

---

## 🤝 Need Help?

- [Discord Community](https://discord.gg/Z754Pfb8bD)
- [Support Portal](https://support.nutrient.io/hc/en-us/requests/new)
- [Report Issues](https://github.com/PSPDFKit/awesome-nutrient/issues)
101 changes: 101 additions & 0 deletions playground/web-annotations.md

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions playground/web-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Web SDK Examples: Comments

> These are interactive Nutrient Playground examples. Click any link to try the code in your browser.
>
> For local runnable examples, see [web/annotation/README.md](../web/annotation/README.md).

---

## Comments

- [Set annotation creator name](https://www.nutrient.io/playground?p=eyJ2IjoxLCJzZXR0aW5ncyI6eyJmaWxlTmFtZSI6ImJhc2ljLnBkZiIsImp3dCI6eyJwZXJtaXNzaW9ucyI6WyJyZWFkLWRvY3VtZW50Iiwid3JpdGUiXSwidXNlcklkIjoicmFuZG9tbEUxUXUwYzdjVCIsImxheWVyIjoicmFuZG9ta1FnUzRqOEpySCJ9fSwianMiOiIvL3NldCB1c2VyIG5hbWUgZnJvbSBhIGxvZ2luIG9yIGF1dGhlbnRpY2F0aW9uXG5jb25zdCB1c2VybmFtZSA9IFwiSm9obiBTbWl0aFwiO1xuUFNQREZLaXQubG9hZCh7XG4gIC4uLmJhc2VPcHRpb25zLFxuICB0aGVtZTogUFNQREZLaXQuVGhlbWUuREFSSyxcbiAgdG9vbGJhckl0ZW1zOiBbeyB0eXBlOiBcImNvbW1lbnRcIiB9XSxcbn0pLnRoZW4oKGluc3RhbmNlKSA9PiB7XG4gIGluc3RhbmNlLnNldEFubm90YXRpb25DcmVhdG9yTmFtZShcIkpvaG4gU21pdGhcIik7XG59KTtcbiIsIm1vZGUiOiJzdGFuZGFsb25lIiwiY3NzIjoiLyogQWRkIHlvdXIgQ1NTIGhlcmUgKi9cbiJ9)
- Set an annotation creator’s name, ensuring any annotations — including comments — made by that user are attributed to them. — [Video](https://www.youtube.com/watch?v=1VJzTbdY_F0)

- [Link comments with annotations](https://github.com/PSPDFKit/awesome-pspdfkit/tree/master/web/annotation/comment-annotations)

- [Add custom buttons for customizing comments](https://github.com/PSPDFKit/awesome-pspdfkit/tree/master/web/annotation/comments-status)
- Customize the comments popover by adding custom actions, like approve and reject, allowing users to manage comments efficiently. — [Video](https://www.youtube.com/watch?v=lVbuW7gMuVg)

- [Clean up empty comment threads and highlights](https://www.nutrient.io/playground?p=eyJ2IjoxLCJqcyI6Ii8vIENsZWFuIFVwIEVtcHR5IENvbW1lbnQgVGhyZWFkcyBhbmQgSGlnaGxpZ2h0c1xubGV0IG9ic2VydmVyID0gbnVsbDtcbmxldCBoYXNCZWVuRWRpdGVkID0gZmFsc2U7XG5cbk51dHJpZW50Vmlld2VyLmxvYWQoe1xuXHQuLi5iYXNlT3B0aW9ucyxcblx0dGhlbWU6IE51dHJpZW50Vmlld2VyLlRoZW1lLkRBUkssXG5cdHRvb2xiYXJJdGVtczogW1xuXHRcdC4uLk51dHJpZW50Vmlld2VyLmRlZmF1bHRUb29sYmFySXRlbXMsXG5cdFx0eyB0eXBlOiBcImNvbW1lbnRcIiB9LFxuXHRdLFxuXHR1aToge1xuXHRcdGNvbW1lbnRUaHJlYWQ6IHtcblx0XHRcdGVkaXRvcjogKGluc3RhbmNlLCB0aHJlYWRJZCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdHJlbmRlcjogKHBhcmFtcykgPT4ge1xuXHRcdFx0XHRcdFx0Ly8gVXNlIGRlZmF1bHQgZWRpdG9yIFVJIGJ5IHJldHVybmluZyBudWxsXG5cdFx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdG9uTW91bnQ6IChyb290SWQpID0%252BIHtcblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKGBIZWFkZXIgbW91bnRlZCB3aXRoIHJvb3RJZDogJHtyb290SWR9YCk7XG5cblx0XHRcdFx0XHRcdC8vIEVuc3VyZSBhIHNpbmdsZSBvYnNlcnZlciBpbnN0YW5jZSBwZXIgdmlld2VyIGluc3RhbmNlXG5cdFx0XHRcdFx0XHRpZiAoIW9ic2VydmVyKSB7XG5cdFx0XHRcdFx0XHRcdG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKG11dGF0aW9ucykgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdGZvciAoY29uc3QgbXV0YXRpb24gb2YgbXV0YXRpb25zKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRsZXQgY29udGFpbmVyO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKG11dGF0aW9uLnR5cGUgPT09IFwiY2hhcmFjdGVyRGF0YVwiKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZvciB0ZXh0IG5vZGVzLCB1c2UgcGFyZW50RWxlbWVudCB0byBnZXQgdG8gdGhlIGVsZW1lbnRcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29udGFpbmVyID0gbXV0YXRpb24udGFyZ2V0Py5wYXJlbnRFbGVtZW50Py5jbG9zZXN0Py4oXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YC5CYXNlbGluZVVJLUVkaXRvci1SaWNoRWRpdG9yRWRpdGluZ0FyZWFgXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgZWxlbWVudCBub2RlcywgdXNlIGNsb3Nlc3QgZGlyZWN0bHlcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29udGFpbmVyID0gbXV0YXRpb24udGFyZ2V0Py5jbG9zZXN0Py4oXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YC5CYXNlbGluZVVJLUVkaXRvci1SaWNoRWRpdG9yRWRpdGluZ0FyZWFgXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdGlmIChjb250YWluZXIpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29uc3QgdGV4dENvbnRlbnQgPSBjb250YWluZXIudGV4dENvbnRlbnQ%252FLnRyaW0oKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29uc3QgaGFzUmVhbENvbnRlbnQgPVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCEhdGV4dENvbnRlbnQgJiYgIXRleHRDb250ZW50LmluY2x1ZGVzKFwiQWRkIHlvdXIgY29tbWVudFwiKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aGFzQmVlbkVkaXRlZCA9IGhhc1JlYWxDb250ZW50O1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIkVkaXRvciBzdGF0ZTpcIixcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRoYXNSZWFsQ29udGVudCA%252FIFwiaGFzIGNvbnRlbnRcIiA6IFwiZW1wdHlcIlxuXHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBGaW5kIHRoZSBjb3JyZWN0IGVkaXRvciBjb250YWluZXIgZm9yIHRoaXMgdGhyZWFkLCBwcmVmZXIgc2NvcGVkIHNlbGVjdG9yXG5cdFx0XHRcdFx0XHRjb25zdCBjb250YWluZXIgPVxuXHRcdFx0XHRcdFx0XHRpbnN0YW5jZS5jb250ZW50RG9jdW1lbnQucXVlcnlTZWxlY3Rvcihcblx0XHRcdFx0XHRcdFx0XHRgW2RhdGEtcm9vdC1pZD1cIiR7cm9vdElkfVwiXSAuQmFzZWxpbmVVSS1FZGl0b3ItUmljaEVkaXRvckVkaXRpbmdBcmVhYFxuXHRcdFx0XHRcdFx0XHQpIHx8XG5cdFx0XHRcdFx0XHRcdGluc3RhbmNlLmNvbnRlbnREb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuXHRcdFx0XHRcdFx0XHRcdGAuQmFzZWxpbmVVSS1FZGl0b3ItUmljaEVkaXRvckVkaXRpbmdBcmVhYFxuXHRcdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRpZiAoY29udGFpbmVyKSB7XG5cdFx0XHRcdFx0XHRcdG9ic2VydmVyLm9ic2VydmUoY29udGFpbmVyLCB7XG5cdFx0XHRcdFx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLCAgICAgICAgLy8gV2F0Y2ggZm9yIGFkZGVkL3JlbW92ZWQgY2hpbGQgbm9kZXNcblx0XHRcdFx0XHRcdFx0XHRhdHRyaWJ1dGVzOiB0cnVlLCAgICAgICAgLy8gV2F0Y2ggZm9yIGF0dHJpYnV0ZSBjaGFuZ2VzXG5cdFx0XHRcdFx0XHRcdFx0c3VidHJlZTogdHJ1ZSwgICAgICAgICAgIC8vIFdhdGNoIGRlc2NlbmRhbnRzIHRvb1xuXHRcdFx0XHRcdFx0XHRcdGNoYXJhY3RlckRhdGE6IHRydWUsICAgICAvLyBUcmFjayB0ZXh0IHVwZGF0ZXNcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRvblVubW91bnQ6IGFzeW5jIChyb290SWQpID0%252BIHtcblx0XHRcdFx0XHRcdC8vIFNhZmVseSBkaXNjb25uZWN0IG9ic2VydmVyIGZvciB0aGlzIGxpZmVjeWNsZTsga2VlcCBpbnN0YW5jZS1zY29wZWQgc3RhdGVcblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdG9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoIHt9XG5cblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKGBIZWFkZXIgdW5tb3VudGVkIHdpdGggcm9vdElkOiAke3Jvb3RJZH1gKTtcblxuXHRcdFx0XHRcdFx0Ly8gSWYgdGhlcmUgYXJlIGNvbW1lbnRzIGluIHRoaXMgdGhyZWFkIG9yIHRoZSBlZGl0b3IgaGFkIGNvbnRlbnQsIGRvIG5vdGhpbmdcblx0XHRcdFx0XHRcdGNvbnN0IGhhc0NvbW1lbnRzID0gKGF3YWl0IGluc3RhbmNlLmdldENvbW1lbnRzKCkpLmZpbmQoXG5cdFx0XHRcdFx0XHRcdChjb21tZW50KSA9PiBjb21tZW50LnJvb3RJZCA9PT0gcm9vdElkXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0aWYgKCEhaGFzQ29tbWVudHMgfHwgaGFzQmVlbkVkaXRlZCkge1xuXHRcdFx0XHRcdFx0XHQvLyBSZXNldCBlZGl0IGZsYWcgZm9yIG5leHQgbGlmZWN5Y2xlXG5cdFx0XHRcdFx0XHRcdGhhc0JlZW5FZGl0ZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBObyBjb21tZW50cyBhbmQgZWRpdG9yIHN0YXllZCBlbXB0eTogcmVtb3ZlIHRoZSBsaW5nZXJpbmcgbWFya2VyIGFubm90YXRpb25cblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiRGVsZXRpbmcgbGluZ2VyaW5nIGFubm90YXRpb24gLSBlZGl0b3IgaXMgZW1wdHlcIik7XG5cdFx0XHRcdFx0XHRjb25zdCB7IGN1cnJlbnRQYWdlSW5kZXggfSA9IGluc3RhbmNlLnZpZXdTdGF0ZTtcblx0XHRcdFx0XHRcdGNvbnN0IGxpbmdlcmluZ0NvbW1lbnRNYXJrZXIgPSAoYXdhaXQgaW5zdGFuY2UuZ2V0QW5ub3RhdGlvbnMoY3VycmVudFBhZ2VJbmRleCkpXG5cdFx0XHRcdFx0XHRcdC5maWx0ZXIoKGFubm90YXRpb24pID0%252BIGFubm90YXRpb24uaWQgPT09IHJvb3RJZCk7XG5cblx0XHRcdFx0XHRcdGlmIChsaW5nZXJpbmdDb21tZW50TWFya2VyLmxlbmd0aCA%252BIDApIHtcblx0XHRcdFx0XHRcdFx0YXdhaXQgaW5zdGFuY2UuZGVsZXRlKGxpbmdlcmluZ0NvbW1lbnRNYXJrZXIpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBSZXNldCBmb3IgbmV4dCBtb3VudFxuXHRcdFx0XHRcdFx0aGFzQmVlbkVkaXRlZCA9IGZhbHNlO1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdH07XG5cdFx0XHR9LFxuXHRcdH0sXG5cdH0sXG59KS50aGVuKChpbnN0YW5jZSkgPT4ge1xuXHQvLyBFU0MgaGFuZGxpbmc6IGRlbGV0ZSB0ZW1wb3JhcnkgbWFya2VycyBvciBjYW5jZWwgZW1wdHkgdGhyZWFkIHJvb3RzXG5cdGNvbnN0IGlzSUUxMSA9IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZihcIlRyaWRlbnQvXCIpID4gLTE7XG5cblx0aW5zdGFuY2UuY29udGVudERvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG5cdFx0XCJrZXlkb3duXCIsXG5cdFx0a2V5RG93bkhhbmRsZXIsXG5cdFx0aXNJRTExID8geyBjYXB0dXJlOiB0cnVlIH0gOiB0cnVlXG5cdCk7XG5cblx0YXN5bmMgZnVuY3Rpb24ga2V5RG93bkhhbmRsZXIoZXZlbnQpIHtcblx0XHRpZiAoZXZlbnQua2V5ICE9PSBcIkVzY2FwZVwiKSByZXR1cm47XG5cblx0XHRjb25zdCBzZWxlY3RlZCA9IGluc3RhbmNlLmdldFNlbGVjdGVkQW5ub3RhdGlvbnMoKTtcblx0XHRjb25zdCBzZWxlY3RlZEZpcnN0ID0gc2VsZWN0ZWQ%252FLmdldD8uKDApO1xuXHRcdGlmICghc2VsZWN0ZWRGaXJzdCkgcmV0dXJuO1xuXG5cdFx0Y29uc3QgY29tbWVudHMgPSBhd2FpdCBpbnN0YW5jZS5nZXRDb21tZW50cygpO1xuXHRcdGNvbnN0IGNvbW1lbnRzQ3JlYXRlZCA9IGNvbW1lbnRzLnNvbWUoXG5cdFx0XHQoY29tbWVudCkgPT4gY29tbWVudD8ucm9vdElkID09PSBzZWxlY3RlZEZpcnN0LmlkXG5cdFx0KTtcblxuXHRcdGNvbnN0IGlzQ29tbWVudE1hcmtlciA9XG5cdFx0XHRzZWxlY3RlZEZpcnN0IGluc3RhbmNlb2YgTnV0cmllbnRWaWV3ZXIuQW5ub3RhdGlvbnMuQ29tbWVudE1hcmtlckFubm90YXRpb247XG5cblx0XHQvLyBEZWxldGUgaWY6XG5cdFx0Ly8gLSBBIG5vbi1yb290IGNvbW1lbnQgbWFya2VyIGlzIHNlbGVjdGVkLCBvclxuXHRcdC8vIC0gQSByb290IG1hcmtlciBpcyBzZWxlY3RlZCBidXQgbm8gY29tbWVudHMgd2VyZSBjcmVhdGVkIHlldFxuXHRcdGNvbnN0IHNob3VsZERlbGV0ZSA9XG5cdFx0XHQoIXNlbGVjdGVkRmlyc3Q%252FLmlzQ29tbWVudFRocmVhZFJvb3QgJiYgaXNDb21tZW50TWFya2VyKSB8fFxuXHRcdFx0KCFjb21tZW50c0NyZWF0ZWQgJiYgc2VsZWN0ZWRGaXJzdD8uaXNDb21tZW50VGhyZWFkUm9vdCk7XG5cblx0XHRpZiAoc2hvdWxkRGVsZXRlKSB7XG5cdFx0XHRhd2FpdCBpbnN0YW5jZS5kZWxldGUoc2VsZWN0ZWQpO1xuXHRcdH1cblx0fVxufSk7IiwiY3NzIjoiLyogQWRkIHlvdXIgQ1NTIGhlcmUgKi9cblx0Iiwic2V0dGluZ3MiOnsiZmlsZU5hbWUiOiJiYXNpYy5wZGYifX0%253D)
- Prevent stray comment markers when someone opens a thread but no longer wants it. If no real text is entered and no comments are posted, the yellow highlight/marker is auto-removed when the editor closes, keeping pages tidy. Press Escape to instantly clear temporary markers while drafting

12 changes: 12 additions & 0 deletions playground/web-content-editor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Web SDK Examples: Content Editor

> These are interactive Nutrient Playground examples. Click any link to try the code in your browser.
>
> For local runnable examples, see [web/document-editor/README.md](../web/document-editor/README.md).

---

## Content Editor

- [Content Editor state change listener](https://www.nutrient.io/playground?p=eyJ2IjoxLCJzZXR0aW5ncyI6eyJmaWxlTmFtZSI6ImJhc2ljLnBkZiJ9LCJqcyI6IlBTUERGS2l0LmxvYWQoe1xuICAuLi5iYXNlT3B0aW9ucyxcbiAgdGhlbWU6IFBTUERGS2l0LlRoZW1lLkRBUkssXG4gIHRvb2xiYXJJdGVtczogWy4uLlBTUERGS2l0LmRlZmF1bHRUb29sYmFySXRlbXMsIHsgdHlwZTogXCJjb250ZW50LWVkaXRvclwiIH1dLFxufSkudGhlbigoaW5zdGFuY2UpID0%252BIHtcbiAgY29uc29sZS5sb2coXCJOdXRyaWVudCBsb2FkZWQhIC0gYnkgTmFyYXNoaW1hblwiKTtcblxuICBsZXQgaXNDb250ZW50RWRpdG9yQWN0aXZlID0gZmFsc2U7XG4gIGxldCBjbGlja0xpc3RlbmVyQWRkZWQgPSBmYWxzZTtcblxuICAvLyBGdW5jdGlvbiB0byBhZGQgYnV0dG9uIGNsaWNrIGRldGVjdGlvblxuICBmdW5jdGlvbiBhZGRCdXR0b25DbGlja0RldGVjdGlvbigpIHtcbiAgICBpZiAoIWluc3RhbmNlLmNvbnRlbnREb2N1bWVudCB8fCBjbGlja0xpc3RlbmVyQWRkZWQpIHJldHVybjtcbiAgICBcbiAgICAvLyBBZGQgZXZlbnQgbGlzdGVuZXIgdG8gZGV0ZWN0IGJ1dHRvbiBjbGlja3MgaW4gY29udGVudCBlZGl0b3JcbiAgICBpbnN0YW5jZS5jb250ZW50RG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgaWYgKCFpc0NvbnRlbnRFZGl0b3JBY3RpdmUpIHJldHVybjtcbiAgICAgIFxuICAgICAgY29uc3QgYnV0dG9uID0gZXZlbnQudGFyZ2V0LmNsb3Nlc3QoJ2J1dHRvbicpO1xuICAgICAgaWYgKCFidXR0b24pIHJldHVybjtcbiAgICAgIFxuICAgICAgY29uc3QgYnV0dG9uVGV4dCA9IGJ1dHRvbi50ZXh0Q29udGVudCB8fCBidXR0b24uaW5uZXJUZXh0IHx8ICcnO1xuICAgICAgXG4gICAgICAvLyBDaGVjayBmb3IgQ2FuY2VsIGJ1dHRvblxuICAgICAgaWYgKGJ1dHRvblRleHQudHJpbSgpID09PSAnQ2FuY2VsJykge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkNhbmNlbCBidXR0b24gY2xpY2tlZFwiKTtcbiAgICAgICAgLy8gWW91IGNhbiBhZGQgeW91ciBsb2dpYyBoZXJlXG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGZvciBTYXZlICYgQ2xvc2UgYnV0dG9uXG4gICAgICBpZiAoYnV0dG9uVGV4dC5pbmNsdWRlcygnU2F2ZScpICYmIGJ1dHRvblRleHQuaW5jbHVkZXMoJ0Nsb3NlJykpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJTYXZlICYgQ2xvc2UgYnV0dG9uIGNsaWNrZWRcIik7XG4gICAgICAgIC8vIFlvdXIgY2FuIGFkZCB5dW9yIGxvZ2ljIGhlcmVcbiAgICAgIH1cbiAgICB9LCB0cnVlKTtcbiAgICBcbiAgICBjbGlja0xpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICB9XG5cbiAgLy8gTW9uaXRvciB2aWV3IHN0YXRlIGNoYW5nZXNcbiAgaW5zdGFuY2UuYWRkRXZlbnRMaXN0ZW5lcihcInZpZXdTdGF0ZS5jaGFuZ2VcIiwgKHZpZXdTdGF0ZSwgcHJldmlvdXNWaWV3U3RhdGUpID0%252BIHtcbiAgICBjb25zdCBjdXJyZW50TW9kZSA9IHZpZXdTdGF0ZS50b0pTKCkuaW50ZXJhY3Rpb25Nb2RlO1xuICAgIGNvbnN0IHByZXZpb3VzTW9kZSA9IHByZXZpb3VzVmlld1N0YXRlLnRvSlMoKS5pbnRlcmFjdGlvbk1vZGU7XG4gICAgXG4gICAgaWYgKGN1cnJlbnRNb2RlID09PSBcIkNPTlRFTlRfRURJVE9SXCIpIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiQ29udGVudCBFZGl0b3Igb3BlbmVkXCIpO1xuICAgICAgaXNDb250ZW50RWRpdG9yQWN0aXZlID0gdHJ1ZTtcbiAgICAgIFxuICAgICAgLy8gQWRkIGJ1dHRvbiBjbGljayBkZXRlY3Rpb25cbiAgICAgIHNldFRpbWVvdXQoYWRkQnV0dG9uQ2xpY2tEZXRlY3Rpb24sIDUwMCk7XG4gICAgICBcbiAgICB9IGVsc2UgaWYgKHByZXZpb3VzTW9kZSA9PT0gXCJDT05URU5UX0VESVRPUlwiKSB7XG4gICAgICBjb25zb2xlLmxvZyhcIkNvbnRlbnQgRWRpdG9yIGNsb3NlZFwiKTtcbiAgICAgIGlzQ29udGVudEVkaXRvckFjdGl2ZSA9IGZhbHNlO1xuICAgIH1cbiAgfSk7XG59KTsiLCJtb2RlIjoic3RhbmRhbG9uZSIsImNzcyI6Ii8qIEFkZCB5b3VyIENTUyBoZXJlICovXG4ifQ%253D%253D)

Loading