diff --git a/templates/README.md b/templates/README.md
new file mode 100644
index 0000000..4ce7c52
--- /dev/null
+++ b/templates/README.md
@@ -0,0 +1,64 @@
+## Swagger / OpenAPI 2 and OpenAPI 3 template parameters
+
+Note that properties of OpenAPI objects will be in OpenAPI 3.0 form, as
+Swagger / OpenAPI 2.0 definitions are converted automatically.
+
+### Code templates
+
+* `method` - the HTTP method of the operation (in lower-case)
+* `methodUpper` - the HTTP method of the operation (in upper-case)
+* `url` - the full URL of the operation (including protocol and host)
+* `consumes[]` - an array of MIME-types the operation consumes
+* `produces[]` - an array of MIME-types the operation produces
+* `operation` - the current operation object
+* `operationId` - the current operation id
+* `opName` - the operationId if set, otherwise the method + path
+* `tags[]` - the full list of tags applying to the operation
+* `security` - the security definitions applying to the operation
+* `resource` - the current tag/path object
+* `parameters[]` - an array of parameters for the operation (see below)
+* `queryString` - an example queryString, urlEncoded
+* `requiredQueryString` - an example queryString for `required:true` parameters
+* `queryParameters[]` - a subset of `parameters` that are `in:query`
+* `requiredParameters[]` - a subset of `queryParameters` that are `required:true`
+* `headerParameters[]` - a subset of `parameters` that are `in:header`
+* `allHeaders[]` - a concatenation of `headerParameters` and pseudo-parameters `Accept` and `Content-Type`, and optionally `Authorization` (the latter has an `isAuth` boolean property set true so it can be omitted in templates if desired
+
+### Parameter template
+
+* `parameters[]` - an array of [parameters](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject), including the following pseudo-properties
+ * `shortDesc` - a truncated version of the parameter description
+ * `safeType` - a computed version of the parameter type, including Body and schema names
+ * `originalType` - the original type of the parameter
+ * `exampleValues` - an object containing examples for use in code-templates
+ * `json` - example values in JSON compatible syntax
+ * `object` - example values in raw object form (unquoted strings etc)
+ * `depth` - a zero-based indicator of the depth of expanded request body parameters
+* `enums[]` - an array of (parameter)name/value pairs
+
+### Responses template
+
+* `responses[]` - an array of [responses](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject), including `status` and `meaning` properties
+
+### Authentication template
+
+* `authenticationStr` - a simple string of methods (and scopes where appropriate)
+* `securityDefinitions[]` - an array of applicable [securityDefinitions](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securityRequirementObject)
+
+### Schema Property template
+
+* `schemaProperties[]` - an array of
+ * `name`
+ * `type`
+ * `required`
+ * `description`
+* `enums[]` - an array of (schema property)name/value pairs
+
+### Common to all templates
+
+* `openapi` - the top-level OpenAPI / Swagger document
+* `header` - the front-matter of the Slate/Shins markdown document
+* `host` - the (computed) host of the API
+* `protocol` - the default/first protocol of the API
+* `baseUrl` - the (computed) baseUrl of the API (including protocol and host)
+* `widdershins` - the contents of widdershins `package.json`
diff --git a/templates/authentication.def b/templates/authentication.def
new file mode 100644
index 0000000..6b039e5
--- /dev/null
+++ b/templates/authentication.def
@@ -0,0 +1,5 @@
+
+
diff --git a/templates/authentication_none.def b/templates/authentication_none.def
new file mode 100644
index 0000000..ddb19cf
--- /dev/null
+++ b/templates/authentication_none.def
@@ -0,0 +1,3 @@
+
diff --git a/templates/callbacks.def b/templates/callbacks.def
new file mode 100644
index 0000000..77873e3
--- /dev/null
+++ b/templates/callbacks.def
@@ -0,0 +1,38 @@
+{{? typeof data.operation.callbacks === 'object'}}
+
+### Callbacks
+
+{{ data.operationStack.push(data.operation); }}
+
+{{ for (var c of Object.keys(data.operation.callbacks)) { }}
+
+#### {{=c}}
+
+{{ var callback = data.operation.callbacks && data.operation.callbacks[c]; }}
+
+{{ for (var e in callback) { }}
+{{ if (!e.startsWith('x-widdershins-')) { }}
+
+**{{=e}}**
+
+{{ var exp = callback[e]; }}
+
+{{ for (var m in exp) { }}
+
+{{ data.operation = exp[m]; }}
+{{ data.method.operation = data.operation; }}
+
+{{= data.templates.operation(data) }}
+
+{{ } /* of methods */ }}
+
+{{ } /* of expressions */ }}
+
+{{ } /* of if */ }}
+
+{{ } /* of callbacks */ }}
+
+{{ data.operation = data.operationStack.pop(); }}
+{{ data.method.operation = data.operation; }}
+
+{{?}}
diff --git a/templates/code_csharp.dot b/templates/code_csharp.dot
new file mode 100644
index 0000000..39597ad
--- /dev/null
+++ b/templates/code_csharp.dot
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+/// <>
+/// Example of Http Client
+/// <>
+public class HttpExample
+{
+ private HttpClient Client { get; set; }
+
+ /// <>
+ /// Setup http client
+ /// <>
+ public HttpExample()
+ {
+ Client = new HttpClient();
+ }
+ {{? data.methodUpper == "GET"}}
+ /// Make a dummy request
+ public async Task MakeGetRequest()
+ {
+ string url = "{{=data.url}}";
+ var result = await GetAsync(url);
+ }
+
+ /// Performs a GET Request
+ public async Task GetAsync(string url)
+ {
+ //Start the request
+ HttpResponseMessage response = await Client.GetAsync(url);
+
+ //Validate result
+ response.EnsureSuccessStatusCode();
+
+ }{{? }}
+ {{? data.methodUpper == "POST"}}
+ /// Make a dummy request
+ public async Task MakePostRequest()
+ {
+ string url = "{{=data.url}}";
+ {{? data.bodyParameter.refName !== undefined }}
+ string json = @"{{=data.bodyParameter.exampleValues.json.replace(new RegExp('"', "g"), '""')}}";
+ {{=data.bodyParameter.refName}} content = JsonConvert.DeserializeObject(json);
+ await PostAsync(content, url);
+ {{? }}
+ {{? data.bodyParameter.refName === undefined }}
+ await PostAsync(null, url);
+ {{? }}
+ }
+
+ /// Performs a POST Request
+ public async Task PostAsync({{=data.bodyParameter.refName}} content, string url)
+ {
+ //Serialize Object
+ StringContent jsonContent = SerializeObject(content);
+
+ //Execute POST request
+ HttpResponseMessage response = await Client.PostAsync(url, jsonContent);
+ }{{? }}
+ {{? data.methodUpper == "PUT"}}
+ /// Make a dummy request
+ public async Task MakePutRequest()
+ {
+ int id = 1;
+ string url = "{{=data.url}}";
+
+ {{? data.bodyParameter.refName !== undefined }}
+ string json = @"{{=data.bodyParameter.exampleValues.json.replace(new RegExp('"', "g"), '""')}}";
+ {{=data.bodyParameter.refName}} content = JsonConvert.DeserializeObject(json);
+ var result = await PutAsync(id, content, url);
+ {{? }}
+ {{? data.bodyParameter.refName === undefined }}
+ var result = await PutAsync(id, null, url);
+ {{? }}
+ }
+
+ /// Performs a PUT Request
+ public async Task PutAsync(int id, {{=data.bodyParameter.refName}} content, string url)
+ {
+ //Serialize Object
+ StringContent jsonContent = SerializeObject(content);
+
+ //Execute PUT request
+ HttpResponseMessage response = await Client.PutAsync(url + $"/{id}", jsonContent);
+
+ //Return response
+ return await DeserializeObject(response);
+ }{{? }}
+ {{? data.methodUpper == "DELETE"}}
+ /// Make a dummy request
+ public async Task MakeDeleteRequest()
+ {
+ int id = 1;
+ string url = "{{=data.url}}";
+
+ await DeleteAsync(id, url);
+ }
+
+ /// Performs a DELETE Request
+ public async Task DeleteAsync(int id, string url)
+ {
+ //Execute DELETE request
+ HttpResponseMessage response = await Client.DeleteAsync(url + $"/{id}");
+
+ //Return response
+ await DeserializeObject(response);
+ }{{? }}
+ {{? data.methodUpper == "POST" || data.methodUpper == "PUT"}}
+ /// Serialize an object to Json
+ private StringContent SerializeObject({{=data.bodyParameter.refName}} content)
+ {
+ //Serialize Object
+ string jsonObject = JsonConvert.SerializeObject(content);
+
+ //Create Json UTF8 String Content
+ return new StringContent(jsonObject, Encoding.UTF8, "application/json");
+ }
+ {{? }}
+ /// Deserialize object from request response
+ private async Task DeserializeObject(HttpResponseMessage response)
+ {
+ //Read body
+ string responseBody = await response.Content.ReadAsStringAsync();
+
+ //Deserialize Body to object
+ var result = JsonConvert.DeserializeObject(responseBody);
+ }
+}
diff --git a/templates/code_go.dot b/templates/code_go.dot
new file mode 100644
index 0000000..0f5a33f
--- /dev/null
+++ b/templates/code_go.dot
@@ -0,0 +1,21 @@
+package main
+
+import (
+ "bytes"
+ "net/http"
+)
+
+func main() {
+{{?data.allHeaders.length}}
+ headers := map[string][]string{
+ {{~data.allHeaders :p:index}}"{{=p.name}}": []string{"{{=p.exampleValues.object}}"},{{?index < data.allHeaders.length-1}}
+ {{?}}{{~}}
+ }{{?}}
+
+ data := bytes.NewBuffer([]byte{jsonReq})
+ req, err := http.NewRequest("{{=data.methodUpper}}", "{{=data.url}}", data)
+ req.Header = headers
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+}
\ No newline at end of file
diff --git a/templates/code_http.dot b/templates/code_http.dot
new file mode 100644
index 0000000..74b0333
--- /dev/null
+++ b/templates/code_http.dot
@@ -0,0 +1,7 @@
+{{=data.methodUpper}} {{=data.url}}{{=data.requiredQueryString}} HTTP/1.1
+{{? data.host}}Host: {{=data.host}}{{?}}
+{{?data.consumes.length}}Content-Type: {{=data.consumes[0]}}
+{{?}}{{?data.produces.length}}Accept: {{=data.produces[0]}}{{?}}
+{{?data.headerParameters.length}}{{~ data.headerParameters :p:index}}{{=p.name}}: {{=p.exampleValues.object}}
+{{~}}
+{{?}}
diff --git a/templates/code_java.dot b/templates/code_java.dot
new file mode 100644
index 0000000..8d61d00
--- /dev/null
+++ b/templates/code_java.dot
@@ -0,0 +1,13 @@
+URL obj = new URL("{{=data.url}}{{=data.requiredQueryString}}");
+HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+con.setRequestMethod("{{=data.methodUpper}}");
+int responseCode = con.getResponseCode();
+BufferedReader in = new BufferedReader(
+ new InputStreamReader(con.getInputStream()));
+String inputLine;
+StringBuffer response = new StringBuffer();
+while ((inputLine = in.readLine()) != null) {
+ response.append(inputLine);
+}
+in.close();
+System.out.println(response.toString());
diff --git a/templates/code_javascript.dot b/templates/code_javascript.dot
new file mode 100644
index 0000000..32b74f4
--- /dev/null
+++ b/templates/code_javascript.dot
@@ -0,0 +1,9 @@
+{{?data.bodyParameter.present}}const inputBody = '{{=data.bodyParameter.exampleValues.json}}';{{?}}{{?data.allHeaders.length}}const headers = {
+{{~data.allHeaders :p:index}} '{{=p.name}}':{{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}}
+{{~}}};
+{{?}}
+const response = await fetch('{{=data.url}}{{=data.requiredQueryString}}', {
+ method: '{{=data.methodUpper}}'{{?data.bodyParameter.present || data.allHeaders.length}},{{?}}{{?data.bodyParameter.present}} body: inputBody{{?}}{{? data.bodyParameter.present && data.allHeaders.length}},{{?}}{{?data.allHeaders.length}} headers: headers{{?}}
+})
+
+const body = await response.json()
\ No newline at end of file
diff --git a/templates/code_jquery.dot b/templates/code_jquery.dot
new file mode 100644
index 0000000..06d2641
--- /dev/null
+++ b/templates/code_jquery.dot
@@ -0,0 +1,14 @@
+{{?data.allHeaders.length}}var headers = {
+{{~data.allHeaders :p:index}} '{{=p.name}}':{{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}}
+{{~}}
+};
+{{?}}
+$.ajax({
+ url: '{{=data.url}}',
+ method: '{{=data.method.verb}}',
+{{?data.requiredQueryString}} data: '{{=data.requiredQueryString}}',{{?}}
+{{?data.allHeaders.length}} headers: headers,{{?}}
+ success: function(data) {
+ console.log(JSON.stringify(data));
+ }
+})
diff --git a/templates/code_nodejs.dot b/templates/code_nodejs.dot
new file mode 100644
index 0000000..876d4bf
--- /dev/null
+++ b/templates/code_nodejs.dot
@@ -0,0 +1,17 @@
+const fetch = require('node-fetch');
+{{?data.bodyParameter.present}}const inputBody = {{=data.bodyParameter.exampleValues.json}};{{?}}
+{{?data.allHeaders.length}}const headers = {
+{{~data.allHeaders :p:index}} '{{=p.name}}':{{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}}
+{{~}}};
+{{?}}
+fetch('{{=data.url}}{{=data.requiredQueryString}}',
+{
+ method: '{{=data.methodUpper}}'{{?data.bodyParameter.present || data.allHeaders.length}},{{?}}
+{{?data.bodyParameter.present}} body: JSON.stringify(inputBody){{?}}{{? data.bodyParameter.present && data.allHeaders.length}},{{?}}
+{{?data.allHeaders.length}} headers: headers{{?}}
+})
+.then(function(res) {
+ return res.json();
+}).then(function(body) {
+ console.log(body);
+});
diff --git a/templates/code_php.dot b/templates/code_php.dot
new file mode 100644
index 0000000..5802466
--- /dev/null
+++ b/templates/code_php.dot
@@ -0,0 +1,28 @@
+ '{{=p.exampleValues.object}}',
+{{?index < data.allHeaders.length-1}} {{?}}{{~}});{{?}}
+
+$client = new \GuzzleHttp\Client();
+
+// Define array of request body.
+$request_body = array();
+
+try {
+ $response = $client->request('{{=data.methodUpper}}','{{=data.url}}', array(
+ 'headers' => $headers,
+ 'json' => $request_body,
+ )
+ );
+ print_r($response->getBody()->getContents());
+ }
+ catch (\GuzzleHttp\Exception\BadResponseException $e) {
+ // handle exception or api errors.
+ print_r($e->getMessage());
+ }
+
+ // ...
diff --git a/templates/code_python.dot b/templates/code_python.dot
new file mode 100644
index 0000000..1282b61
--- /dev/null
+++ b/templates/code_python.dot
@@ -0,0 +1,8 @@
+import requests
+{{?data.allHeaders.length}}headers = {
+{{~data.allHeaders :p:index}} '{{=p.name}}': {{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}}
+{{~}}}
+{{?}}
+r = requests.{{=data.method.verb}}('{{=data.url}}'{{? data.requiredParameters.length}}, params={
+{{~ data.requiredParameters :p:index}} '{{=p.name}}': {{=p.exampleValues.json}}{{? data.requiredParameters.length-1 != index }},{{?}}{{~}}
+}{{?}}{{?data.allHeaders.length}}, headers = headers{{?}})
\ No newline at end of file
diff --git a/templates/code_ruby.dot b/templates/code_ruby.dot
new file mode 100644
index 0000000..172219d
--- /dev/null
+++ b/templates/code_ruby.dot
@@ -0,0 +1,14 @@
+require 'rest-client'
+require 'json'
+
+{{?data.allHeaders.length}}headers = {
+{{~data.allHeaders :p:index}} '{{=p.name}}' => {{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}}
+{{~}}}{{?}}
+
+result = RestClient.{{=data.method.verb}} '{{=data.url}}',
+ params: {
+ {{~ data.requiredParameters :p:index}}'{{=p.name}}' => '{{=p.safeType}}'{{? data.requiredParameters.length-1 != index }},{{?}}
+{{~}}}{{? data.allHeaders.length}}, headers: headers
+{{?}}
+
+p JSON.parse(result)
diff --git a/templates/code_shell.dot b/templates/code_shell.dot
new file mode 100644
index 0000000..9934692
--- /dev/null
+++ b/templates/code_shell.dot
@@ -0,0 +1,3 @@
+curl -X {{=data.methodUpper}} {{=data.url}}{{=data.requiredQueryString}}{{?data.allHeaders.length}} \{{?}}
+{{~data.allHeaders :p:index}} -H '{{=p.name}}: {{=p.exampleValues.object}}'{{?index < data.allHeaders.length-1}} \{{?}}
+{{~}}
diff --git a/templates/debug.def b/templates/debug.def
new file mode 100644
index 0000000..04fcf8f
--- /dev/null
+++ b/templates/debug.def
@@ -0,0 +1 @@
+{{= data.utils.inspect(data) }}
diff --git a/templates/discovery.def b/templates/discovery.def
new file mode 100644
index 0000000..4755a7b
--- /dev/null
+++ b/templates/discovery.def
@@ -0,0 +1,11 @@
+
diff --git a/templates/footer.def b/templates/footer.def
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/templates/footer.def
@@ -0,0 +1,2 @@
+
+
diff --git a/templates/links.def b/templates/links.def
new file mode 100644
index 0000000..990e130
--- /dev/null
+++ b/templates/links.def
@@ -0,0 +1,18 @@
+{{? data.response.links }}
+
+#### Links
+
+{{ for (var l in data.response.links) { }}
+{{ var link = data.response.links[l]; }}
+
+**{{=l}}** => {{?link.operationId}}{{=link.operationId}}{{??}}{{=link.operationRef}}{{?}}
+
+{{? link.parameters }}
+|Parameter|Expression|
+|---|---|
+{{for (var p in link.parameters) { }}|{{=p}}|{{=link.parameters[p]}}|{{ } }}
+{{?}}
+
+{{ } /* of links */ }}
+
+{{?}}
diff --git a/templates/main.dot b/templates/main.dot
new file mode 100644
index 0000000..2c3a218
--- /dev/null
+++ b/templates/main.dot
@@ -0,0 +1,138 @@
+{{= data.tags.section }}
+
+# Endpoints
+
+> Scroll down for {{? data.header.language_tabs.length}}code samples, {{?}}example requests and responses.{{? data.header.language_tabs.length}} Select a language for code samples from the tabs above or the mobile navigation menu.{{?}}
+
+{{? data.api.info && data.api.info.description}}{{=data.api.info.description}}{{?}}
+
+{{? data.api.servers }}
+Base URLs:
+{{~data.api.servers :s}}
+* {{=s.url}}
+{{ for(var v in s.variables) { }}
+ * **{{=v}}** - {{=s.variables[v].description||''}} Default: {{=s.variables[v].default}}
+{{? s.variables[v].enum}}
+{{~ s.variables[v].enum :e}}
+ * {{= e}}
+{{~}}
+{{?}}
+{{ } }}
+{{~}}
+{{?}}
+
+{{? data.api.info && data.api.info.termsOfService}}Terms of service{{?}}
+{{? data.api.info && data.api.info.contact}}{{? data.api.info.contact.email}}Email: {{=data.api.info.contact.name || 'Support'}} {{?}}{{? data.api.info.contact.url}}Web: {{= data.api.info.contact.name || 'Support'}} {{?}}{{?}}
+{{? data.api.info && data.api.info.license}}{{? data.api.info.license.url}}License: {{=data.api.info.license.name}}{{??}} License: {{=data.api.info.license.name}}{{?}}{{?}}
+{{= data.tags.endSection }}
+
+{{? data.api.components && data.api.components.securitySchemes }}
+{{#def.security}}
+{{?}}
+
+{{= data.tags.section }}
+
+
+{{ for (var r in data.resources) { }}
+{{ data.resource = data.resources[r]; }}
+
+### {{= r}}
+
+{{? data.resource.description }}{{= data.resource.description}}{{?}}
+
+{{? data.resource.externalDocs}}
+{{=data.resource.externalDocs.description||'External documentation'}}
+{{?}}
+
+{{ for (var m in data.resource.methods) { }}
+{{ data.operationUniqueName = m; }}
+{{ data.method = data.resource.methods[m]; }}
+{{ data.operationUniqueSlug = data.method.slug; }}
+{{ data.operation = data.method.operation; }}
+
+{{= data.templates.operation(data) }}
+{{ } /* of methods */ }}
+
+{{= data.tags.endSection }}
+{{ } /* of resources */ }}
+
+{{? data.api.components && data.api.components.schemas }}
+{{= data.tags.section }}
+
+## Schemas
+
+{{ for (var s in data.components.schemas) { }}
+{{ var origSchema = data.components.schemas[s]; }}
+{{ var schema = data.api.components.schemas[s]; }}
+
+{{= data.tags.section }}
+
+### {{= s}}
+
+{{? data.options.yaml }}
+```yaml
+{{=data.utils.yaml.stringify(data.utils.getSample(schema,data.options,{quiet:true},data.api))}}
+{{??}}
+```json
+{{=data.utils.safejson(data.utils.getSample(schema,data.options,{quiet:true},data.api),null,2)}}{{?}}
+```
+
+{{ var enums = []; }}
+{{ var blocks = data.utils.schemaToArray(origSchema,-1,{trim:true,join:true},data); }}
+{{ for (var block of blocks) {
+ for (var p of block.rows) {
+ if (p.schema && p.schema.enum) {
+ for (var e of p.schema.enum) {
+ enums.push({name:p.name,value:e});
+ }
+ }
+ }
+ }
+}}
+
+{{~ blocks :block}}
+{{? block.title }}{{= block.title}}{{= '\n\n'}}{{?}}
+{{? block.externalDocs}}
+{{=block.externalDocs.description||'External documentation'}}
+{{?}}
+
+{{? block===blocks[0] }}
+{{= data.tags.section }}
+
+**Properties**
+{{?}}
+
+{{? block.rows.length}}|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|{{?}}
+{{~ block.rows :p}}|{{=p.displayName}}|{{=p.safeType}}|{{=p.required}}|{{=p.restrictions||'none'}}|{{=p.description||'none'}}|
+{{~}}
+{{~}}
+{{? (blocks[0].rows.length === 0) && (blocks.length === 1) }}
+*None*
+{{?}}
+
+{{? enums.length > 0 }}
+{{= data.tags.section }}
+
+**Enumerated Values**
+
+|Property|Value|
+|---|---|
+{{~ enums :e}}|{{=e.name}}|{{=data.utils.toPrimitive(e.value)}}|
+{{~}}
+
+{{= data.tags.endSection }}
+{{?}}
+
+{{= data.tags.endSection }}
+{{= data.tags.endSection }}
+
+{{ } /* of schemas */ }}
+
+{{?}}
+
+{{#def.footer}}
+
+{{? data.options.discovery}}
+{{#def.discovery}}
+{{?}}
diff --git a/templates/operation.dot b/templates/operation.dot
new file mode 100644
index 0000000..cfd5b63
--- /dev/null
+++ b/templates/operation.dot
@@ -0,0 +1,49 @@
+{{= data.tags.section }}
+
+{{ data.methodUpper = data.method.verb.toUpperCase(); }}
+{{ data.url = data.utils.slashes(data.baseUrl + data.method.path); }}
+{{ data.parameters = data.operation.parameters; }}
+{{ data.enums = []; }}
+{{ data.utils.fakeProdCons(data); }}
+{{ data.utils.fakeBodyParameter(data); }}
+{{ data.utils.mergePathParameters(data); }}
+{{ data.utils.getParameters(data); }}
+
+#### {{= data.methodUpper}} {{=data.method.path}}
+
+{{? data.operation.summary && !data.options.tocSummary}}*{{= data.operation.summary }}*{{?}}
+
+{{? data.operation.description}}{{= data.operation.description }}{{?}}
+
+{{? data.options.codeSamples || data.operation["x-code-samples"] }}
+
+{{= data.utils.getCodeSamples(data) }}
+{{?}}
+
+{{? data.operation.requestBody}}
+Body
+
+{{? data.bodyParameter.exampleValues.description }}
+> {{= data.bodyParameter.exampleValues.description }}
+{{?}}
+
+{{= data.utils.getBodyParameterExamples(data) }}
+{{?}}
+
+{{? data.parameters && data.parameters.length }}
+{{#def.parameters}}
+{{?}}
+
+{{#def.responses}}
+
+{{#def.callbacks}}
+
+{{ data.security = data.operation.security ? data.operation.security : data.api.security; }}
+{{? data.security && data.security.length }}
+{{#def.authentication}}
+{{??}}
+{{#def.authentication_none}}
+{{?}}
+
+
+{{= data.tags.endSection }}
diff --git a/templates/parameters.def b/templates/parameters.def
new file mode 100644
index 0000000..8df3b31
--- /dev/null
+++ b/templates/parameters.def
@@ -0,0 +1,40 @@
+{{= data.tags.section }}
+
Parameters
+
+|Name|In|Type|Required|Description|
+|---|---|---|---|---|
+{{~ data.parameters :p}}|{{=p.name}}|{{=p.in}}|{{=p.safeType}}|{{? p.required === true }}✔{{?? }} ❌ {{? }}|{{=p.shortDesc || 'none'}}|
+{{~}}
+
+{{? data.longDescs }}
+#### Detailed descriptions
+{{~ data.parameters :p}}{{? p.shortDesc !== p.description}}
+**{{=p.name}}**: {{=p.description}}{{?}}
+{{~}}
+{{?}}
+
+{{~ data.parameters :p}}
+
+{{? p.schema && p.schema.enum }}
+{{~ p.schema.enum :e}}
+{{ var entry = {}; entry.name = p.name; entry.value = e; data.enums.push(entry); }}
+{{~}}
+{{?}}
+
+{{? p.schema && p.schema.items && p.schema.items.enum }}
+{{~ p.schema.items.enum :e}}
+{{ var entry = {}; entry.name = p.name; entry.value = e; data.enums.push(entry); }}
+{{~}}
+{{?}}
+
+{{~}}
+
+{{? data.enums && data.enums.length }}
+#### Enumerated Values
+
+|Parameter|Value|
+|---|---|
+{{~ data.enums :e}}|{{=e.name}}|{{=data.utils.toPrimitive(e.value)}}|
+{{~}}
+{{?}}
+{{= data.tags.endSection }}
diff --git a/templates/responses.def b/templates/responses.def
new file mode 100644
index 0000000..6a9846b
--- /dev/null
+++ b/templates/responses.def
@@ -0,0 +1,78 @@
+{{ data.responses = data.utils.getResponses(data); }}
+{{ data.responseSchemas = false; }}
+{{~ data.responses :response }}
+{{ if (response.content) data.responseSchemas = true; }}
+{{~}}
+
+{{? data.responseSchemas }}
+Responses
+
+{{= data.utils.getResponseExamples(data) }}
+{{?}}
+
+{{= data.tags.section }}
+
+|Status|Meaning|Description|Schema|
+|---|---|---|---|
+{{~ data.responses :r}}|{{=r.status}}|{{=r.meaning}}|{{=r.description || 'none'}}|{{=r.schema}}|
+{{~}}
+
+{{ data.responseSchemas = false; }}
+{{~ data.responses :response }}
+{{ if (response.content && !response.$ref && !data.utils.isPrimitive(response.type)) data.responseSchemas = true; }}
+{{~}}
+{{? data.responseSchemas }}
+Response Schema
+{{~ data.responses :response}}
+{{? response.content && !response.$ref && !data.utils.isPrimitive(response.type)}}
+{{? Object.keys(response.content).length }}
+{{ var responseKey = Object.keys(response.content)[0]; }}
+{{ var responseSchema = response.content[responseKey].schema; }}
+{{ var enums = []; }}
+{{ var blocks = data.utils.schemaToArray(responseSchema,0,{trim:true,join:true},data); }}
+{{ for (var block of blocks) {
+ for (var p of block.rows) {
+ if (p.schema && p.schema.enum) {
+ for (var e of p.schema.enum) {
+ enums.push({name:p.name,value:e});
+ }
+ }
+ }
+ }
+}}
+
+{{? blocks[0].rows.length || blocks[0].title }}
+Status Code **{{=response.status}}**
+
+{{~ blocks :block}}
+{{? block.title }}*{{=block.title}}*
+{{?}}
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+{{~block.rows :p}}|{{=p.displayName}}|{{=p.safeType}}|{{=p.required}}|{{=p.restrictions||'none'}}|{{=p.description||'none'}}|
+{{~}}
+{{~}}
+{{?}}
+
+
+{{?}}
+
+{{ data.response = response; }}
+{{#def.links}}
+
+{{?}}
+{{~}}
+{{?}}
+
+{{ data.responseHeaders = data.utils.getResponseHeaders(data); }}
+{{? data.responseHeaders.length }}
+
+### Response Headers
+
+|Status|Header|Type|Format|Description|
+|---|---|---|---|---|
+{{~ data.responseHeaders :h}}|{{=h.status}}|{{=h.header}}|{{=h.type}}|{{=h.format||''}}|{{=h.description||'none'}}|
+{{~}}
+
+{{?}}
+{{= data.tags.endSection }}
diff --git a/templates/security.def b/templates/security.def
new file mode 100644
index 0000000..2e83581
--- /dev/null
+++ b/templates/security.def
@@ -0,0 +1,31 @@
+{{= data.tags.section }}
+
+# Authentication
+
+{{ for (var s in data.api.components.securitySchemes) { }}
+{{ var sd = data.api.components.securitySchemes[s]; }}
+{{? sd.type == 'apiKey' }}
+* API Key ({{=s}})
+ - Parameter Name: **{{=sd.name}}**, in: {{=sd.in}}. {{=sd.description || ''}}
+{{?}}
+{{? sd.type == 'http'}}
+- HTTP Authentication, scheme: {{=sd.scheme}}{{? sd.description }}
{{=sd.description}}{{?}}
+{{?}}
+{{? sd.type == 'oauth2'}}
+- oAuth2 authentication. {{=sd.description || ''}}
+{{ for (var f in sd.flows) { }}
+{{ var flow = sd.flows[f]; }}
+ - Flow: {{=f}}
+{{? flow.authorizationUrl}} - Authorization URL = [{{=flow.authorizationUrl}}]({{=flow.authorizationUrl}}){{?}}
+{{? flow.tokenUrl}} - Token URL = [{{=flow.tokenUrl}}]({{=flow.tokenUrl}}){{?}}
+{{? flow.scopes && Object.keys(flow.scopes).length}}
+|Scope|Scope Description|
+|---|---|
+{{ for (var sc in flow.scopes) { }}|{{=sc}}|{{=data.utils.join(flow.scopes[sc])}}|
+{{ } /* of scopes */ }}
+{{?}}
+{{ } /* of flows */ }}
+{{?}}
+{{ } /* of securitySchemes */ }}
+
+{{= data.tags.endSection }}
diff --git a/templates/translations.dot b/templates/translations.dot
new file mode 100644
index 0000000..b58e912
--- /dev/null
+++ b/templates/translations.dot
@@ -0,0 +1,19 @@
+{{
+data.translations.defaultTag = 'Default';
+data.translations.response = 'Response';
+data.translations.responseDefault = 'Default';
+data.translations.responseUnknown = 'Unknown';
+data.translations.schemaInline = 'Inline';
+data.translations.schemaNone = 'None';
+data.translations.externalDocs = 'External documentation';
+data.translations.secDefNone = 'None';
+data.translations.secDefScopes = 'Scopes';
+data.translations.anonymous = 'anonymous';
+data.translations.continued = 'continued';
+data.translations.indent = '»';
+data.translations.readOnly = 'read-only';
+data.translations.writeOnly = 'write-only';
+data.tags = {};
+data.tags.section = data.options.respec ? '' : '';
+data.tags.endSection = data.options.respec ? '' : '';
+}}