-
Notifications
You must be signed in to change notification settings - Fork 3
feat(evals): add skia category with 20 react-native-skia evals #377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
andriicallstack
wants to merge
15
commits into
main
Choose a base branch
from
feat/skia-evals
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
8a51ff0
feat(evals): add skia category with 20 react-native-skia evals
andriicallstack c24deb4
feat: default opencode port value, do not run opencode server if alre…
artus9033 fa7f09d
chore: changes after CR
artus9033 37250ee
Merge branch 'main' into feat/skia-evals
artus9033 c44d24d
feat: add Skia evals starter templates
artus9033 300f7f1
feat: consistently require the canvas to be present
artus9033 89e0ca4
chore: add missing inputs key
artus9033 27b50a5
fix: remove obsolete & inconsistent pieces
artus9033 a34b0b1
feat: add evals for: Group layer + Paint + Blur, SweepGradient, Parag…
artus9033 509eb3b
feat: eval for imperative canvas APIs
artus9033 aadacee
refactor: consistently type port as non-nullable
artus9033 ec3c856
chore: update Skia README
artus9033 4e7ebb5
chore: add missing COLORS to Skia eval 21
artus9033 e052b5a
chore: unify declarations in Skia eval 22
artus9033 ed1f6f6
feat: add Skottie eval
artus9033 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { Platform } from 'react-native' | ||
|
|
||
| const FONT_SIZE = 18 | ||
|
|
||
| const fontStyle = { | ||
| fontFamily: Platform.select({ ios: 'Helvetica', default: 'serif' }), | ||
| fontSize: FONT_SIZE, | ||
| fontWeight: 'bold', | ||
| } as const | ||
|
|
||
| export default function App() { | ||
| return <></> | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Implement a full-screen Skia canvas with a solid background color using Fill. Display the current canvas width and height as centered text inside the canvas. Use useCanvasSize to read the canvas dimensions on the JS thread and position the text accordingly. |
35 changes: 35 additions & 0 deletions
35
evals/skia/01-rn-skia-canvas-fill-background/reference/App.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { Platform } from 'react-native' | ||
| import { Canvas, Fill, Text, matchFont, useCanvasSize } from '@shopify/react-native-skia' | ||
|
|
||
| const FONT_SIZE = 18 | ||
|
|
||
| const fontStyle = { | ||
| fontFamily: Platform.select({ ios: 'Helvetica', default: 'serif' }), | ||
| fontSize: FONT_SIZE, | ||
| fontWeight: 'bold', | ||
| } as const | ||
|
|
||
| const font = matchFont(fontStyle) | ||
|
|
||
| function CanvasContent() { | ||
| const { width, height } = useCanvasSize() | ||
|
|
||
| const label = `${Math.round(width)} × ${Math.round(height)}` | ||
| const textX = width / 2 - (font?.getTextWidth(label) ?? 0) / 2 | ||
| const textY = height / 2 + FONT_SIZE / 2 | ||
|
|
||
| return ( | ||
| <> | ||
| <Fill color='#1e293b' /> | ||
| <Text x={textX} y={textY} text={label} font={font} color='#f8fafc' /> | ||
| </> | ||
| ) | ||
| } | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <CanvasContent /> | ||
| </Canvas> | ||
| ) | ||
| } |
13 changes: 13 additions & 0 deletions
13
evals/skia/01-rn-skia-canvas-fill-background/requirements.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| version: 1 | ||
| inputs: | ||
| files: | ||
| - app/App.tsx | ||
| requirements: | ||
| - id: uses-canvas-component | ||
| description: Must render all drawing content inside a Canvas component from @shopify/react-native-skia. | ||
| - id: uses-fill-for-background | ||
| description: Must use the Fill component from @shopify/react-native-skia to paint the canvas background color. | ||
| - id: uses-canvas-size-hook | ||
| description: Must use useCanvasSize from @shopify/react-native-skia to read canvas dimensions on the JS thread. | ||
| - id: displays-dimensions-as-text | ||
| description: Must render the canvas width and height as visible text inside the canvas using the Text component from @shopify/react-native-skia. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import { Canvas, Fill } from '@shopify/react-native-skia' | ||
|
|
||
| const PADDING = 24 | ||
| const SHAPE_SIZE = 80 | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <Fill color="#f1f5f9" /> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Draw a composition of basic shapes on a Skia canvas: a filled rectangle, a filled circle, a rounded rectangle, and a straight line. Give each shape a distinct color and arrange them so they are all visible without overlap. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import { | ||
| Canvas, | ||
| Circle, | ||
| Fill, | ||
| Line, | ||
| Rect, | ||
| RoundedRect, | ||
| vec, | ||
| } from '@shopify/react-native-skia' | ||
|
|
||
| const PADDING = 24 | ||
| const SHAPE_SIZE = 80 | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <Fill color="#f1f5f9" /> | ||
|
|
||
| <Rect | ||
| x={PADDING} | ||
| y={PADDING} | ||
| width={SHAPE_SIZE} | ||
| height={SHAPE_SIZE} | ||
| color="#3b82f6" | ||
| /> | ||
|
|
||
| <Circle | ||
| cx={PADDING + SHAPE_SIZE + 40 + SHAPE_SIZE / 2} | ||
| cy={PADDING + SHAPE_SIZE / 2} | ||
| r={SHAPE_SIZE / 2} | ||
| color="#ef4444" | ||
| /> | ||
|
|
||
| <RoundedRect | ||
| x={PADDING} | ||
| y={PADDING + SHAPE_SIZE + 24} | ||
| width={SHAPE_SIZE} | ||
| height={SHAPE_SIZE} | ||
| r={16} | ||
| color="#22c55e" | ||
| /> | ||
|
|
||
| <Line | ||
| p1={vec(PADDING, PADDING + (SHAPE_SIZE + 24) * 2 + 40)} | ||
| p2={vec( | ||
| PADDING + SHAPE_SIZE * 2 + 40, | ||
| PADDING + (SHAPE_SIZE + 24) * 2 + 40 | ||
| )} | ||
| color="#f59e0b" | ||
| strokeWidth={4} | ||
| /> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| version: 1 | ||
| inputs: | ||
| files: | ||
| - app/App.tsx | ||
| requirements: | ||
| - id: uses-canvas-component | ||
| description: Must render all drawing content inside a Canvas component from @shopify/react-native-skia. | ||
| weight: 0.1 | ||
| - id: uses-rect-component | ||
| description: Must render a Rect component from @shopify/react-native-skia. | ||
| - id: uses-circle-component | ||
| description: Must render a Circle component from @shopify/react-native-skia. | ||
| - id: uses-rounded-rect-component | ||
| description: Must render a RoundedRect or equivalent rounded rectangle component from @shopify/react-native-skia. | ||
| - id: uses-line-component | ||
| description: Must render a Line component from @shopify/react-native-skia. | ||
| - id: shapes-have-distinct-colors | ||
| description: Each shape must use a visually distinct color. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { Canvas, Fill } from '@shopify/react-native-skia' | ||
|
|
||
| const STROKE_WIDTH = 4 | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <Fill color="#0f172a" /> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Draw a custom Bezier curve path on a Skia canvas. Build the path imperatively using Skia.Path.Make() with moveTo and cubicTo commands, and render it as a stroked line with a visible stroke width and color. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import { Canvas, Fill, Path, Skia } from '@shopify/react-native-skia' | ||
|
|
||
| const STROKE_WIDTH = 4 | ||
|
|
||
| const path = (() => { | ||
| const p = Skia.Path.Make() | ||
| p.moveTo(40, 300) | ||
| p.cubicTo(100, 100, 260, 500, 340, 200) | ||
| p.cubicTo(380, 80, 300, 400, 360, 340) | ||
| return p | ||
| })() | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <Fill color="#0f172a" /> | ||
| <Path | ||
| path={path} | ||
| color="#38bdf8" | ||
| style="stroke" | ||
| strokeWidth={STROKE_WIDTH} | ||
| strokeCap="round" | ||
| strokeJoin="round" | ||
| /> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| version: 1 | ||
| inputs: | ||
| files: | ||
| - app/App.tsx | ||
| requirements: | ||
| - id: uses-canvas-component | ||
| description: Must render all drawing content inside a Canvas component from @shopify/react-native-skia. | ||
| weight: 0.1 | ||
| - id: uses-path-component | ||
| description: Must render a Path component from @shopify/react-native-skia. | ||
| - id: builds-path-imperatively | ||
| description: Must build the path using Skia.Path.Make() with at least moveTo and cubicTo or quadTo path commands. | ||
| - id: renders-as-stroke | ||
| description: Must render the path as a stroke using style="stroke" or strokeWidth property, not as a fill. | ||
| - id: path-is-memoized | ||
| description: The path object must be created outside of the render function or memoized with useMemo to avoid recreating it on every render. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { Canvas, Fill } from '@shopify/react-native-skia' | ||
|
|
||
| const SIZE = 300 | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <Fill color="#0f172a" /> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Render a circle that has a solid fill and two concentric strokes of different widths using nested Paint components. Wrap multiple shapes in a Group to demonstrate paint attribute inheritance, where the group-level color is shared by all children. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { | ||
| Canvas, | ||
| Circle, | ||
| Fill, | ||
| Group, | ||
| Paint, | ||
| Rect, | ||
| } from '@shopify/react-native-skia' | ||
|
|
||
| const SIZE = 300 | ||
| const CX = SIZE / 2 | ||
| const R = 100 | ||
| const OUTER_STROKE = 16 | ||
| const INNER_STROKE = 8 | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas | ||
| style={{ width: SIZE, height: SIZE, alignSelf: 'center', marginTop: 60 }} | ||
| > | ||
| <Fill color="#0f172a" /> | ||
|
|
||
| <Circle cx={CX} cy={CX} r={R} color="#6366f1"> | ||
| <Paint color="#a5b4fc" /> | ||
| <Paint color="#818cf8" style="stroke" strokeWidth={OUTER_STROKE} /> | ||
| <Paint color="#c7d2fe" style="stroke" strokeWidth={INNER_STROKE} /> | ||
| </Circle> | ||
|
|
||
| <Group color="#fbbf24"> | ||
| <Rect x={20} y={20} width={40} height={40} /> | ||
| <Group style="stroke" strokeWidth={3}> | ||
| <Rect x={70} y={20} width={40} height={40} /> | ||
| </Group> | ||
| </Group> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| version: 1 | ||
| inputs: | ||
| files: | ||
| - app/App.tsx | ||
| requirements: | ||
| - id: uses-canvas-component | ||
| description: Must render all drawing content inside a Canvas component from @shopify/react-native-skia. | ||
| weight: 0.1 | ||
| - id: uses-paint-children-for-strokes | ||
| description: Must use Paint components as children of a drawing element to add at least two strokes with different widths. | ||
| - id: paint-uses-stroke-style | ||
| description: At least one Paint child must explicitly use style="stroke" with a strokeWidth property. | ||
| - id: uses-group-paint-inheritance | ||
| description: Must use a Group component with a color or paint prop to demonstrate that paint attributes are inherited by child drawing elements. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| const START_COLORS = ['#6366f1', '#3b82f6', '#06b6d4', '#10b981'] | ||
| const END_COLORS = ['#f59e0b', '#ef4444', '#ec4899', '#8b5cf6'] | ||
|
|
||
| export default function App() { | ||
| return <></> | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Fill a Skia canvas with an animated linear gradient that continuously cycles through two sets of colors. Use LinearGradient as a child of Fill and drive the color interpolation with a Reanimated shared value combined with Skia's interpolateColors function. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { useEffect } from 'react' | ||
| import { useWindowDimensions } from 'react-native' | ||
| import { Canvas, Fill, LinearGradient, interpolateColors, vec } from '@shopify/react-native-skia' | ||
| import { useDerivedValue, useSharedValue, withRepeat, withTiming } from 'react-native-reanimated' | ||
|
|
||
| const START_COLORS = ['#6366f1', '#3b82f6', '#06b6d4', '#10b981'] | ||
| const END_COLORS = ['#f59e0b', '#ef4444', '#ec4899', '#8b5cf6'] | ||
|
|
||
| const INPUT_RANGE = START_COLORS.map((_, i) => i) | ||
|
|
||
| export default function App() { | ||
| const { width, height } = useWindowDimensions() | ||
| const progress = useSharedValue(0) | ||
|
|
||
| useEffect(() => { | ||
| progress.value = withRepeat( | ||
| withTiming(START_COLORS.length - 1, { duration: 3000 }), | ||
| -1, | ||
| true | ||
| ) | ||
| }, [progress]) | ||
|
|
||
| const colors = useDerivedValue(() => [ | ||
| interpolateColors(progress.value, INPUT_RANGE, START_COLORS), | ||
| interpolateColors(progress.value, INPUT_RANGE, END_COLORS), | ||
| ]) | ||
|
|
||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <Fill> | ||
| <LinearGradient | ||
| start={vec(0, 0)} | ||
| end={vec(width, height)} | ||
| colors={colors} | ||
| /> | ||
| </Fill> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| version: 1 | ||
| inputs: | ||
| files: | ||
| - app/App.tsx | ||
| requirements: | ||
| - id: uses-canvas-component | ||
| description: Must render all drawing content inside a Canvas component from @shopify/react-native-skia. | ||
| weight: 0.1 | ||
| - id: uses-linear-gradient-component | ||
| description: Must use LinearGradient from @shopify/react-native-skia as a child shader of Fill or another drawing element. | ||
| - id: uses-skia-interpolate-colors | ||
| description: Must use interpolateColors from @shopify/react-native-skia for color transitions, not interpolateColor from react-native-reanimated. | ||
| - id: uses-reanimated-shared-value | ||
| description: Must use useSharedValue from react-native-reanimated to drive the gradient animation progress. | ||
| - id: animation-is-infinite-loop | ||
| description: Must use withRepeat to create a continuous looping color animation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { Canvas, Fill } from '@shopify/react-native-skia' | ||
|
|
||
| const SIZE = 320 | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas style={{ flex: 1 }}> | ||
| <Fill color="#0f172a" /> | ||
| </Canvas> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Draw a circle filled with a radial gradient using the RadialGradient component as a child shader. The gradient should radiate from the circle's center, transitioning from a bright opaque inner color to a fully transparent outer edge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { | ||
| Canvas, | ||
| Circle, | ||
| Fill, | ||
| RadialGradient, | ||
| vec, | ||
| } from '@shopify/react-native-skia' | ||
|
|
||
| const SIZE = 320 | ||
| const CX = SIZE / 2 | ||
| const CY = SIZE / 2 | ||
| const R = 120 | ||
|
|
||
| export default function App() { | ||
| return ( | ||
| <Canvas | ||
| style={{ width: SIZE, height: SIZE, alignSelf: 'center', marginTop: 60 }} | ||
| > | ||
| <Fill color="#0f172a" /> | ||
| <Circle cx={CX} cy={CY} r={R}> | ||
| <RadialGradient | ||
| c={vec(CX, CY)} | ||
| r={R} | ||
| colors={['#facc15', '#f97316', 'transparent']} | ||
| /> | ||
| </Circle> | ||
| </Canvas> | ||
| ) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.