From 735db76f2fd54059fc14e6dc8269a92bc818ba02 Mon Sep 17 00:00:00 2001 From: Yuliya Bagriy Date: Wed, 3 Jan 2024 23:59:57 -0500 Subject: [PATCH] move callouts to classes --- assets/css/site.css | 59 ++----------------- .../1992/1992-01-01-elements/index.md | 12 ++-- .../index.md | 4 +- .../index.md | 8 +-- .../2019/2019-09-15-soap-testing-101/index.md | 12 ++-- .../index.md | 4 +- .../index.md | 4 +- .../2020-10-18-blog-redesign-phase-1/index.md | 4 +- .../index.md | 4 +- .../index.md | 4 +- .../index.md | 12 ++-- .../index.md | 8 +-- .../index.md | 8 +-- .../index.md | 4 +- layouts/shortcodes/callout.html | 27 +++++++++ layouts/shortcodes/cta.html | 9 --- layouts/shortcodes/note.html | 9 --- layouts/shortcodes/warning.html | 9 --- 18 files changed, 75 insertions(+), 126 deletions(-) create mode 100644 layouts/shortcodes/callout.html delete mode 100644 layouts/shortcodes/cta.html delete mode 100644 layouts/shortcodes/note.html delete mode 100644 layouts/shortcodes/warning.html diff --git a/assets/css/site.css b/assets/css/site.css index 45ea0701..680a340e 100644 --- a/assets/css/site.css +++ b/assets/css/site.css @@ -124,72 +124,21 @@ article blockquote { padding: theme(spacing.bleed); } -article blockquote p, article blockquote, article .admonition { +article blockquote p, article blockquote { font-size: 1.7rem; } -article blockquote p, article .admonition p { +article blockquote p { margin-bottom: 1.6rem; } -article blockquote > :last-child, article .admonition > :last-child { +article blockquote > :last-child { margin-bottom: 0px !important; } -article .admonition { - width: 100%; - margin: 2.4rem 0 2.4rem; - position: relative; - border-radius: 0.3rem 0.6rem 0.6rem 0.3rem; - padding: theme(spacing.bleed); - - &.warning { - border-left: 0.3rem solid theme(colors.rose.500); - background-color: theme(colors.rose.100); - } - - &.note { - border-left: 0.3rem solid theme(colors.indigo.500); - background-color: theme(colors.indigo.100); - } - - &.cta { - border-left: 0.3rem solid theme(colors.yellow.500); - background-color: theme(colors.yellow.100); - } -} - -article p.admonition-title { - font-weight: bolder; - margin-bottom: 2rem; -} - -.admonition-icon { - position: absolute; - top: 0px; - left: 0px; - transform: translate(-50%, -50%); - padding: 0.6rem; - background: theme(colors.white); - border-radius: 50%; - - .warning & { - color: theme(colors.rose.500); - } - - .note & { - color: theme(colors.indigo.500); - } - - .cta & { - color: theme(colors.yellow.500); - } -} - - @screen normal { - article .highlight, article blockquote, article .gist, article .admonition { + article .highlight, article blockquote, article .gist { width: 80.5rem; margin: 2.4rem theme(spacing.bleed-negative) 2.4rem; } diff --git a/content/articles/1992/1992-01-01-elements/index.md b/content/articles/1992/1992-01-01-elements/index.md index 68910123..f4e1526d 100644 --- a/content/articles/1992/1992-01-01-elements/index.md +++ b/content/articles/1992/1992-01-01-elements/index.md @@ -108,7 +108,7 @@ Next list: ### Admonitions -{{< warning >}} +{{< callout type="warning" >}} This is a simple warning. With _some_ lists and [link A](https://google.com) and [link B](../test): @@ -118,15 +118,15 @@ With _some_ lists and [link A](https://google.com) and [link B](../test): 1. a 2. b -{{< /warning >}} +{{< /callout >}} -{{< note >}} +{{< callout >}} This is a simple note with [link A](https://google.com) and [link B](../test). -{{< /note >}} +{{< /callout >}} -{{< cta >}} +{{< callout type="cta" >}} This is a _simple_ cta. -{{< /cta >}} +{{< /callout >}} --- diff --git a/content/articles/2019/2019-08-26-revision-testers-in-this-world/index.md b/content/articles/2019/2019-08-26-revision-testers-in-this-world/index.md index 7100e64f..f221a9a6 100644 --- a/content/articles/2019/2019-08-26-revision-testers-in-this-world/index.md +++ b/content/articles/2019/2019-08-26-revision-testers-in-this-world/index.md @@ -9,9 +9,9 @@ Category: Testing Recently I've remembered [my old article]({{< ref "2018-01-23-en-testers-in-this-world" >}}) and wondered, how much my thoughts have changed and how they align to the principles of context-driven and modern testing (and yes, I don't see them as contradicting each other). -{{< warning title="" >}} +{{< callout type="warning" >}} Remark in the parentheses is a bit stupid. It was discussed in the [AB Testing episode 94](https://www.angryweasel.com/ABTesting/ab-testing-episode-94-modern-testing-meets-context-driven-testing/) and at least for Alan and Brent there is no real contradiction. -{{< /warning >}} +{{< /callout >}} It looks like there are two main themes in that article. diff --git a/content/articles/2019/2019-09-02-your-api-is-your-public-image/index.md b/content/articles/2019/2019-09-02-your-api-is-your-public-image/index.md index b1867e3f..c7904a39 100644 --- a/content/articles/2019/2019-09-02-your-api-is-your-public-image/index.md +++ b/content/articles/2019/2019-09-02-your-api-is-your-public-image/index.md @@ -7,9 +7,9 @@ Category: Testing **Disclaimer:** this is a translation of [the article](https://quality-lab.ru/blog/your-api-is-your-public-face/) written 2 years ago for a corporate blog. I didn't do a word-for-word translation because the original article went through an editor, whose style was not that close to mine. Too watered down and "official." Also, some examples don't make sense in English. Still, I didn't update it too radically. Bear in mind, at the moment of the writing I was testing SOAP services and Excel-based import/export at big government project, so most of the examples relate to that experience. -{{< note >}} +{{< callout >}} Sometimes you'll see a block like that. It will contain my current thoughts on the subject or comments. -{{< /note >}} +{{< /callout >}} --- @@ -72,9 +72,9 @@ When we hear the word "usability", we usually think about GUI: buttons and dialo > Your developers drink too much and it impairs their accuracy. There is an epic fail in a scheme with the name of the element `Pressure`: the first letter is a Cyrillic character and it breaks all client code generation. -{{< note >}} +{{< callout >}} Cyrillic `Р/р` (pronounced like "r") looks exactly like Latin `P/p`. -{{< /note >}} +{{< /callout >}} * Service works fine, but error messages are not that informative? Users won't understand how to fix an error (and probably will open a support ticket, so you'll needlessly spend time resolving non-existing issue). diff --git a/content/articles/2019/2019-09-15-soap-testing-101/index.md b/content/articles/2019/2019-09-15-soap-testing-101/index.md index c1a5343a..c1153ada 100644 --- a/content/articles/2019/2019-09-15-soap-testing-101/index.md +++ b/content/articles/2019/2019-09-15-soap-testing-101/index.md @@ -7,9 +7,9 @@ Category: Testing **Disclaimer:** this is a translation of [the article](https://quality-lab.ru/blog/soap-api-testing/) written 2 years ago for a corporate blog. I didn't do a word-for-word translation because the original article went through an editor, whose style was not that close to mine. Too watered down and "official." Also, some examples don't make sense in English. Still, I didn't update it too radically. Bear in mind, at the moment of the writing I was testing SOAP services and Excel-based import/export at big government project, so most of the examples relate to that experience. -{{< note >}} +{{< callout >}} Sometimes you'll see a block like that. It will contain my current thoughts on the subject or comments. -{{< /note >}} +{{< /callout >}} --- @@ -186,9 +186,9 @@ SoapUI can generate mock objects based on WSDL. It's a crude service simulation You recognize differences between free and pro versions of SoapUI. You use SoapUI as a library from code. You use plugins and run test cases via CLI and/or CI. Your tests cases are elegant and easy to support. You know all the angles! I envy you. -{{< note >}} +{{< callout >}} Or not. Presently I don't use any GUI tools for API testing except for exploratory sessions. -{{< /note >}} +{{< /callout >}} ### Testing with code @@ -215,11 +215,11 @@ assert '1' == response.CheckTextResponse.SpellResult.error.@code.text() As far as I know there are no high-level test frameworks for SOAP (similar to Rest-assured), but there is an interesting framework called [karate](https://github.com/intuit/karate) where you can describe test cases for SOAP and REST in Cucumber / Gherkin style. -{{< note >}} +{{< callout >}} I don't do any Groovy programming anymore, so no idea how groovy-wslite fares. In fact, I don't do SOAP testing now, so my knowledge about libraries can be outdated. Plus, I avoid anything cucumber-ish =) -{{< /note >}} +{{< /callout >}} --- diff --git a/content/articles/2019/2019-10-19-how-to-test-api-usability-part-2/index.md b/content/articles/2019/2019-10-19-how-to-test-api-usability-part-2/index.md index 90ce5fc2..4203f891 100644 --- a/content/articles/2019/2019-10-19-how-to-test-api-usability-part-2/index.md +++ b/content/articles/2019/2019-10-19-how-to-test-api-usability-part-2/index.md @@ -64,9 +64,9 @@ Typical developers' personas: * **Pragmatic developers** are more common and work both in deductive and inductive manners. Typically they code desktop and mobile apps in Java or C#. * **Opportunistic developers** concentrate on solving business problems in an exploratory and inductive fashion. Guess what language they prefer? JavaScript. -{{< warning title="" >}} +{{< callout type="warning" >}} Now, I want to point out that the aforementioned language discrimination is not my invention. If you're lucky, perhaps you'll find the original article by Visual Studio usability expert, where these quirky definitions were introduced. Unfortunately, I was able to get only [its first page in the Wayback Machine][visual-studio], so you have to take my word for it. Nevertheless, I hope this example can encourage you to create your own personas. -{{< /warning >}} +{{< /callout >}} We can also combine personas with cognitive dimensions. Create [a radar chart](https://en.wikipedia.org/wiki/Radar_chart) with 12 axes, where each axis is a cognitive dimension. Next, plot current values for your API and values according to the persona's expectations. This chart is great for comparing how existing API corresponds to user values. diff --git a/content/articles/2020/2020-02-07-api-testing-in-python-requests-vs-bravado/index.md b/content/articles/2020/2020-02-07-api-testing-in-python-requests-vs-bravado/index.md index bccf5b52..23298931 100644 --- a/content/articles/2020/2020-02-07-api-testing-in-python-requests-vs-bravado/index.md +++ b/content/articles/2020/2020-02-07-api-testing-in-python-requests-vs-bravado/index.md @@ -7,7 +7,7 @@ og_image: og_requests-vs-bravado.png --- -{{< note >}} +{{< callout >}} This article is written as a result of collaboration with [TestProject](https://testproject.io/). While many of you know me as [a GUI-driven tools hater]({{< ref "2019-11-25-why-i-dont-use-postman" >}}), that's just my preference, so if something works for you and your company, that's the only thing @@ -15,7 +15,7 @@ that matters. There are no best practices and there are no best tools for everyo What I really admire the TestProject team for is their strategy of creating a knowledge-sharing community. And their product has a totally free usage tier. You don't see such combo often. -{{< /note >}} +{{< /callout >}} API testing is not an uncommon topic and you can find a gazillion of articles about it. If you check tutorials in Java or JavaScript, you’ll notice that they use a plethora of diverse libraries. Yet for Python diff --git a/content/articles/2020/2020-10-18-blog-redesign-phase-1/index.md b/content/articles/2020/2020-10-18-blog-redesign-phase-1/index.md index 0e8fa78c..cf4923e0 100644 --- a/content/articles/2020/2020-10-18-blog-redesign-phase-1/index.md +++ b/content/articles/2020/2020-10-18-blog-redesign-phase-1/index.md @@ -26,11 +26,11 @@ Tailwind CSS has [a plugin for typography](https://tailwindcss-typography.netlif For layout I used `grid` and `flexbox`. Last time I did any CSS these two weren't a common thing; you had to do a million of `div`'s with `float`'s and other weird things. I also wanted to use `grid` for minor bleeding elements [how it was described here](https://joshwcomeau.com/css/full-bleed/), but I didn't like the result: vertical margins don't collapse when you apply grid to child elements. -{{}} +{{< callout >}} BTW, [raindrop.io](https://raindrop.io/) helped tremendously with gathering links and sources. I completely migrated there from [Pocket](http://getpocket.com/). It has a similar "save for later" experience, but also supports collections and comments. For example, for this project I created a collection "blog redesign" and added a comment for each link saved there to remember later why it was saved in the first place. -{{}} +{{< /callout >}} Additional resources: diff --git a/content/articles/2020/2020-10-24-automap-api-operation-handlers-in-components-based-project/index.md b/content/articles/2020/2020-10-24-automap-api-operation-handlers-in-components-based-project/index.md index 07b7d89a..ac6b4202 100644 --- a/content/articles/2020/2020-10-24-automap-api-operation-handlers-in-components-based-project/index.md +++ b/content/articles/2020/2020-10-24-automap-api-operation-handlers-in-components-based-project/index.md @@ -69,9 +69,9 @@ operationHandlers: { } ``` -{{< warning title="" >}} +{{< callout type="warning" >}} The code was updated after the fix [#426](https://github.com/cdimascio/express-openapi-validator/issues/426). Should be a valid example as of version v4.3.6. -{{< /warning >}} +{{< /callout >}} It assumes several things about the project's structure: diff --git a/content/articles/2020/2020-12-05-crash-course-into-api-related-terminology/index.md b/content/articles/2020/2020-12-05-crash-course-into-api-related-terminology/index.md index 3615a031..2d6dd55b 100644 --- a/content/articles/2020/2020-12-05-crash-course-into-api-related-terminology/index.md +++ b/content/articles/2020/2020-12-05-crash-course-into-api-related-terminology/index.md @@ -41,12 +41,12 @@ There are *tons* of API-related specifications. I'll cover only some. **[OpenAPI](https://www.openapis.org/)** is used to describe both the service model and the request/response body *kinda* based on JSON Schema. It was called Swagger before being donated to Linux Foundation. You probably noticed that this created a sore spot: people still call it Swagger, perhaps, because "OpenAPI" is a bit mouthful. Anyway, know that Swagger is just a part of the SwaggerHub branding of tooling like Swagger Editor or SwaggerUI. -{{< warning title="" >}} +{{< callout type="warning" >}} You may stumble upon people using the word "swagger" even in weirder situations: - as a synonym for "API": "We developed swagger for creating users!", "Use this swagger to export files!" - as a synonym for response body: "We make a request and the swagger we got back…" -{{< /warning >}} +{{< /callout >}} **[JSON Schema](https://json-schema.org/)** is for describing an instance of JSON data. OpenAPI was using an extended subset of it, but this was fixed in OAS 3.1, and now they are fully compatible. Why does it matter? Well, JSON Schema have additional tooling for client-side validations or HATEOAS support. diff --git a/content/articles/2021/2021-01-10-using-openapi-cli-for-api-exploration/index.md b/content/articles/2021/2021-01-10-using-openapi-cli-for-api-exploration/index.md index 4d7565ed..9f499353 100644 --- a/content/articles/2021/2021-01-10-using-openapi-cli-for-api-exploration/index.md +++ b/content/articles/2021/2021-01-10-using-openapi-cli-for-api-exploration/index.md @@ -22,9 +22,9 @@ In the simplest words, it is a process of learning something about API I don't k There are many ways to perform exploration, countless tools and sources to use. In this article I'll be looking only at OpenAPI description documents, because that's where `openapi-cli` comes handy. -{{< note title="" >}} +{{< callout >}} When exploring unknown APIs, I run a globally installed package: `npm i -g @redocly/openapi-cli`. Then it is accessible in the terminal as `openapi `. -{{< /note >}} +{{< /callout >}} ## `openapi stats` Gathers some basic statistics for an OpenAPI description document. Can be in "stylish" format (as in the example below) or in JSON. @@ -75,9 +75,9 @@ For example, it's a SwaggerUI, and you don't like it, or the description doc has Or perhaps you have special needs. Lorna Jane Mitchell in her presentation on [Delightful SDKs](https://lornajane.net/resource/delightful-sdks-with-openapi) mentions that she often generates her own local reference docs because official documentations aren't *accessible*. AFAIK, she uses Redoc and made several pull requests specifically for better accessibility support. -{{< note title="" >}} +{{< callout >}} You can generate reference docs with [`redoc-cli`](https://www.npmjs.com/package/redoc-cli), but I prefer using `openapi-cli` as a one-stop shop. The difference is when you want to generate static HTML with your theme: right now you have to use a small hack [from this issue](https://github.com/Redocly/openapi-cli/issues/133). -{{< /note >}} +{{< /callout >}} ## `openapi split` Reading a big OpenAPI description doc is cumbersome. Especially when you need to jump back and forth between references. @@ -85,9 +85,9 @@ Reading a big OpenAPI description doc is cumbersome. Especially when you need to Split for the rescue! It's an opposite of the [bundling operation]({{< ref "2020-12-05-crash-course-into-api-related-terminology#ref" >}}) and separates references into several files. Though, it's a bit smarter; for example, it splits paths into separate files too. -{{< warning >}} +{{< callout type="warning" >}} This command doesn't support OpenAPI 2. -{{< /warning >}} +{{< /callout >}} Let's split a description doc into `out` directory: `openapi split --outDir out openapi.json`. Here is a sample result: diff --git a/content/articles/2021/2021-01-31-using-openapi-cli-during-api-design-part-one/index.md b/content/articles/2021/2021-01-31-using-openapi-cli-during-api-design-part-one/index.md index a8e9632b..47c586ea 100644 --- a/content/articles/2021/2021-01-31-using-openapi-cli-during-api-design-part-one/index.md +++ b/content/articles/2021/2021-01-31-using-openapi-cli-during-api-design-part-one/index.md @@ -36,9 +36,9 @@ Next, operations. Nothing fancy, the bare minimum: - Get gate info - Update gate info -{{< note title="">}} +{{< callout >}} Don't forget, not all APIs should be OpenAPI-based. If I needed to design a real Stargate system, I would go with a combo of something like GraphQL for lookup and event-based APIs for anything else (perhaps described with AsyncAPI). -{{< /note >}} +{{< /callout >}} Let's create a place to store our OpenAPI description doc: YAML-based, multi-file git repo. You can read more about [why's in the Redocly docs](https://redoc.ly/docs/resources/openapi-decisions/). @@ -63,11 +63,11 @@ Let's explore the generated files: Now, let's rewind the time. Stargate Network API contract is defined, [commit c2b8d11](https://github.com/aviskase/openapi-cli-examples/tree/c2b8d1172129e00903d3d1bd4cbb90f2bf03b51f). For more information about keeping your structure *DRY* read [this](https://mux.com/blog/an-adventure-in-openapi-v3-api-code-generation/) and [this](https://stoplight.io/blog/keeping-openapi-dry-and-portable/). If you're interested in reading/watching about it from me, just ping! -{{< warning title="">}} +{{< callout type="warning" >}} The definitions are not state of art, even for this shallow design. Some problems with it were added consciously to simplify the example, others for fixing in later articles. And I'm not even talking about how many details are omitted lore-wise! -{{< /warning >}} +{{< /callout >}} ## Preview In the `package.json` file there is already an action for previewing the docs: `openapi preview-docs`. To execute it, run in the terminal `npm run start`. diff --git a/content/articles/2021/2021-08-16-using-openapi-cli-custom-preprocessing/index.md b/content/articles/2021/2021-08-16-using-openapi-cli-custom-preprocessing/index.md index adef5f31..f07999a8 100644 --- a/content/articles/2021/2021-08-16-using-openapi-cli-custom-preprocessing/index.md +++ b/content/articles/2021/2021-08-16-using-openapi-cli-custom-preprocessing/index.md @@ -63,9 +63,9 @@ What's happening here: - All `openapi-cli` preprocessors should return a _visitor_. In our case, we specifically indicate to take into account only schema nodes. - If a schema has defined extensible enumeration property, we update its description with formatted list of values. -{{< warning >}} +{{< callout type="warning" >}} Per documentation, for type support you can use `import('@redocly/openapi-cli').Oas3Preprocessor}`. It never worked for me, so I use a "full path" `import('@redocly/openapi-core/src/visitors').Oas3Preprocessor`. -{{< /warning >}} +{{< /callout >}} ### Enabling our preprocessor via custom plugin Let's keep our preprocessor (and the future ones) bundled inside one plugin via `./plugins/custom-preprocessors.js`: @@ -110,9 +110,9 @@ Now, when we render a reference documentation, we can see all values with simple ![Redoc with modified descriptions for extensible enumerations](x_enum_render.png) -{{< cta >}} +{{< callout type="cta" >}} By the way, can you spot operations where we could have left normal `enum` and why? -{{< /cta >}} +{{< /callout >}} ## Why use a preprocessor here? As mentioned before, preprocessors might be brittle. We could have used decorator instead. I'll show you the reason in the next article, but here is a sneak peek: we want to be able to [_lint_ modified descriptions]({{< ref "2021-09-06-using-openapi-cli-custom-rules" >}})! diff --git a/content/articles/2021/2021-09-06-using-openapi-cli-custom-rules/index.md b/content/articles/2021/2021-09-06-using-openapi-cli-custom-rules/index.md index 205d0d47..81a0de87 100644 --- a/content/articles/2021/2021-09-06-using-openapi-cli-custom-rules/index.md +++ b/content/articles/2021/2021-09-06-using-openapi-cli-custom-rules/index.md @@ -208,6 +208,6 @@ Hmm, looks confusing. Thanks to `suggest` we can at least see that something was Finally, to make linter passing, we need to fix the preprocessor plugin code [commit 81a4332](https://github.com/aviskase/openapi-cli-examples/tree/81a43321ae607fd20afd5abe4922fc86fa0fcce0). -{{< cta >}} +{{< callout type="cta" >}} Rules are cooler than preprocessors and decorators: they support nested visitors. I'll cover this concept in the next article. Until then, try to come up with an example where the uppercase rule in its current form might have undesired behavior. -{{< /cta >}} +{{< /callout >}} diff --git a/layouts/shortcodes/callout.html b/layouts/shortcodes/callout.html new file mode 100644 index 00000000..3d2bde90 --- /dev/null +++ b/layouts/shortcodes/callout.html @@ -0,0 +1,27 @@ +{{/* Available callout types: note, warning, cta */}} +{{- $calloutType := .Get "type" | default "note" -}} +{{- $color := "indigo" -}} +{{- if eq $calloutType "note" }} + {{- $color = "indigo" -}} +{{- else if eq $calloutType "warning" }} + {{- $color = "rose" -}} +{{- else if eq $calloutType "cta" -}} + {{- $color = "yellow" -}} +{{- else -}} + {{ errorf "Unknown callout type." }} +{{- end -}} +{{/* Check for single vs multiple paragraphs */}} +{{- $raw := .Inner | $.Page.RenderString | chomp -}} +{{- $isBlock := findRE "<[h|p][^>]*>" $raw -}} +
+
+ {{- if eq $calloutType "warning" }} + + {{- else if eq $calloutType "cta" -}} + + {{- else -}} + + {{- end -}} +
+ {{- if $isBlock }}{{ $raw }}{{ else }}

{{ $raw }}

{{ end -}} +
\ No newline at end of file diff --git a/layouts/shortcodes/cta.html b/layouts/shortcodes/cta.html deleted file mode 100644 index af6233d7..00000000 --- a/layouts/shortcodes/cta.html +++ /dev/null @@ -1,9 +0,0 @@ -
-
- {{- $markdown := .Inner | $.Page.RenderString -}} - {{ if not ( findRE "<[h|p][^>]*>" $markdown ) }} -

{{ $markdown }}

- {{ else }} - {{ $markdown }} - {{ end }} -
diff --git a/layouts/shortcodes/note.html b/layouts/shortcodes/note.html deleted file mode 100644 index d2fc4779..00000000 --- a/layouts/shortcodes/note.html +++ /dev/null @@ -1,9 +0,0 @@ -
-
- {{- $markdown := .Inner | $.Page.RenderString -}} - {{ if not ( findRE "<[h|p][^>]*>" $markdown ) }} -

{{ $markdown }}

- {{ else }} - {{ $markdown }} - {{ end }} -
\ No newline at end of file diff --git a/layouts/shortcodes/warning.html b/layouts/shortcodes/warning.html deleted file mode 100644 index 1cde93c9..00000000 --- a/layouts/shortcodes/warning.html +++ /dev/null @@ -1,9 +0,0 @@ -
-
- {{- $markdown := .Inner | $.Page.RenderString -}} - {{ if not ( findRE "<[h|p][^>]*>" $markdown ) }} -

{{ $markdown }}

- {{ else }} - {{ $markdown }} - {{ end }} -
\ No newline at end of file