Skip to content

Custom toolbar radio button#178

Open
0mar-K wants to merge 6 commits intomasterfrom
omar/custom-toolbar-radio-button
Open

Custom toolbar radio button#178
0mar-K wants to merge 6 commits intomasterfrom
omar/custom-toolbar-radio-button

Conversation

@0mar-K
Copy link
Copy Markdown
Collaborator

@0mar-K 0mar-K commented Jan 6, 2026

Adding a new playground example demonstrating how to create a custom toolbar button that programmatically creates pre-grouped radio buttons with a single click.

@0mar-K 0mar-K requested review from a team January 6, 2026 23:05
---
category: forms
title: Add Grouped Radio Buttons with Custom Toolbar Button
description: Create a custom toolbar item that programmatically places pre-grouped radio buttons with a single click, avoiding manual renaming.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does pre-grouped means here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means radio buttons are created with the same formFieldName, so they automatically function as a group

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't they called grouped?

defaultValue: "1",
},
);
await instance!.create([radioWidget1, radioWidget2, formField]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ! here is the non-null assertion operator—it tells TypeScript "trust me, this isn't null." Since instance is typed as Instance | null, what's the intended behavior if it actually is null at this point? Should it:

  • Fail loudly (current behavior with ! if null at runtime)
  • Silently skip the call (use ?.)
  • Something else (explicit check with error message?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already worked on something similar btw: #155

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@veroo-m , if I correctly understood your comment, I've added an if (!instance) return. Is that right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eli7pm , I see that yours auto-groups them widgets during manual creation in Form Creator mode, while mine provides a toolbar button for programmatic placement of grouped radio buttons. I was reluctant at first to close this one, but I think they're both useful for different workflows + this one adapts Rahul's new Playground structure.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use await instance?.create([radioWidget1, radioWidget2, formField]);

@veroo-m
Copy link
Copy Markdown
Contributor

veroo-m commented Jan 7, 2026

Tested with Miguel's project to test and it seems to be working

Copy link
Copy Markdown
Collaborator Author

@0mar-K 0mar-K left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

@0mar-K 0mar-K requested a review from veroo-m January 8, 2026 00:42
Copy link
Copy Markdown
Collaborator Author

@0mar-K 0mar-K left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@veroo-m , done

@0mar-K
Copy link
Copy Markdown
Collaborator Author

0mar-K commented Feb 4, 2026

@veroo-m , could you please review this?

Copy link
Copy Markdown
Contributor

@veroo-m veroo-m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good job. I added a comment to improve the readability of the code. After the change it can be merged.

Comment on lines +10 to +62
onPress: async () => {
const radioWidget1 = new window.NutrientViewer.Annotations.WidgetAnnotation(
{
id: window.NutrientViewer.generateInstantId(),
pageIndex: 0,
formFieldName: "MyFormField",
boundingBox: new window.NutrientViewer.Geometry.Rect({
left: 100,
top: 100,
width: 20,
height: 20,
}),
},
);

const radioWidget2 = new window.NutrientViewer.Annotations.WidgetAnnotation(
{
id: window.NutrientViewer.generateInstantId(),
pageIndex: 0,
formFieldName: "MyFormField",
boundingBox: new window.NutrientViewer.Geometry.Rect({
left: 130,
top: 100,
width: 20,
height: 20,
}),
},
);

const formField = new window.NutrientViewer.FormFields.RadioButtonFormField(
{
name: "MyFormField",
annotationIds: new window.NutrientViewer.Immutable.List([
radioWidget1.id,
radioWidget2.id,
]),
options: new window.NutrientViewer.Immutable.List([
new window.NutrientViewer.FormOption({
label: "Option 1",
value: "1",
}),
new window.NutrientViewer.FormOption({
label: "Option 2",
value: "2",
}),
]),
defaultValue: "1",
},
);

await instance?.create([radioWidget1, radioWidget2, formField]);
},
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for readability please move defining and creating the radio widgets and associated form field to a function that gets called inside the onPress(). Smtg like:

Suggested change
onPress: async () => {
const radioWidget1 = new window.NutrientViewer.Annotations.WidgetAnnotation(
{
id: window.NutrientViewer.generateInstantId(),
pageIndex: 0,
formFieldName: "MyFormField",
boundingBox: new window.NutrientViewer.Geometry.Rect({
left: 100,
top: 100,
width: 20,
height: 20,
}),
},
);
const radioWidget2 = new window.NutrientViewer.Annotations.WidgetAnnotation(
{
id: window.NutrientViewer.generateInstantId(),
pageIndex: 0,
formFieldName: "MyFormField",
boundingBox: new window.NutrientViewer.Geometry.Rect({
left: 130,
top: 100,
width: 20,
height: 20,
}),
},
);
const formField = new window.NutrientViewer.FormFields.RadioButtonFormField(
{
name: "MyFormField",
annotationIds: new window.NutrientViewer.Immutable.List([
radioWidget1.id,
radioWidget2.id,
]),
options: new window.NutrientViewer.Immutable.List([
new window.NutrientViewer.FormOption({
label: "Option 1",
value: "1",
}),
new window.NutrientViewer.FormOption({
label: "Option 2",
value: "2",
}),
]),
defaultValue: "1",
},
);
await instance?.create([radioWidget1, radioWidget2, formField]);
},
};
onPress: () => createGroupedRadioButtons(instance)
// ....
const createdGroupedRadioButtons = async (instance) => {
const radioWidget1 = new window.NutrientViewer.Annotations.WidgetAnnotation(
{
id: window.NutrientViewer.generateInstantId(),
pageIndex: 0,
formFieldName: "MyFormField",
boundingBox: new window.NutrientViewer.Geometry.Rect({
left: 100,
top: 100,
width: 20,
height: 20,
}),
},
);
const radioWidget2 = new window.NutrientViewer.Annotations.WidgetAnnotation(
{
id: window.NutrientViewer.generateInstantId(),
pageIndex: 0,
formFieldName: "MyFormField",
boundingBox: new window.NutrientViewer.Geometry.Rect({
left: 130,
top: 100,
width: 20,
height: 20,
}),
},
);
const formField = new window.NutrientViewer.FormFields.RadioButtonFormField(
{
name: "MyFormField",
annotationIds: new window.NutrientViewer.Immutable.List([
radioWidget1.id,
radioWidget2.id,
]),
options: new window.NutrientViewer.Immutable.List([
new window.NutrientViewer.FormOption({
label: "Option 1",
value: "1",
}),
new window.NutrientViewer.FormOption({
label: "Option 2",
value: "2",
}),
]),
defaultValue: "1",
},
);
await instance?.create([radioWidget1, radioWidget2, formField]);
},
}

@miguelcalderon
Copy link
Copy Markdown
Contributor

Triage note: This PR was approved by @veroo-m on Mar 2 with one minor readability comment. @0mar-K — can you address that last comment so this can be merged? It's been sitting approved for almost a month.

(Part of stale PR triage: #187)

@0mar-K 0mar-K force-pushed the omar/custom-toolbar-radio-button branch from 695678e to 20b7f15 Compare March 30, 2026 14:42
@0mar-K
Copy link
Copy Markdown
Collaborator Author

0mar-K commented Mar 30, 2026

Triage note: This PR was approved by @veroo-m on Mar 2 with one minor readability comment. @0mar-K — can you address that last comment so this can be merged? It's been sitting approved for almost a month.

(Part of stale PR triage: #187)

Thanks for the reminder, @miguelcalderon! Had some CI issues and managed to fix them.

Would it be possible to give it a final quick review and let me know if it should be merged or if we have any other changes to implement?

@0mar-K 0mar-K requested a review from miguelcalderon March 30, 2026 14:44
Copy link
Copy Markdown
Contributor

@miguelcalderon miguelcalderon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small but key change to the url 🙇

let instance: Instance | null = null;

const createGroupedRadioButtons = async (instance: Instance | null) => {
const radioWidget1 = new window.NutrientViewer.Annotations.WidgetAnnotation({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be possible to use NutrientViewer directly without window.NutrientViewer.

@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://playground.pspdfkit.com/?p=eyJ2IjoxLCJjc3MiOiIvKiBBZGQgeW91ciBDU1MgaGVyZSAqL1xuIiwic2V0dGluZ3MiOnsiZmlsZU5hbWUiOiJiYXNpYy5wZGYifSwianMiOiJsZXQgaW5zdGFuY2UgPSBudWxsO1xuXG5jb25zdCBpdGVtID0ge1xuICB0eXBlOiBcImN1c3RvbVwiLFxuICBpZDogXCJhZGQtcmFkaW8tZ3JvdXBcIixcbiAgdGl0bGU6IFwiQWRkIFJhZGlvIEdyb3VwXCIsXG4gIG9uUHJlc3M6IGFzeW5jICgpID0%252BIHtcbiAgICBjb25zdCByYWRpb1dpZGdldDEgPSBuZXcgTnV0cmllbnRWaWV3ZXIuQW5ub3RhdGlvbnMuV2lkZ2V0QW5ub3RhdGlvbih7XG4gIGlkOiBOdXRyaWVudFZpZXdlci5nZW5lcmF0ZUluc3RhbnRJZCgpLFxuICBwYWdlSW5kZXg6IDAsXG4gIGZvcm1GaWVsZE5hbWU6IFwiTXlGb3JtRmllbGRcIixcbiAgYm91bmRpbmdCb3g6IG5ldyBOdXRyaWVudFZpZXdlci5HZW9tZXRyeS5SZWN0KHtcbiAgICBsZWZ0OiAxMDAsXG4gICAgdG9wOiAxMDAsXG4gICAgd2lkdGg6IDIwLFxuICAgIGhlaWdodDogMjBcbiAgfSlcbn0pO1xuY29uc3QgcmFkaW9XaWRnZXQyID0gbmV3IE51dHJpZW50Vmlld2VyLkFubm90YXRpb25zLldpZGdldEFubm90YXRpb24oe1xuICBpZDogTnV0cmllbnRWaWV3ZXIuZ2VuZXJhdGVJbnN0YW50SWQoKSxcbiAgcGFnZUluZGV4OiAwLFxuICBmb3JtRmllbGROYW1lOiBcIk15Rm9ybUZpZWxkXCIsXG4gIGJvdW5kaW5nQm94OiBuZXcgTnV0cmllbnRWaWV3ZXIuR2VvbWV0cnkuUmVjdCh7XG4gICAgbGVmdDogMTMwLFxuICAgIHRvcDogMTAwLFxuICAgIHdpZHRoOiAyMCxcbiAgICBoZWlnaHQ6IDIwXG4gIH0pXG59KTtcbmNvbnN0IGZvcm1GaWVsZCA9IG5ldyBOdXRyaWVudFZpZXdlci5Gb3JtRmllbGRzLlJhZGlvQnV0dG9uRm9ybUZpZWxkKHtcbiAgbmFtZTogXCJNeUZvcm1GaWVsZFwiLFxuICBhbm5vdGF0aW9uSWRzOiBuZXcgTnV0cmllbnRWaWV3ZXIuSW1tdXRhYmxlLkxpc3QoW3JhZGlvV2lkZ2V0MS5pZCwgcmFkaW9XaWRnZXQyLmlkXSksXG4gIG9wdGlvbnM6IG5ldyBOdXRyaWVudFZpZXdlci5JbW11dGFibGUuTGlzdChbXG4gICAgbmV3IE51dHJpZW50Vmlld2VyLkZvcm1PcHRpb24oeyBsYWJlbDogXCJPcHRpb24gMVwiLCB2YWx1ZTogXCIxXCIgfSksXG4gICAgbmV3IE51dHJpZW50Vmlld2VyLkZvcm1PcHRpb24oeyBsYWJlbDogXCJPcHRpb24gMlwiLCB2YWx1ZTogXCIyXCIgfSlcbiAgXSksXG4gIGRlZmF1bHRWYWx1ZTogXCIxXCJcbn0pO1xuYXdhaXQgaW5zdGFuY2UuY3JlYXRlKFtyYWRpb1dpZGdldDEsIHJhZGlvV2lkZ2V0MiwgZm9ybUZpZWxkXSk7XG4gIH1cbn07XG5cblxuXG5cblxuXG5cbk51dHJpZW50Vmlld2VyLmxvYWQoe1xuICAuLi5iYXNlT3B0aW9ucyxcbiAgdGhlbWU6IE51dHJpZW50Vmlld2VyLlRoZW1lLkRBUkssXG4gIHRvb2xiYXJJdGVtczogWy4uLk51dHJpZW50Vmlld2VyLmRlZmF1bHRUb29sYmFySXRlbXMsIHsgdHlwZTogXCJmb3JtLWNyZWF0b3JcIiB9XVxufSkudGhlbigoX2luc3RhbmNlKSA9PiB7XG4gICAgaW5zdGFuY2UgPSBfaW5zdGFuY2U7XG4gICAgaW5zdGFuY2Uuc2V0VG9vbGJhckl0ZW1zKChpdGVtcykgPT4gWy4uLml0ZW1zLCBpdGVtXSk7XG5cbn0pO1xuXHQifQ%253D%253D
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use https://www.nutrient.io/demo/sandbox?p= instead.

Suggested change
URL=https://playground.pspdfkit.com/?p=eyJ2IjoxLCJjc3MiOiIvKiBBZGQgeW91ciBDU1MgaGVyZSAqL1xuIiwic2V0dGluZ3MiOnsiZmlsZU5hbWUiOiJiYXNpYy5wZGYifSwianMiOiJsZXQgaW5zdGFuY2UgPSBudWxsO1xuXG5jb25zdCBpdGVtID0ge1xuICB0eXBlOiBcImN1c3RvbVwiLFxuICBpZDogXCJhZGQtcmFkaW8tZ3JvdXBcIixcbiAgdGl0bGU6IFwiQWRkIFJhZGlvIEdyb3VwXCIsXG4gIG9uUHJlc3M6IGFzeW5jICgpID0%252BIHtcbiAgICBjb25zdCByYWRpb1dpZGdldDEgPSBuZXcgTnV0cmllbnRWaWV3ZXIuQW5ub3RhdGlvbnMuV2lkZ2V0QW5ub3RhdGlvbih7XG4gIGlkOiBOdXRyaWVudFZpZXdlci5nZW5lcmF0ZUluc3RhbnRJZCgpLFxuICBwYWdlSW5kZXg6IDAsXG4gIGZvcm1GaWVsZE5hbWU6IFwiTXlGb3JtRmllbGRcIixcbiAgYm91bmRpbmdCb3g6IG5ldyBOdXRyaWVudFZpZXdlci5HZW9tZXRyeS5SZWN0KHtcbiAgICBsZWZ0OiAxMDAsXG4gICAgdG9wOiAxMDAsXG4gICAgd2lkdGg6IDIwLFxuICAgIGhlaWdodDogMjBcbiAgfSlcbn0pO1xuY29uc3QgcmFkaW9XaWRnZXQyID0gbmV3IE51dHJpZW50Vmlld2VyLkFubm90YXRpb25zLldpZGdldEFubm90YXRpb24oe1xuICBpZDogTnV0cmllbnRWaWV3ZXIuZ2VuZXJhdGVJbnN0YW50SWQoKSxcbiAgcGFnZUluZGV4OiAwLFxuICBmb3JtRmllbGROYW1lOiBcIk15Rm9ybUZpZWxkXCIsXG4gIGJvdW5kaW5nQm94OiBuZXcgTnV0cmllbnRWaWV3ZXIuR2VvbWV0cnkuUmVjdCh7XG4gICAgbGVmdDogMTMwLFxuICAgIHRvcDogMTAwLFxuICAgIHdpZHRoOiAyMCxcbiAgICBoZWlnaHQ6IDIwXG4gIH0pXG59KTtcbmNvbnN0IGZvcm1GaWVsZCA9IG5ldyBOdXRyaWVudFZpZXdlci5Gb3JtRmllbGRzLlJhZGlvQnV0dG9uRm9ybUZpZWxkKHtcbiAgbmFtZTogXCJNeUZvcm1GaWVsZFwiLFxuICBhbm5vdGF0aW9uSWRzOiBuZXcgTnV0cmllbnRWaWV3ZXIuSW1tdXRhYmxlLkxpc3QoW3JhZGlvV2lkZ2V0MS5pZCwgcmFkaW9XaWRnZXQyLmlkXSksXG4gIG9wdGlvbnM6IG5ldyBOdXRyaWVudFZpZXdlci5JbW11dGFibGUuTGlzdChbXG4gICAgbmV3IE51dHJpZW50Vmlld2VyLkZvcm1PcHRpb24oeyBsYWJlbDogXCJPcHRpb24gMVwiLCB2YWx1ZTogXCIxXCIgfSksXG4gICAgbmV3IE51dHJpZW50Vmlld2VyLkZvcm1PcHRpb24oeyBsYWJlbDogXCJPcHRpb24gMlwiLCB2YWx1ZTogXCIyXCIgfSlcbiAgXSksXG4gIGRlZmF1bHRWYWx1ZTogXCIxXCJcbn0pO1xuYXdhaXQgaW5zdGFuY2UuY3JlYXRlKFtyYWRpb1dpZGdldDEsIHJhZGlvV2lkZ2V0MiwgZm9ybUZpZWxkXSk7XG4gIH1cbn07XG5cblxuXG5cblxuXG5cbk51dHJpZW50Vmlld2VyLmxvYWQoe1xuICAuLi5iYXNlT3B0aW9ucyxcbiAgdGhlbWU6IE51dHJpZW50Vmlld2VyLlRoZW1lLkRBUkssXG4gIHRvb2xiYXJJdGVtczogWy4uLk51dHJpZW50Vmlld2VyLmRlZmF1bHRUb29sYmFySXRlbXMsIHsgdHlwZTogXCJmb3JtLWNyZWF0b3JcIiB9XVxufSkudGhlbigoX2luc3RhbmNlKSA9PiB7XG4gICAgaW5zdGFuY2UgPSBfaW5zdGFuY2U7XG4gICAgaW5zdGFuY2Uuc2V0VG9vbGJhckl0ZW1zKChpdGVtcykgPT4gWy4uLml0ZW1zLCBpdGVtXSk7XG5cbn0pO1xuXHQifQ%253D%253D
URL=https://www.nutrient.io/demo/sandbox?p=eyJ2IjoxLCJjc3MiOiIvKiBBZGQgeW91ciBDU1MgaGVyZSAqL1xuIiwic2V0dGluZ3MiOnsiZmlsZU5hbWUiOiJiYXNpYy5wZGYifSwianMiOiJsZXQgaW5zdGFuY2UgPSBudWxsO1xuXG5jb25zdCBpdGVtID0ge1xuICB0eXBlOiBcImN1c3RvbVwiLFxuICBpZDogXCJhZGQtcmFkaW8tZ3JvdXBcIixcbiAgdGl0bGU6IFwiQWRkIFJhZGlvIEdyb3VwXCIsXG4gIG9uUHJlc3M6IGFzeW5jICgpID0%252BIHtcbiAgICBjb25zdCByYWRpb1dpZGdldDEgPSBuZXcgTnV0cmllbnRWaWV3ZXIuQW5ub3RhdGlvbnMuV2lkZ2V0QW5ub3RhdGlvbih7XG4gIGlkOiBOdXRyaWVudFZpZXdlci5nZW5lcmF0ZUluc3RhbnRJZCgpLFxuICBwYWdlSW5kZXg6IDAsXG4gIGZvcm1GaWVsZE5hbWU6IFwiTXlGb3JtRmllbGRcIixcbiAgYm91bmRpbmdCb3g6IG5ldyBOdXRyaWVudFZpZXdlci5HZW9tZXRyeS5SZWN0KHtcbiAgICBsZWZ0OiAxMDAsXG4gICAgdG9wOiAxMDAsXG4gICAgd2lkdGg6IDIwLFxuICAgIGhlaWdodDogMjBcbiAgfSlcbn0pO1xuY29uc3QgcmFkaW9XaWRnZXQyID0gbmV3IE51dHJpZW50Vmlld2VyLkFubm90YXRpb25zLldpZGdldEFubm90YXRpb24oe1xuICBpZDogTnV0cmllbnRWaWV3ZXIuZ2VuZXJhdGVJbnN0YW50SWQoKSxcbiAgcGFnZUluZGV4OiAwLFxuICBmb3JtRmllbGROYW1lOiBcIk15Rm9ybUZpZWxkXCIsXG4gIGJvdW5kaW5nQm94OiBuZXcgTnV0cmllbnRWaWV3ZXIuR2VvbWV0cnkuUmVjdCh7XG4gICAgbGVmdDogMTMwLFxuICAgIHRvcDogMTAwLFxuICAgIHdpZHRoOiAyMCxcbiAgICBoZWlnaHQ6IDIwXG4gIH0pXG59KTtcbmNvbnN0IGZvcm1GaWVsZCA9IG5ldyBOdXRyaWVudFZpZXdlci5Gb3JtRmllbGRzLlJhZGlvQnV0dG9uRm9ybUZpZWxkKHtcbiAgbmFtZTogXCJNeUZvcm1GaWVsZFwiLFxuICBhbm5vdGF0aW9uSWRzOiBuZXcgTnV0cmllbnRWaWV3ZXIuSW1tdXRhYmxlLkxpc3QoW3JhZGlvV2lkZ2V0MS5pZCwgcmFkaW9XaWRnZXQyLmlkXSksXG4gIG9wdGlvbnM6IG5ldyBOdXRyaWVudFZpZXdlci5JbW11dGFibGUuTGlzdChbXG4gICAgbmV3IE51dHJpZW50Vmlld2VyLkZvcm1PcHRpb24oeyBsYWJlbDogXCJPcHRpb24gMVwiLCB2YWx1ZTogXCIxXCIgfSksXG4gICAgbmV3IE51dHJpZW50Vmlld2VyLkZvcm1PcHRpb24oeyBsYWJlbDogXCJPcHRpb24gMlwiLCB2YWx1ZTogXCIyXCIgfSlcbiAgXSksXG4gIGRlZmF1bHRWYWx1ZTogXCIxXCJcbn0pO1xuYXdhaXQgaW5zdGFuY2UuY3JlYXRlKFtyYWRpb1dpZGdldDEsIHJhZGlvV2lkZ2V0MiwgZm9ybUZpZWxkXSk7XG4gIH1cbn07XG5cblxuXG5cblxuXG5cbk51dHJpZW50Vmlld2VyLmxvYWQoe1xuICAuLi5iYXNlT3B0aW9ucyxcbiAgdGhlbWU6IE51dHJpZW50Vmlld2VyLlRoZW1lLkRBUkssXG4gIHRvb2xiYXJJdGVtczogWy4uLk51dHJpZW50Vmlld2VyLmRlZmF1bHRUb29sYmFySXRlbXMsIHsgdHlwZTogXCJmb3JtLWNyZWF0b3JcIiB9XVxufSkudGhlbigoX2luc3RhbmNlKSA9PiB7XG4gICAgaW5zdGFuY2UgPSBfaW5zdGFuY2U7XG4gICAgaW5zdGFuY2Uuc2V0VG9vbGJhckl0ZW1zKChpdGVtcykgPT4gWy4uLml0ZW1zLCBpdGVtXSk7XG5cbn0pO1xuXHQifQ%253D%253D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants