diff --git a/403/index.html b/403/index.html index b991352b..0484509e 100644 --- a/403/index.html +++ b/403/index.html @@ -7,13 +7,13 @@ - +
Skip to main content
404

You don't have access to that page.

You may need to refresh your login. Please log out and log back in.

- + \ No newline at end of file diff --git a/404.html b/404.html index 4bcd8ac2..708d6a66 100644 --- a/404.html +++ b/404.html @@ -7,13 +7,13 @@ - +
- + \ No newline at end of file diff --git a/404/index.html b/404/index.html index b096ee21..c790b35b 100644 --- a/404/index.html +++ b/404/index.html @@ -7,13 +7,13 @@ - +
Skip to main content
404

Uh oh. That page doesn’t exist.

Back to home.

- + \ No newline at end of file diff --git a/assets/js/018e43cb.27c12fa7.js b/assets/js/018e43cb.27c12fa7.js deleted file mode 100644 index 4f197ef2..00000000 --- a/assets/js/018e43cb.27c12fa7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[962],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var g=o.createContext({}),c=function(e){var t=o.useContext(g),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(g.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,g=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),f=a,d=u["".concat(g,".").concat(f)]||u[f]||s[f]||i;return n?o.createElement(d,r(r({ref:t},p),{},{components:n})):o.createElement(d,r({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=u;var l={};for(var g in t)hasOwnProperty.call(t,g)&&(l[g]=t[g]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>g,contentTitle:()=>r,default:()=>s,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var o=n(7462),a=(n(7294),n(3905));const i={},r="Logger Setup",l={unversionedId:"configuration/LOGGER_SETUP",id:"configuration/LOGGER_SETUP",title:"Logger Setup",description:"A Logger is just a class with a LoggerConfig instance and a default tag.",source:"@site/docs/configuration/LOGGER_SETUP.md",sourceDirName:"configuration",slug:"/configuration/LOGGER_SETUP",permalink:"/docs/configuration/LOGGER_SETUP",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/LOGGER_SETUP.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Configuration",permalink:"/docs/configuration/"},next:{title:"Message Formatting",permalink:"/docs/configuration/MESSAGE_FORMATTING"}},g={},c=[{value:"LoggerConfig",id:"loggerconfig",level:2},{value:"Where to do config?",id:"where-to-do-config",level:3},{value:"StaticConfig vs MutableLoggerConfig",id:"staticconfig-vs-mutableloggerconfig",level:2}],p={toc:c};function s(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"logger-setup"},"Logger Setup"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," is just a class with a ",(0,a.kt)("inlineCode",{parentName:"p"},"LoggerConfig")," instance and a default tag."),(0,a.kt)("p",null,"You can create your own instance of ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger"),", or configure and call the global ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instance."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'// Local\nval log = Logger(\n loggerConfigInit(platformLogWriter(NoTagLogFormatter)), \n "MyTag"\n)\nlog.i { "Hello Kotlin" }\n\n// Global\nLogger.setLogWriters(platformLogWriter(NoTagLogFormatter))\nLogger.setTag("MyTag")\nLogger.i { "Hello Kotlin" }\n')),(0,a.kt)("p",null,"Which method you choose is up to you, but obviously a local log instance will need to be made available for you code to call, while global is available everywhere. ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/touchlab/KaMPKit/blob/main/shared/src/iosMain/kotlin/co/touchlab/kampkit/KoinIOS.kt#L34"},"For example"),", our pattern has been to inject loggers into components, with the tag applied at that point, rather than specify the tag in each call."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'single { \n BreedCallbackViewModel(\n get(), \n getWith("BreedCallbackViewModel") // Convenience function to get a Logger with a tag set\n ) \n }\n')),(0,a.kt)("h2",{id:"loggerconfig"},"LoggerConfig"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"LoggerConfig")," defines the ",(0,a.kt)("inlineCode",{parentName:"p"},"minSeverity"),", below which log statements will be ignored, and ",(0,a.kt)("inlineCode",{parentName:"p"},"logWriterList"),", the collection of ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances that will be written to."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"interface LoggerConfig {\n val minSeverity: Severity\n val logWriterList: List\n}\n")),(0,a.kt)("p",null,"When creating our own ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instances above, we call ",(0,a.kt)("inlineCode",{parentName:"p"},"loggerConfigInit"),". That is a convenience function to create a ",(0,a.kt)("inlineCode",{parentName:"p"},"StaticConfig")," instance."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"fun loggerConfigInit(vararg logWriters: LogWriter, minSeverity: Severity = DEFAULT_MIN_SEVERITY): LoggerConfig =\n StaticConfig(logWriterList = logWriters.toList(), minSeverity = minSeverity)\n")),(0,a.kt)("h3",{id:"where-to-do-config"},"Where to do config?"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"platformLogWriter()")," is an ",(0,a.kt)("inlineCode",{parentName:"p"},"expect"),"/",(0,a.kt)("inlineCode",{parentName:"p"},"actual")," factory function. You can call it in common code, and it will create a ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," designed for the platform the code is running on."),(0,a.kt)("p",null,"For more complex configuration, you'll either need platform-specific entry points, or possibly your own ",(0,a.kt)("inlineCode",{parentName:"p"},"expect"),"/",(0,a.kt)("inlineCode",{parentName:"p"},"actual")," factory function(s)."),(0,a.kt)("h2",{id:"staticconfig-vs-mutableloggerconfig"},"StaticConfig vs MutableLoggerConfig"),(0,a.kt)("p",null,"For most use cases, once your logger is set up, you won't need to change the config. ",(0,a.kt)("inlineCode",{parentName:"p"},"StaticConfig")," has values that can't be changed once initializd. That is what you want when creating a local ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instance."),(0,a.kt)("p",null,"The global ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," uses ",(0,a.kt)("inlineCode",{parentName:"p"},"MutableLoggerConfig"),", because values need to be changed after that instance has been initialized. It is also possible that you have a use case where the config of your local ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instance needs to be changed after the instance is created. In that case, you can use ",(0,a.kt)("inlineCode",{parentName:"p"},"MutableLoggerConfig")," instead of ",(0,a.kt)("inlineCode",{parentName:"p"},"StaticConfig"),"."),(0,a.kt)("admonition",{title:"Why have StaticConfig at all?",type:"info"},(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instances are thread-safe, so ",(0,a.kt)("inlineCode",{parentName:"p"},"MutableLoggerConfig")," needs to be thread-safe. That means config fields are volatile on the JVM and Atomic on native platforms. While the performance impact is likely negligable, if you want to maximize performance, static is better.")),(0,a.kt)("p",null,"If you really like global access, but want static config, you can just create your own global logger."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'object MyLogger : Logger(\n config = loggerConfigInit(\n platformLogWriter(NoTagLogFormatter),\n minSeverity = Severity.Info\n ),\n tag = "MyAppTag"\n)\n\nfun hello(){\n MyLogger.i { "Hello" }\n}\n')))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/018e43cb.8ba55a2b.js b/assets/js/018e43cb.8ba55a2b.js new file mode 100644 index 00000000..08f4e326 --- /dev/null +++ b/assets/js/018e43cb.8ba55a2b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[962],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var g=o.createContext({}),c=function(e){var t=o.useContext(g),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(g.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,g=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),f=a,d=u["".concat(g,".").concat(f)]||u[f]||s[f]||i;return n?o.createElement(d,r(r({ref:t},p),{},{components:n})):o.createElement(d,r({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=u;var l={};for(var g in t)hasOwnProperty.call(t,g)&&(l[g]=t[g]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>g,contentTitle:()=>r,default:()=>s,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var o=n(7462),a=(n(7294),n(3905));const i={},r="Logger Setup",l={unversionedId:"configuration/LOGGER_SETUP",id:"configuration/LOGGER_SETUP",title:"Logger Setup",description:"A Logger is just a class with a LoggerConfig instance and a default tag.",source:"@site/docs/configuration/LOGGER_SETUP.md",sourceDirName:"configuration",slug:"/configuration/LOGGER_SETUP",permalink:"/docs/configuration/LOGGER_SETUP",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/LOGGER_SETUP.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Configuration",permalink:"/docs/configuration/"},next:{title:"Message Formatting",permalink:"/docs/configuration/MESSAGE_FORMATTING"}},g={},c=[{value:"LoggerConfig",id:"loggerconfig",level:2},{value:"Where to do config?",id:"where-to-do-config",level:3},{value:"StaticConfig vs MutableLoggerConfig",id:"staticconfig-vs-mutableloggerconfig",level:2}],p={toc:c};function s(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"logger-setup"},"Logger Setup"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," is just a class with a ",(0,a.kt)("inlineCode",{parentName:"p"},"LoggerConfig")," instance and a default tag."),(0,a.kt)("p",null,"You can create your own instance of ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger"),", or configure and call the global ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instance."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'// Local\nval log = Logger(\n loggerConfigInit(platformLogWriter(NoTagLogFormatter)), \n "MyTag"\n)\nlog.i { "Hello Kotlin" }\n\n// Global\nLogger.setLogWriters(platformLogWriter(NoTagLogFormatter))\nLogger.setTag("MyTag")\nLogger.i { "Hello Kotlin" }\n')),(0,a.kt)("p",null,"Which method you choose is up to you, but obviously a local log instance will need to be made available for you code to call, while global is available everywhere. ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/touchlab/KaMPKit/blob/main/shared/src/iosMain/kotlin/co/touchlab/kampkit/KoinIOS.kt#L34"},"For example"),", our pattern has been to inject loggers into components, with the tag applied at that point, rather than specify the tag in each call."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'single { \n BreedCallbackViewModel(\n get(), \n getWith("BreedCallbackViewModel") // Convenience function to get a Logger with a tag set\n ) \n }\n')),(0,a.kt)("h2",{id:"loggerconfig"},"LoggerConfig"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"LoggerConfig")," defines the ",(0,a.kt)("inlineCode",{parentName:"p"},"minSeverity"),", below which log statements will be ignored, and ",(0,a.kt)("inlineCode",{parentName:"p"},"logWriterList"),", the collection of ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances that will be written to."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"interface LoggerConfig {\n val minSeverity: Severity\n val logWriterList: List\n}\n")),(0,a.kt)("p",null,"When creating our own ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instances above, we call ",(0,a.kt)("inlineCode",{parentName:"p"},"loggerConfigInit"),". That is a convenience function to create a ",(0,a.kt)("inlineCode",{parentName:"p"},"StaticConfig")," instance."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"fun loggerConfigInit(vararg logWriters: LogWriter, minSeverity: Severity = DEFAULT_MIN_SEVERITY): LoggerConfig =\n StaticConfig(logWriterList = logWriters.toList(), minSeverity = minSeverity)\n")),(0,a.kt)("h3",{id:"where-to-do-config"},"Where to do config?"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"platformLogWriter()")," is an ",(0,a.kt)("inlineCode",{parentName:"p"},"expect"),"/",(0,a.kt)("inlineCode",{parentName:"p"},"actual")," factory function. You can call it in common code, and it will create a ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," designed for the platform the code is running on."),(0,a.kt)("p",null,"For more complex configuration, you'll either need platform-specific entry points, or possibly your own ",(0,a.kt)("inlineCode",{parentName:"p"},"expect"),"/",(0,a.kt)("inlineCode",{parentName:"p"},"actual")," factory function(s)."),(0,a.kt)("h2",{id:"staticconfig-vs-mutableloggerconfig"},"StaticConfig vs MutableLoggerConfig"),(0,a.kt)("p",null,"For most use cases, once your logger is set up, you won't need to change the config. ",(0,a.kt)("inlineCode",{parentName:"p"},"StaticConfig")," has values that can't be changed once initializd. That is what you want when creating a local ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instance."),(0,a.kt)("p",null,"The global ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," uses ",(0,a.kt)("inlineCode",{parentName:"p"},"MutableLoggerConfig"),", because values need to be changed after that instance has been initialized. It is also possible that you have a use case where the config of your local ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instance needs to be changed after the instance is created. In that case, you can use ",(0,a.kt)("inlineCode",{parentName:"p"},"MutableLoggerConfig")," instead of ",(0,a.kt)("inlineCode",{parentName:"p"},"StaticConfig"),"."),(0,a.kt)("admonition",{title:"Why have StaticConfig at all?",type:"info"},(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instances are thread-safe, so ",(0,a.kt)("inlineCode",{parentName:"p"},"MutableLoggerConfig")," needs to be thread-safe. That means config fields are volatile on the JVM and Atomic on native platforms. While the performance impact is likely negligable, if you want to maximize performance, static is better.")),(0,a.kt)("p",null,"If you really like global access, but want static config, you can just create your own global logger."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'object MyLogger : Logger(\n config = loggerConfigInit(\n platformLogWriter(NoTagLogFormatter),\n minSeverity = Severity.Info\n ),\n tag = "MyAppTag"\n)\n\nfun hello(){\n MyLogger.i { "Hello" }\n}\n')))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/14eb3368.bbe7cbed.js b/assets/js/14eb3368.bc29483f.js similarity index 96% rename from assets/js/14eb3368.bbe7cbed.js rename to assets/js/14eb3368.bc29483f.js index dc50fc8a..b6ac9719 100644 --- a/assets/js/14eb3368.bbe7cbed.js +++ b/assets/js/14eb3368.bc29483f.js @@ -1 +1 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[817],{1310:(e,t,a)=>{a.d(t,{Z:()=>g});var n=a(7462),l=a(7294),c=a(6010),r=a(5281),i=a(2802),s=a(8596),o=a(9960),m=a(5999),d=a(4996);function u(e){return l.createElement("svg",(0,n.Z)({viewBox:"0 0 24 24"},e),l.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const h="breadcrumbHomeIcon_YNFT";function v(){const e=(0,d.Z)("/");return l.createElement("li",{className:"breadcrumbs__item"},l.createElement(o.Z,{"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},l.createElement(u,{className:h})))}const b="breadcrumbsContainer_Z_bl";function p(e){let{children:t,href:a,isLast:n}=e;const c="breadcrumbs__link";return n?l.createElement("span",{className:c,itemProp:"name"},t):a?l.createElement(o.Z,{className:c,href:a,itemProp:"item"},l.createElement("span",{itemProp:"name"},t)):l.createElement("span",{className:c},t)}function E(e){let{children:t,active:a,index:r,addMicrodata:i}=e;return l.createElement("li",(0,n.Z)({},i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,c.Z)("breadcrumbs__item",{"breadcrumbs__item--active":a})}),t,l.createElement("meta",{itemProp:"position",content:String(r+1)}))}function g(){const e=(0,i.s1)(),t=(0,s.Ns)();return e?l.createElement("nav",{className:(0,c.Z)(r.k.docs.docBreadcrumbs,b),"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},l.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&l.createElement(v,null),e.map(((t,a)=>{const n=a===e.length-1;return l.createElement(E,{key:a,active:n,index:a,addMicrodata:!!t.href},l.createElement(p,{href:t.href,isLast:n},t.label))})))):null}},4228:(e,t,a)=>{a.r(t),a.d(t,{default:()=>z});var n=a(7294),l=a(1944),c=a(2802),r=a(4996),i=a(6010),s=a(9960),o=a(3919),m=a(5999);const d="cardContainer_fWXF",u="cardTitle_rnsV",h="cardDescription_PWke";function v(e){let{href:t,children:a}=e;return n.createElement(s.Z,{href:t,className:(0,i.Z)("card padding--lg",d)},a)}function b(e){let{href:t,icon:a,title:l,description:c}=e;return n.createElement(v,{href:t},n.createElement("h2",{className:(0,i.Z)("text--truncate",u),title:l},a," ",l),c&&n.createElement("p",{className:(0,i.Z)("text--truncate",h),title:c},c))}function p(e){let{item:t}=e;const a=(0,c.Wl)(t);return a?n.createElement(b,{href:a,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,m.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function E(e){let{item:t}=e;const a=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",l=(0,c.xz)(t.docId??void 0);return n.createElement(b,{href:t.href,icon:a,title:t.label,description:null==l?void 0:l.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(E,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const a=(0,c.jA)();return n.createElement(N,{items:a.items,className:t})}function N(e){const{items:t,className:a}=e;if(!t)return n.createElement(f,e);const l=(0,c.MN)(t);return n.createElement("section",{className:(0,i.Z)("row",a)},l.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}var Z=a(5797),x=a(3120),k=a(4364),y=a(1310),L=a(7955);const _="generatedIndexPage_vN6x",T="list_eTzJ",w="title_kItE";function C(e){let{categoryGeneratedIndex:t}=e;return n.createElement(l.d,{title:t.title,description:t.description,keywords:t.keywords,image:(0,r.Z)(t.image)})}function I(e){let{categoryGeneratedIndex:t}=e;const a=(0,c.jA)();return n.createElement("div",{className:_},n.createElement(x.Z,null),n.createElement(y.Z,null),n.createElement(k.Z,null),n.createElement("header",null,n.createElement(L.Z,{as:"h1",className:w},t.title),t.description&&n.createElement("p",null,t.description)),n.createElement("article",{className:"margin-top--lg"},n.createElement(N,{items:a.items,className:T})),n.createElement("footer",{className:"margin-top--lg"},n.createElement(Z.Z,{previous:t.navigation.previous,next:t.navigation.next})))}function z(e){return n.createElement(n.Fragment,null,n.createElement(C,e),n.createElement(I,e))}},4966:(e,t,a)=>{a.d(t,{Z:()=>o});var n=a(7462),l=a(7294),c=a(5999),r=a(6010),i=a(9960);function s(e){const{permalink:t,title:a,subLabel:n,isNext:c}=e;return l.createElement(i.Z,{className:(0,r.Z)("pagination-nav__link",c?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},n&&l.createElement("div",{className:"pagination-nav__sublabel"},n),l.createElement("div",{className:"pagination-nav__label"},a))}function o(e){const{previous:t,next:a}=e;return l.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages navigation",description:"The ARIA label for the docs pagination"})},t&&l.createElement(s,(0,n.Z)({},t,{subLabel:l.createElement(c.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),a&&l.createElement(s,(0,n.Z)({},a,{subLabel:l.createElement(c.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(6010),c=a(5999),r=a(5281),i=a(4477);function s(e){let{className:t}=e;const a=(0,i.E)();return a.badge?n.createElement("span",{className:(0,l.Z)(t,r.k.docs.docVersionBadge,"badge badge--secondary")},n.createElement(c.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:a.label}},"Version: {versionLabel}")):null}},3120:(e,t,a)=>{a.d(t,{Z:()=>p});var n=a(7294),l=a(6010),c=a(2263),r=a(9960),i=a(5999),s=a(143),o=a(5281),m=a(373),d=a(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(i.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(i.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function h(e){const t=u[e.versionMetadata.banner];return n.createElement(t,e)}function v(e){let{versionLabel:t,to:a,onClick:l}=e;return n.createElement(i.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:n.createElement("b",null,n.createElement(r.Z,{to:a,onClick:l},n.createElement(i.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function b(e){let{className:t,versionMetadata:a}=e;const{siteConfig:{title:r}}=(0,c.Z)(),{pluginId:i}=(0,s.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,m.J)(i),{latestDocSuggestion:u,latestVersionSuggestion:b}=(0,s.Jo)(i),p=u??(E=b).docs.find((e=>e.id===E.mainDocId));var E;return n.createElement("div",{className:(0,l.Z)(t,o.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},n.createElement("div",null,n.createElement(h,{siteTitle:r,versionMetadata:a})),n.createElement("div",{className:"margin-top--md"},n.createElement(v,{versionLabel:b.label,to:p.path,onClick:()=>d(b.name)})))}function p(e){let{className:t}=e;const a=(0,d.E)();return a.banner?n.createElement(b,{className:t,versionMetadata:a}):null}},7955:(e,t,a)=>{a.d(t,{Z:()=>d});var n=a(7462),l=a(7294),c=a(6010),r=a(5999),i=a(6668),s=a(9960);const o="anchorWithStickyNavbar_LWe7",m="anchorWithHideOnScrollNavbar_WYt5";function d(e){let{as:t,id:a,...d}=e;const{navbar:{hideOnScroll:u}}=(0,i.L)();if("h1"===t||!a)return l.createElement(t,(0,n.Z)({},d,{id:void 0}));const h=(0,r.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof d.children?d.children:a});return l.createElement(t,(0,n.Z)({},d,{className:(0,c.Z)("anchor",u?m:o,d.className),id:a}),d.children,l.createElement(s.Z,{className:"hash-link",to:`#${a}`,"aria-label":h,title:h},"\u200b"))}},5797:(e,t,a)=>{a.d(t,{Z:()=>r});var n=a(7294),l=a(4966);const c=function(){return n.createElement("section",null,n.createElement("div",{className:"max-w-6xl mx-auto px-4 sm:px-6"},n.createElement("div",{className:"relative bg-cyan-600 py-4 px-5 md:py-5 md:px-6"},n.createElement("div",{className:"absolute right-0 top-0 -ml-40 pointer-events-none","aria-hidden":"true"},n.createElement("svg",{width:"238",height:"110",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("defs",null,n.createElement("linearGradient",{id:"illustration-04",x1:"369.483",y1:"-84.633",x2:"139.954",y2:"-199.798",gradientUnits:"userSpaceOnUse"},n.createElement("stop",{stopColor:"#fff",stopOpacity:".01"}),n.createElement("stop",{offset:"1",stopColor:"#fff",stopOpacity:".24"}))),n.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M189.135 89.198c3.624 9.678 7.039 18.799 15.713 18.187 7.885-.548 19.733-2.523 33.152-5.256v2.04c-13.345 2.709-25.125 4.663-33.013 5.211-.331.023-.657.034-.975.034-9.441 0-13.176-9.972-16.792-19.627-3.571-9.536-6.946-18.545-15.389-16.96-13.086 2.455-24.348 3.539-37.385 4.794l-.024.002c-8.07.776-17.217 1.657-27.841 2.98-4.629.58-8.116 1.595-10.919 2.411l-.016.005c-6.68 1.947-10.032 2.924-14.897-6.267-3.62-6.842-8.541-7.827-14.24-8.967h-.001c-4.793-.959-10.225-2.046-15.65-6.76C40.64 52.141 15.48 20.345.66 0H3.13c14.82 20.254 39.089 50.863 49.042 59.515 5.023 4.367 9.956 5.354 14.73 6.31 5.94 1.187 11.552 2.31 15.616 9.991 3.443 6.51 5.39 7.141 9.773 6.057-3.311.19-5.726-1.455-8.768-7.374-3.533-6.876-8.064-7.803-13.8-8.976-4.642-.949-9.902-2.025-15.275-6.679C43.995 49.797 18.704 19.375 4.057 0h2.506C21.226 19.288 45.58 48.524 55.755 57.333c4.977 4.309 9.748 5.285 14.363 6.23l.005.001c5.763 1.178 11.206 2.292 15.178 10.021 3.255 6.333 5.085 6.977 9.146 5.928-3.035.107-5.304-1.569-8.148-7.27-3.45-6.913-7.822-7.829-13.359-8.988-4.49-.939-9.58-2.004-14.902-6.593C47.268 47.376 21.798 18.312 7.406 0h2.572c14.477 18.232 39.16 46.348 49.366 55.147 4.93 4.252 9.544 5.217 14.005 6.15h.002c5.583 1.17 10.856 2.273 14.737 10.053 1.853 3.713 3.336 5.515 4.959 6.027.993.312 2.15.164 3.558-.212-2.77.013-4.89-1.707-7.534-7.175-3.363-6.95-7.578-7.854-12.914-8.998h-.003c-4.34-.93-9.259-1.984-14.528-6.509C50.465 44.901 24.695 17.086 10.69 0h2.583C27.39 17.058 52.088 43.659 62.93 52.965c4.883 4.194 9.337 5.148 13.644 6.07l.002.001c5.404 1.158 10.508 2.253 14.297 10.083 1.74 3.6 3.195 5.421 4.712 5.906 1.453.463 3.288-.17 5.829-1.05l.005-.002c2.872-.995 6.804-2.356 12.263-2.776 10.687-.813 19.576-.84 28.174-.867 8.671-.027 16.548-.055 24.765-.913-6.672.214-13.232-.169-20.311-.59-8.482-.504-17.257-1.025-27.637-.582-5.471.237-9.134 1.68-12.076 2.838-5.4 2.127-8.165 2.774-11.971-5.607-3.193-7.03-7.09-7.908-12.025-9.019-4.044-.91-8.628-1.944-13.791-6.34C56.639 39.755 30.287 15.234 16.926 0h2.688c13.353 14.888 38.3 38.212 50.492 48.595 4.787 4.075 9.115 5.051 12.933 5.911 5.26 1.184 9.802 2.207 13.407 10.142 3.19 7.023 4.631 6.458 9.418 4.574l.002-.001c2.919-1.149 6.915-2.722 12.72-2.974 10.488-.448 19.311.076 27.841.583 9.399.56 17.871 1.054 26.886.14-7.662.148-15.028-.743-22.644-1.672l-.129-.016c-8.337-1.017-16.965-2.07-27.032-1.98-5.676.051-9.475 1.759-12.25 3.006h-.001l-.009.004c-2.405 1.081-4.305 1.935-6.216 1.186-1.747-.684-3.2-2.637-4.855-6.53-3.024-7.113-6.422-7.922-11.125-9.04-3.568-.849-8.01-1.906-13.06-6.172-3.452-2.915-8.08-6.644-12.982-10.59C49.18 24.025 32.319 10.441 23.107.347A22.509 22.509 0 0121.788 0h7.364c-.172.105-.354.2-.546.282C36.59 8.69 50.299 18.877 62.563 27.985l.026.02c6.966 5.173 13.544 10.06 18.276 14.038 4.635 3.899 8.487 4.842 11.885 5.674 4.679 1.145 8.721 2.134 12.048 10.233 1.33 3.238 2.466 4.944 3.575 5.37 1.047.398 2.446-.272 4.385-1.203l.004-.002c2.896-1.39 6.848-3.288 12.92-3.288h.127l.131.001c10.128.096 18.8 1.427 27.186 2.715 10.143 1.558 19.227 2.942 29.116 1.933-8.585.026-16.703-1.72-25.117-3.543l-.012-.002c-8.19-1.775-16.659-3.61-26.357-4.05-5.874-.272-9.581 1.763-12.297 3.253l-.032.018c-2.1 1.152-3.756 2.06-5.499 1.424-1.642-.604-2.926-2.45-4.427-6.376-2.775-7.256-5.555-7.979-9.764-9.074h-.002c-3.165-.824-7.103-1.85-11.977-5.914-5.877-4.9-14.04-9.772-22.683-14.929-11.904-7.1-24.212-14.445-31.192-22.409A21.936 21.936 0 0131.402 0h2.51c.151.181.309.366.475.555a41.174 41.174 0 002.058 2.161A19.713 19.713 0 0134.51 0h2.345a21.721 21.721 0 001.719 2.138 36.154 36.154 0 001.535 1.586C39.087 2.47 38.283 1.231 37.663 0h2.283c.712 1.228 1.636 2.464 2.812 3.727.39.418.797.826 1.214 1.228A24.14 24.14 0 0140.872 0h2.188c.968 1.84 2.244 3.608 3.885 5.318a26.373 26.373 0 00.912.893A31.463 31.463 0 0144.03 0h2.22c1.672 3.3 3.549 5.556 4.882 6.906 6.749 6.832 16.135 9.186 26.072 11.678l.006.002c8.887 2.228 18.076 4.533 25.178 10.355 4.299 3.524 7.382 4.447 9.858 5.188 4.261 1.276 6.609 2.32 9.26 10.426 1.233 3.767 2.108 4.761 2.625 4.931.593.191 1.683-.578 2.941-1.475l.015-.011c2.699-1.925 6.77-4.828 13.572-4 9.344 1.131 17.646 3.986 25.674 6.748 13.142 4.52 25.555 8.787 40.152 4.348 9.929-3.023 20.193-.49 30.12 1.96l.012.003 1.382.34v2.06l-1.87-.46c-5.67-1.4-11.163-2.755-16.554-3.17 4.327.818 8.598 2.19 12.803 3.545 1.856.599 3.731 1.203 5.621 1.764v2.086c-2.099-.612-4.175-1.282-6.23-1.944l-.004-.002c-5.464-1.762-10.75-3.457-16.03-4.018 4.349 1.003 8.58 2.716 12.741 4.405 3.116 1.265 6.281 2.55 9.523 3.555v2.094c-3.516-1.053-6.922-2.435-10.272-3.795h-.003c-5.35-2.173-10.514-4.267-15.793-4.936 4.45 1.177 8.694 3.283 12.864 5.358l.173.087c4.197 2.09 8.485 4.224 13.031 5.441v2.056c-4.973-1.253-9.583-3.547-14.093-5.792h-.002c-5.186-2.582-10.186-5.06-15.439-5.842 4.499 1.353 8.69 3.858 12.803 6.321h.001c5.244 3.141 10.636 6.37 16.73 7.339v2.027c-6.578-.956-12.241-4.346-17.75-7.644l-.009-.006c-7.325-4.387-14.258-8.518-22.642-6.536 6.503.685 11.778 5.075 16.916 9.363l.083.07c5.881 4.91 11.941 9.968 20.03 9.724 1.069-.031 2.194-.083 3.372-.155v2.003c-1.156.07-2.261.12-3.313.151-.207.006-.414.01-.618.01-8.534 0-14.783-5.216-20.833-10.265l-.002-.002c-4.717-3.938-9.252-7.703-14.586-8.719 4.734 1.825 8.707 5.677 12.594 9.458l.042.041c5.622 5.471 11.424 11.116 19.623 10.832 2.143-.074 4.52-.233 7.093-.469v1.986c-2.612.248-4.968.411-7.025.482-.227.008-.453.012-.677.012-8.683 0-14.662-5.817-20.449-11.449l-.002-.002c-6.138-5.97-11.934-11.607-20.396-9.544a6.362 6.362 0 01-.264.06c6.645.94 11.198 6.85 15.624 12.615l.018.024c5.046 6.575 10.262 13.37 18.631 12.993 4.052-.18 8.987-.683 14.54-1.438v2.016c-5.51.744-10.413 1.24-14.45 1.42-.262.012-.521.018-.777.018-8.945 0-14.331-7.017-19.546-13.811l-.003-.004-.006-.007c-5.346-6.966-10.397-13.547-18.803-11.626-.132.03-.261.057-.391.084l-.311.066c6.794 1.085 10.839 8.053 14.767 14.848 4.641 8.027 9.03 15.614 17.534 15.145 5.726-.312 13.322-1.305 21.986-2.76v2.023c-8.612 1.44-16.166 2.423-21.877 2.734-.291.016-.58.024-.862.024-9.167 0-13.914-8.21-18.51-16.16l-.003-.005c-3.706-6.412-7.25-12.526-12.858-13.763 5.122 2.473 8.33 8.832 11.453 15.061 4.311 8.593 8.385 16.71 16.95 16.2 6.486-.386 15.461-1.675 25.707-3.53v2.028c-10.185 1.837-19.111 3.112-25.587 3.498-.305.018-.607.028-.902.028-9.266.001-13.681-8.802-17.955-17.325l-.001-.003-.007-.012c-3.481-6.943-6.805-13.57-12.502-14.813 5.221 2.575 8.235 9.477 11.168 16.232 3.976 9.158 7.731 17.803 16.357 17.251 7.205-.465 17.596-2.081 29.429-4.364v2.035c-11.765 2.261-22.099 3.86-29.3 4.325a14.29 14.29 0 01-.939.031c-9.357 0-13.434-9.39-17.382-18.48v-.002c-3.236-7.452-6.334-14.556-12.065-15.862 5.271 2.704 8.063 10.121 10.779 17.372l.042.114zm-85.541-10.165a58.657 58.657 0 012.739-.415c4.4-.548 8.533-1.017 12.453-1.437-3.127.273-6.375.582-9.789.953-2.012.221-3.792.54-5.403.9zm20.806-4.32c-4.073.225-8.35.52-12.983.95a43.406 43.406 0 00-5.73.921 51.813 51.813 0 013.094-.438 494.47 494.47 0 0115.619-1.434zm5.224-2.265c-4.911.104-10.092.31-15.791.743a38.9 38.9 0 00-5.905.912 46.087 46.087 0 013.305-.433c6.728-.622 12.731-.974 18.391-1.222zm-3.703-11.62h-.235c-2.341 0-4.335.317-6.08.772a28.976 28.976 0 013.885-.298c10.241-.069 18.981.981 27.421 2.011.905.11 1.799.22 2.689.326l-.39-.06-.388-.059-.01-.001c-8.314-1.277-16.911-2.597-26.892-2.69zm-64.55-31.237C48.6 20.107 34.27 9.46 26.29.733a2.244 2.244 0 01-.083.002c9.365 9.76 25.058 22.401 38.058 32.872l.08.065c5.089 4.1 9.486 7.641 12.938 10.556 4.686 3.96 8.696 4.913 12.232 5.754 4.874 1.16 9.083 2.161 12.502 10.203 1.388 3.262 2.577 4.994 3.744 5.451.701.275 1.542.12 2.573-.259a3.898 3.898 0 01-.677-.19c-1.704-.655-3.113-2.592-4.708-6.477-2.942-7.158-6.185-7.952-10.673-9.05-3.433-.84-7.704-1.887-12.698-6.087-4.691-3.944-11.256-8.82-18.207-13.982zm97.895 28.533c-8.129-2.019-16.534-4.106-26.095-4.718-2.483-.159-4.567.13-6.353.632 1.228-.155 2.562-.222 4.028-.155 9.866.449 18.418 2.301 26.688 4.092l.014.003c2.655.575 5.278 1.14 7.894 1.646a444.507 444.507 0 01-6.176-1.5zm-68.92-21.098c-6.198-5.129-14.641-9.493-23.581-14.113-2.88-1.488-5.781-2.989-8.626-4.529a942.257 942.257 0 006.96 4.182c8.713 5.198 16.942 10.108 22.94 15.11 4.528 3.777 8.07 4.699 11.196 5.513l.006.001c4.462 1.161 7.985 2.078 11.128 10.295 1.204 3.147 2.266 4.852 3.249 5.213.551.204 1.244.014 2.105-.387-.023-.007-.046-.012-.069-.016-.028-.006-.056-.012-.084-.022-1.603-.574-2.847-2.408-4.293-6.33-2.69-7.301-5.32-8.008-9.3-9.076h-.002c-3.037-.816-6.815-1.83-11.628-5.84zm71.064 19.28c-8.064-2.259-16.403-4.595-25.821-5.373-2.502-.208-4.592.076-6.377.594a21.799 21.799 0 014.086-.117c9.74.623 18.236 2.733 26.45 4.773 3.145.781 6.247 1.55 9.344 2.211-2.548-.652-5.101-1.365-7.682-2.088zM69.811 21.884l-.008-.004a654.364 654.364 0 01-4.285-1.864l2.165 1.12.012.007c8.636 4.464 17.565 9.079 23.93 14.345 4.477 3.731 7.872 4.642 10.869 5.446h.001c4.252 1.142 7.611 2.044 10.659 10.317 1.152 3.126 2.163 4.807 3.09 5.14.503.18 1.149-.019 1.955-.424-1.556-.55-2.758-2.373-4.144-6.28-2.61-7.36-4.958-8.013-8.848-9.094-2.905-.807-6.52-1.812-11.267-5.747-6.443-5.316-15.434-9.203-24.129-12.962zm70.608 24.101c-2.506-.303-4.579-.04-6.337.5a19.188 19.188 0 014.124-.013c9.477.963 17.845 3.573 25.938 6.098 3.996 1.246 7.925 2.47 11.867 3.448-3.43-1.01-6.853-2.184-10.327-3.379l-.018-.006c-7.926-2.725-16.12-5.543-25.247-6.648zm23.123 8.492c-7.996-2.494-16.264-5.073-25.539-6.016-2.495-.253-4.572.02-6.342.544a20.477 20.477 0 014.092-.066c9.602.794 18.029 3.154 26.178 5.436l.019.005c3.56.997 7.067 1.974 10.576 2.79-2.98-.825-5.959-1.749-8.978-2.69l-.006-.003zm-90.373-33.35l-.014-.006-.36-.123c8.124 3.527 16.306 7.263 22.419 12.307 4.42 3.663 7.665 4.565 10.53 5.361 4.044 1.124 7.239 2.012 10.196 10.352 1.101 3.106 2.061 4.764 2.932 5.068.459.158 1.079-.06 1.832-.468-1.453-.583-2.587-2.39-3.874-6.185-2.542-7.417-4.622-8.018-8.397-9.108l-.009-.003c-2.771-.801-6.221-1.8-10.894-5.653-6.623-5.444-15.64-8.544-24.36-11.543zm45.555 25.661c1.032 3.048 1.963 4.73 2.768 5.003.417.145 1.012-.097 1.744-.529-1.355-.615-2.427-2.41-3.629-6.085-2.45-7.49-4.398-8.073-7.931-9.131h-.002c-2.648-.793-5.944-1.78-10.552-5.558-6.026-4.94-13.81-7.262-21.575-9.25 6.993 2.523 13.83 5.43 19.253 9.888 4.361 3.594 7.591 4.527 10.187 5.277h.002c3.978 1.15 6.853 1.981 9.735 10.385z",fill:"url(#illustration-04)"}))),n.createElement("div",{className:"relative flex flex-col xl:flex-row justify-between items-center"},n.createElement("h4",{className:"h4 text-white xl:mb-0 text-center"},"Touchlab KMP Insiders Newsletter"),n.createElement("a",{className:"btn text-cyan-600 bg-cyan-100 hover:bg-white shadow text-xl",href:"https://form.typeform.com/to/MJTpmm"},"Subscribe")))))};function r(e){return n.createElement(n.Fragment,null,n.createElement(l.Z,e),n.createElement("div",{className:"mt-8"},n.createElement(c,null)))}}}]); \ No newline at end of file +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[817],{1310:(e,t,a)=>{a.d(t,{Z:()=>g});var n=a(7462),l=a(7294),c=a(6010),r=a(5281),i=a(2802),s=a(8596),o=a(9960),m=a(5999),d=a(4996);function u(e){return l.createElement("svg",(0,n.Z)({viewBox:"0 0 24 24"},e),l.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const h="breadcrumbHomeIcon_YNFT";function v(){const e=(0,d.Z)("/");return l.createElement("li",{className:"breadcrumbs__item"},l.createElement(o.Z,{"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},l.createElement(u,{className:h})))}const b="breadcrumbsContainer_Z_bl";function p(e){let{children:t,href:a,isLast:n}=e;const c="breadcrumbs__link";return n?l.createElement("span",{className:c,itemProp:"name"},t):a?l.createElement(o.Z,{className:c,href:a,itemProp:"item"},l.createElement("span",{itemProp:"name"},t)):l.createElement("span",{className:c},t)}function E(e){let{children:t,active:a,index:r,addMicrodata:i}=e;return l.createElement("li",(0,n.Z)({},i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,c.Z)("breadcrumbs__item",{"breadcrumbs__item--active":a})}),t,l.createElement("meta",{itemProp:"position",content:String(r+1)}))}function g(){const e=(0,i.s1)(),t=(0,s.Ns)();return e?l.createElement("nav",{className:(0,c.Z)(r.k.docs.docBreadcrumbs,b),"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},l.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&l.createElement(v,null),e.map(((t,a)=>{const n=a===e.length-1;return l.createElement(E,{key:a,active:n,index:a,addMicrodata:!!t.href},l.createElement(p,{href:t.href,isLast:n},t.label))})))):null}},4228:(e,t,a)=>{a.r(t),a.d(t,{default:()=>z});var n=a(7294),l=a(1944),c=a(2802),r=a(4996),i=a(6010),s=a(9960),o=a(3919),m=a(5999);const d="cardContainer_fWXF",u="cardTitle_rnsV",h="cardDescription_PWke";function v(e){let{href:t,children:a}=e;return n.createElement(s.Z,{href:t,className:(0,i.Z)("card padding--lg",d)},a)}function b(e){let{href:t,icon:a,title:l,description:c}=e;return n.createElement(v,{href:t},n.createElement("h2",{className:(0,i.Z)("text--truncate",u),title:l},a," ",l),c&&n.createElement("p",{className:(0,i.Z)("text--truncate",h),title:c},c))}function p(e){let{item:t}=e;const a=(0,c.Wl)(t);return a?n.createElement(b,{href:a,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,m.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function E(e){let{item:t}=e;const a=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",l=(0,c.xz)(t.docId??void 0);return n.createElement(b,{href:t.href,icon:a,title:t.label,description:null==l?void 0:l.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(E,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const a=(0,c.jA)();return n.createElement(N,{items:a.items,className:t})}function N(e){const{items:t,className:a}=e;if(!t)return n.createElement(f,e);const l=(0,c.MN)(t);return n.createElement("section",{className:(0,i.Z)("row",a)},l.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}var Z=a(5797),x=a(3120),k=a(4364),L=a(1310),_=a(7955);const y="generatedIndexPage_vN6x",w="list_eTzJ",T="title_kItE";function C(e){let{categoryGeneratedIndex:t}=e;return n.createElement(l.d,{title:t.title,description:t.description,keywords:t.keywords,image:(0,r.Z)(t.image)})}function I(e){let{categoryGeneratedIndex:t}=e;const a=(0,c.jA)();return n.createElement("div",{className:y},n.createElement(x.Z,null),n.createElement(L.Z,null),n.createElement(k.Z,null),n.createElement("header",null,n.createElement(_.Z,{as:"h1",className:T},t.title),t.description&&n.createElement("p",null,t.description)),n.createElement("article",{className:"margin-top--lg"},n.createElement(N,{items:a.items,className:w})),n.createElement("footer",{className:"margin-top--lg"},n.createElement(Z.Z,{previous:t.navigation.previous,next:t.navigation.next})))}function z(e){return n.createElement(n.Fragment,null,n.createElement(C,e),n.createElement(I,e))}},4966:(e,t,a)=>{a.d(t,{Z:()=>o});var n=a(7462),l=a(7294),c=a(5999),r=a(6010),i=a(9960);function s(e){const{permalink:t,title:a,subLabel:n,isNext:c}=e;return l.createElement(i.Z,{className:(0,r.Z)("pagination-nav__link",c?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},n&&l.createElement("div",{className:"pagination-nav__sublabel"},n),l.createElement("div",{className:"pagination-nav__label"},a))}function o(e){const{previous:t,next:a}=e;return l.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages navigation",description:"The ARIA label for the docs pagination"})},t&&l.createElement(s,(0,n.Z)({},t,{subLabel:l.createElement(c.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),a&&l.createElement(s,(0,n.Z)({},a,{subLabel:l.createElement(c.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(6010),c=a(5999),r=a(5281),i=a(4477);function s(e){let{className:t}=e;const a=(0,i.E)();return a.badge?n.createElement("span",{className:(0,l.Z)(t,r.k.docs.docVersionBadge,"badge badge--secondary")},n.createElement(c.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:a.label}},"Version: {versionLabel}")):null}},3120:(e,t,a)=>{a.d(t,{Z:()=>p});var n=a(7294),l=a(6010),c=a(2263),r=a(9960),i=a(5999),s=a(143),o=a(5281),m=a(373),d=a(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(i.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(i.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function h(e){const t=u[e.versionMetadata.banner];return n.createElement(t,e)}function v(e){let{versionLabel:t,to:a,onClick:l}=e;return n.createElement(i.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:n.createElement("b",null,n.createElement(r.Z,{to:a,onClick:l},n.createElement(i.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function b(e){let{className:t,versionMetadata:a}=e;const{siteConfig:{title:r}}=(0,c.Z)(),{pluginId:i}=(0,s.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,m.J)(i),{latestDocSuggestion:u,latestVersionSuggestion:b}=(0,s.Jo)(i),p=u??(E=b).docs.find((e=>e.id===E.mainDocId));var E;return n.createElement("div",{className:(0,l.Z)(t,o.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},n.createElement("div",null,n.createElement(h,{siteTitle:r,versionMetadata:a})),n.createElement("div",{className:"margin-top--md"},n.createElement(v,{versionLabel:b.label,to:p.path,onClick:()=>d(b.name)})))}function p(e){let{className:t}=e;const a=(0,d.E)();return a.banner?n.createElement(b,{className:t,versionMetadata:a}):null}},7955:(e,t,a)=>{a.d(t,{Z:()=>d});var n=a(7462),l=a(7294),c=a(6010),r=a(5999),i=a(6668),s=a(9960);const o="anchorWithStickyNavbar_LWe7",m="anchorWithHideOnScrollNavbar_WYt5";function d(e){let{as:t,id:a,...d}=e;const{navbar:{hideOnScroll:u}}=(0,i.L)();if("h1"===t||!a)return l.createElement(t,(0,n.Z)({},d,{id:void 0}));const h=(0,r.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof d.children?d.children:a});return l.createElement(t,(0,n.Z)({},d,{className:(0,c.Z)("anchor",u?m:o,d.className),id:a}),d.children,l.createElement(s.Z,{className:"hash-link",to:`#${a}`,"aria-label":h,title:h},"\u200b"))}},5797:(e,t,a)=>{a.d(t,{Z:()=>r});var n=a(7294),l=a(4966);const c=function(){return n.createElement("section",null,n.createElement("div",{className:"max-w-6xl mx-auto px-4 sm:px-6"},n.createElement("div",{className:"relative bg-cyan-600 py-4 px-5 md:py-5 md:px-6"},n.createElement("div",{className:"absolute right-0 top-0 -ml-40 pointer-events-none","aria-hidden":"true"},n.createElement("svg",{width:"238",height:"110",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("defs",null,n.createElement("linearGradient",{id:"illustration-04",x1:"369.483",y1:"-84.633",x2:"139.954",y2:"-199.798",gradientUnits:"userSpaceOnUse"},n.createElement("stop",{stopColor:"#fff",stopOpacity:".01"}),n.createElement("stop",{offset:"1",stopColor:"#fff",stopOpacity:".24"}))),n.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M189.135 89.198c3.624 9.678 7.039 18.799 15.713 18.187 7.885-.548 19.733-2.523 33.152-5.256v2.04c-13.345 2.709-25.125 4.663-33.013 5.211-.331.023-.657.034-.975.034-9.441 0-13.176-9.972-16.792-19.627-3.571-9.536-6.946-18.545-15.389-16.96-13.086 2.455-24.348 3.539-37.385 4.794l-.024.002c-8.07.776-17.217 1.657-27.841 2.98-4.629.58-8.116 1.595-10.919 2.411l-.016.005c-6.68 1.947-10.032 2.924-14.897-6.267-3.62-6.842-8.541-7.827-14.24-8.967h-.001c-4.793-.959-10.225-2.046-15.65-6.76C40.64 52.141 15.48 20.345.66 0H3.13c14.82 20.254 39.089 50.863 49.042 59.515 5.023 4.367 9.956 5.354 14.73 6.31 5.94 1.187 11.552 2.31 15.616 9.991 3.443 6.51 5.39 7.141 9.773 6.057-3.311.19-5.726-1.455-8.768-7.374-3.533-6.876-8.064-7.803-13.8-8.976-4.642-.949-9.902-2.025-15.275-6.679C43.995 49.797 18.704 19.375 4.057 0h2.506C21.226 19.288 45.58 48.524 55.755 57.333c4.977 4.309 9.748 5.285 14.363 6.23l.005.001c5.763 1.178 11.206 2.292 15.178 10.021 3.255 6.333 5.085 6.977 9.146 5.928-3.035.107-5.304-1.569-8.148-7.27-3.45-6.913-7.822-7.829-13.359-8.988-4.49-.939-9.58-2.004-14.902-6.593C47.268 47.376 21.798 18.312 7.406 0h2.572c14.477 18.232 39.16 46.348 49.366 55.147 4.93 4.252 9.544 5.217 14.005 6.15h.002c5.583 1.17 10.856 2.273 14.737 10.053 1.853 3.713 3.336 5.515 4.959 6.027.993.312 2.15.164 3.558-.212-2.77.013-4.89-1.707-7.534-7.175-3.363-6.95-7.578-7.854-12.914-8.998h-.003c-4.34-.93-9.259-1.984-14.528-6.509C50.465 44.901 24.695 17.086 10.69 0h2.583C27.39 17.058 52.088 43.659 62.93 52.965c4.883 4.194 9.337 5.148 13.644 6.07l.002.001c5.404 1.158 10.508 2.253 14.297 10.083 1.74 3.6 3.195 5.421 4.712 5.906 1.453.463 3.288-.17 5.829-1.05l.005-.002c2.872-.995 6.804-2.356 12.263-2.776 10.687-.813 19.576-.84 28.174-.867 8.671-.027 16.548-.055 24.765-.913-6.672.214-13.232-.169-20.311-.59-8.482-.504-17.257-1.025-27.637-.582-5.471.237-9.134 1.68-12.076 2.838-5.4 2.127-8.165 2.774-11.971-5.607-3.193-7.03-7.09-7.908-12.025-9.019-4.044-.91-8.628-1.944-13.791-6.34C56.639 39.755 30.287 15.234 16.926 0h2.688c13.353 14.888 38.3 38.212 50.492 48.595 4.787 4.075 9.115 5.051 12.933 5.911 5.26 1.184 9.802 2.207 13.407 10.142 3.19 7.023 4.631 6.458 9.418 4.574l.002-.001c2.919-1.149 6.915-2.722 12.72-2.974 10.488-.448 19.311.076 27.841.583 9.399.56 17.871 1.054 26.886.14-7.662.148-15.028-.743-22.644-1.672l-.129-.016c-8.337-1.017-16.965-2.07-27.032-1.98-5.676.051-9.475 1.759-12.25 3.006h-.001l-.009.004c-2.405 1.081-4.305 1.935-6.216 1.186-1.747-.684-3.2-2.637-4.855-6.53-3.024-7.113-6.422-7.922-11.125-9.04-3.568-.849-8.01-1.906-13.06-6.172-3.452-2.915-8.08-6.644-12.982-10.59C49.18 24.025 32.319 10.441 23.107.347A22.509 22.509 0 0121.788 0h7.364c-.172.105-.354.2-.546.282C36.59 8.69 50.299 18.877 62.563 27.985l.026.02c6.966 5.173 13.544 10.06 18.276 14.038 4.635 3.899 8.487 4.842 11.885 5.674 4.679 1.145 8.721 2.134 12.048 10.233 1.33 3.238 2.466 4.944 3.575 5.37 1.047.398 2.446-.272 4.385-1.203l.004-.002c2.896-1.39 6.848-3.288 12.92-3.288h.127l.131.001c10.128.096 18.8 1.427 27.186 2.715 10.143 1.558 19.227 2.942 29.116 1.933-8.585.026-16.703-1.72-25.117-3.543l-.012-.002c-8.19-1.775-16.659-3.61-26.357-4.05-5.874-.272-9.581 1.763-12.297 3.253l-.032.018c-2.1 1.152-3.756 2.06-5.499 1.424-1.642-.604-2.926-2.45-4.427-6.376-2.775-7.256-5.555-7.979-9.764-9.074h-.002c-3.165-.824-7.103-1.85-11.977-5.914-5.877-4.9-14.04-9.772-22.683-14.929-11.904-7.1-24.212-14.445-31.192-22.409A21.936 21.936 0 0131.402 0h2.51c.151.181.309.366.475.555a41.174 41.174 0 002.058 2.161A19.713 19.713 0 0134.51 0h2.345a21.721 21.721 0 001.719 2.138 36.154 36.154 0 001.535 1.586C39.087 2.47 38.283 1.231 37.663 0h2.283c.712 1.228 1.636 2.464 2.812 3.727.39.418.797.826 1.214 1.228A24.14 24.14 0 0140.872 0h2.188c.968 1.84 2.244 3.608 3.885 5.318a26.373 26.373 0 00.912.893A31.463 31.463 0 0144.03 0h2.22c1.672 3.3 3.549 5.556 4.882 6.906 6.749 6.832 16.135 9.186 26.072 11.678l.006.002c8.887 2.228 18.076 4.533 25.178 10.355 4.299 3.524 7.382 4.447 9.858 5.188 4.261 1.276 6.609 2.32 9.26 10.426 1.233 3.767 2.108 4.761 2.625 4.931.593.191 1.683-.578 2.941-1.475l.015-.011c2.699-1.925 6.77-4.828 13.572-4 9.344 1.131 17.646 3.986 25.674 6.748 13.142 4.52 25.555 8.787 40.152 4.348 9.929-3.023 20.193-.49 30.12 1.96l.012.003 1.382.34v2.06l-1.87-.46c-5.67-1.4-11.163-2.755-16.554-3.17 4.327.818 8.598 2.19 12.803 3.545 1.856.599 3.731 1.203 5.621 1.764v2.086c-2.099-.612-4.175-1.282-6.23-1.944l-.004-.002c-5.464-1.762-10.75-3.457-16.03-4.018 4.349 1.003 8.58 2.716 12.741 4.405 3.116 1.265 6.281 2.55 9.523 3.555v2.094c-3.516-1.053-6.922-2.435-10.272-3.795h-.003c-5.35-2.173-10.514-4.267-15.793-4.936 4.45 1.177 8.694 3.283 12.864 5.358l.173.087c4.197 2.09 8.485 4.224 13.031 5.441v2.056c-4.973-1.253-9.583-3.547-14.093-5.792h-.002c-5.186-2.582-10.186-5.06-15.439-5.842 4.499 1.353 8.69 3.858 12.803 6.321h.001c5.244 3.141 10.636 6.37 16.73 7.339v2.027c-6.578-.956-12.241-4.346-17.75-7.644l-.009-.006c-7.325-4.387-14.258-8.518-22.642-6.536 6.503.685 11.778 5.075 16.916 9.363l.083.07c5.881 4.91 11.941 9.968 20.03 9.724 1.069-.031 2.194-.083 3.372-.155v2.003c-1.156.07-2.261.12-3.313.151-.207.006-.414.01-.618.01-8.534 0-14.783-5.216-20.833-10.265l-.002-.002c-4.717-3.938-9.252-7.703-14.586-8.719 4.734 1.825 8.707 5.677 12.594 9.458l.042.041c5.622 5.471 11.424 11.116 19.623 10.832 2.143-.074 4.52-.233 7.093-.469v1.986c-2.612.248-4.968.411-7.025.482-.227.008-.453.012-.677.012-8.683 0-14.662-5.817-20.449-11.449l-.002-.002c-6.138-5.97-11.934-11.607-20.396-9.544a6.362 6.362 0 01-.264.06c6.645.94 11.198 6.85 15.624 12.615l.018.024c5.046 6.575 10.262 13.37 18.631 12.993 4.052-.18 8.987-.683 14.54-1.438v2.016c-5.51.744-10.413 1.24-14.45 1.42-.262.012-.521.018-.777.018-8.945 0-14.331-7.017-19.546-13.811l-.003-.004-.006-.007c-5.346-6.966-10.397-13.547-18.803-11.626-.132.03-.261.057-.391.084l-.311.066c6.794 1.085 10.839 8.053 14.767 14.848 4.641 8.027 9.03 15.614 17.534 15.145 5.726-.312 13.322-1.305 21.986-2.76v2.023c-8.612 1.44-16.166 2.423-21.877 2.734-.291.016-.58.024-.862.024-9.167 0-13.914-8.21-18.51-16.16l-.003-.005c-3.706-6.412-7.25-12.526-12.858-13.763 5.122 2.473 8.33 8.832 11.453 15.061 4.311 8.593 8.385 16.71 16.95 16.2 6.486-.386 15.461-1.675 25.707-3.53v2.028c-10.185 1.837-19.111 3.112-25.587 3.498-.305.018-.607.028-.902.028-9.266.001-13.681-8.802-17.955-17.325l-.001-.003-.007-.012c-3.481-6.943-6.805-13.57-12.502-14.813 5.221 2.575 8.235 9.477 11.168 16.232 3.976 9.158 7.731 17.803 16.357 17.251 7.205-.465 17.596-2.081 29.429-4.364v2.035c-11.765 2.261-22.099 3.86-29.3 4.325a14.29 14.29 0 01-.939.031c-9.357 0-13.434-9.39-17.382-18.48v-.002c-3.236-7.452-6.334-14.556-12.065-15.862 5.271 2.704 8.063 10.121 10.779 17.372l.042.114zm-85.541-10.165a58.657 58.657 0 012.739-.415c4.4-.548 8.533-1.017 12.453-1.437-3.127.273-6.375.582-9.789.953-2.012.221-3.792.54-5.403.9zm20.806-4.32c-4.073.225-8.35.52-12.983.95a43.406 43.406 0 00-5.73.921 51.813 51.813 0 013.094-.438 494.47 494.47 0 0115.619-1.434zm5.224-2.265c-4.911.104-10.092.31-15.791.743a38.9 38.9 0 00-5.905.912 46.087 46.087 0 013.305-.433c6.728-.622 12.731-.974 18.391-1.222zm-3.703-11.62h-.235c-2.341 0-4.335.317-6.08.772a28.976 28.976 0 013.885-.298c10.241-.069 18.981.981 27.421 2.011.905.11 1.799.22 2.689.326l-.39-.06-.388-.059-.01-.001c-8.314-1.277-16.911-2.597-26.892-2.69zm-64.55-31.237C48.6 20.107 34.27 9.46 26.29.733a2.244 2.244 0 01-.083.002c9.365 9.76 25.058 22.401 38.058 32.872l.08.065c5.089 4.1 9.486 7.641 12.938 10.556 4.686 3.96 8.696 4.913 12.232 5.754 4.874 1.16 9.083 2.161 12.502 10.203 1.388 3.262 2.577 4.994 3.744 5.451.701.275 1.542.12 2.573-.259a3.898 3.898 0 01-.677-.19c-1.704-.655-3.113-2.592-4.708-6.477-2.942-7.158-6.185-7.952-10.673-9.05-3.433-.84-7.704-1.887-12.698-6.087-4.691-3.944-11.256-8.82-18.207-13.982zm97.895 28.533c-8.129-2.019-16.534-4.106-26.095-4.718-2.483-.159-4.567.13-6.353.632 1.228-.155 2.562-.222 4.028-.155 9.866.449 18.418 2.301 26.688 4.092l.014.003c2.655.575 5.278 1.14 7.894 1.646a444.507 444.507 0 01-6.176-1.5zm-68.92-21.098c-6.198-5.129-14.641-9.493-23.581-14.113-2.88-1.488-5.781-2.989-8.626-4.529a942.257 942.257 0 006.96 4.182c8.713 5.198 16.942 10.108 22.94 15.11 4.528 3.777 8.07 4.699 11.196 5.513l.006.001c4.462 1.161 7.985 2.078 11.128 10.295 1.204 3.147 2.266 4.852 3.249 5.213.551.204 1.244.014 2.105-.387-.023-.007-.046-.012-.069-.016-.028-.006-.056-.012-.084-.022-1.603-.574-2.847-2.408-4.293-6.33-2.69-7.301-5.32-8.008-9.3-9.076h-.002c-3.037-.816-6.815-1.83-11.628-5.84zm71.064 19.28c-8.064-2.259-16.403-4.595-25.821-5.373-2.502-.208-4.592.076-6.377.594a21.799 21.799 0 014.086-.117c9.74.623 18.236 2.733 26.45 4.773 3.145.781 6.247 1.55 9.344 2.211-2.548-.652-5.101-1.365-7.682-2.088zM69.811 21.884l-.008-.004a654.364 654.364 0 01-4.285-1.864l2.165 1.12.012.007c8.636 4.464 17.565 9.079 23.93 14.345 4.477 3.731 7.872 4.642 10.869 5.446h.001c4.252 1.142 7.611 2.044 10.659 10.317 1.152 3.126 2.163 4.807 3.09 5.14.503.18 1.149-.019 1.955-.424-1.556-.55-2.758-2.373-4.144-6.28-2.61-7.36-4.958-8.013-8.848-9.094-2.905-.807-6.52-1.812-11.267-5.747-6.443-5.316-15.434-9.203-24.129-12.962zm70.608 24.101c-2.506-.303-4.579-.04-6.337.5a19.188 19.188 0 014.124-.013c9.477.963 17.845 3.573 25.938 6.098 3.996 1.246 7.925 2.47 11.867 3.448-3.43-1.01-6.853-2.184-10.327-3.379l-.018-.006c-7.926-2.725-16.12-5.543-25.247-6.648zm23.123 8.492c-7.996-2.494-16.264-5.073-25.539-6.016-2.495-.253-4.572.02-6.342.544a20.477 20.477 0 014.092-.066c9.602.794 18.029 3.154 26.178 5.436l.019.005c3.56.997 7.067 1.974 10.576 2.79-2.98-.825-5.959-1.749-8.978-2.69l-.006-.003zm-90.373-33.35l-.014-.006-.36-.123c8.124 3.527 16.306 7.263 22.419 12.307 4.42 3.663 7.665 4.565 10.53 5.361 4.044 1.124 7.239 2.012 10.196 10.352 1.101 3.106 2.061 4.764 2.932 5.068.459.158 1.079-.06 1.832-.468-1.453-.583-2.587-2.39-3.874-6.185-2.542-7.417-4.622-8.018-8.397-9.108l-.009-.003c-2.771-.801-6.221-1.8-10.894-5.653-6.623-5.444-15.64-8.544-24.36-11.543zm45.555 25.661c1.032 3.048 1.963 4.73 2.768 5.003.417.145 1.012-.097 1.744-.529-1.355-.615-2.427-2.41-3.629-6.085-2.45-7.49-4.398-8.073-7.931-9.131h-.002c-2.648-.793-5.944-1.78-10.552-5.558-6.026-4.94-13.81-7.262-21.575-9.25 6.993 2.523 13.83 5.43 19.253 9.888 4.361 3.594 7.591 4.527 10.187 5.277h.002c3.978 1.15 6.853 1.981 9.735 10.385z",fill:"url(#illustration-04)"}))),n.createElement("div",{className:"relative flex flex-col xl:flex-row justify-between items-center"},n.createElement("h4",{className:"h4 text-white xl:mb-0 text-center"},"Touchlab KMP Insiders Newsletter"),n.createElement("a",{className:"btn text-cyan-600 bg-cyan-100 hover:bg-white shadow text-xl",href:"https://touchlab.co/?s=shownewsletter"},"Subscribe")))))};function r(e){return n.createElement(n.Fragment,null,n.createElement(l.Z,e),n.createElement("div",{className:"mt-8"},n.createElement(c,null)))}}}]); \ No newline at end of file diff --git a/assets/js/17896441.2d2e3b09.js b/assets/js/17896441.2d2e3b09.js new file mode 100644 index 00000000..a0dd4915 --- /dev/null +++ b/assets/js/17896441.2d2e3b09.js @@ -0,0 +1 @@ +(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[918],{5797:(e,c,t)=>{"use strict";t.d(c,{Z:()=>n});var l=t(7294),a=t(4966);const r=function(){return l.createElement("section",null,l.createElement("div",{className:"max-w-6xl mx-auto px-4 sm:px-6"},l.createElement("div",{className:"relative bg-cyan-600 py-4 px-5 md:py-5 md:px-6"},l.createElement("div",{className:"absolute right-0 top-0 -ml-40 pointer-events-none","aria-hidden":"true"},l.createElement("svg",{width:"238",height:"110",fill:"none",xmlns:"http://www.w3.org/2000/svg"},l.createElement("defs",null,l.createElement("linearGradient",{id:"illustration-04",x1:"369.483",y1:"-84.633",x2:"139.954",y2:"-199.798",gradientUnits:"userSpaceOnUse"},l.createElement("stop",{stopColor:"#fff",stopOpacity:".01"}),l.createElement("stop",{offset:"1",stopColor:"#fff",stopOpacity:".24"}))),l.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M189.135 89.198c3.624 9.678 7.039 18.799 15.713 18.187 7.885-.548 19.733-2.523 33.152-5.256v2.04c-13.345 2.709-25.125 4.663-33.013 5.211-.331.023-.657.034-.975.034-9.441 0-13.176-9.972-16.792-19.627-3.571-9.536-6.946-18.545-15.389-16.96-13.086 2.455-24.348 3.539-37.385 4.794l-.024.002c-8.07.776-17.217 1.657-27.841 2.98-4.629.58-8.116 1.595-10.919 2.411l-.016.005c-6.68 1.947-10.032 2.924-14.897-6.267-3.62-6.842-8.541-7.827-14.24-8.967h-.001c-4.793-.959-10.225-2.046-15.65-6.76C40.64 52.141 15.48 20.345.66 0H3.13c14.82 20.254 39.089 50.863 49.042 59.515 5.023 4.367 9.956 5.354 14.73 6.31 5.94 1.187 11.552 2.31 15.616 9.991 3.443 6.51 5.39 7.141 9.773 6.057-3.311.19-5.726-1.455-8.768-7.374-3.533-6.876-8.064-7.803-13.8-8.976-4.642-.949-9.902-2.025-15.275-6.679C43.995 49.797 18.704 19.375 4.057 0h2.506C21.226 19.288 45.58 48.524 55.755 57.333c4.977 4.309 9.748 5.285 14.363 6.23l.005.001c5.763 1.178 11.206 2.292 15.178 10.021 3.255 6.333 5.085 6.977 9.146 5.928-3.035.107-5.304-1.569-8.148-7.27-3.45-6.913-7.822-7.829-13.359-8.988-4.49-.939-9.58-2.004-14.902-6.593C47.268 47.376 21.798 18.312 7.406 0h2.572c14.477 18.232 39.16 46.348 49.366 55.147 4.93 4.252 9.544 5.217 14.005 6.15h.002c5.583 1.17 10.856 2.273 14.737 10.053 1.853 3.713 3.336 5.515 4.959 6.027.993.312 2.15.164 3.558-.212-2.77.013-4.89-1.707-7.534-7.175-3.363-6.95-7.578-7.854-12.914-8.998h-.003c-4.34-.93-9.259-1.984-14.528-6.509C50.465 44.901 24.695 17.086 10.69 0h2.583C27.39 17.058 52.088 43.659 62.93 52.965c4.883 4.194 9.337 5.148 13.644 6.07l.002.001c5.404 1.158 10.508 2.253 14.297 10.083 1.74 3.6 3.195 5.421 4.712 5.906 1.453.463 3.288-.17 5.829-1.05l.005-.002c2.872-.995 6.804-2.356 12.263-2.776 10.687-.813 19.576-.84 28.174-.867 8.671-.027 16.548-.055 24.765-.913-6.672.214-13.232-.169-20.311-.59-8.482-.504-17.257-1.025-27.637-.582-5.471.237-9.134 1.68-12.076 2.838-5.4 2.127-8.165 2.774-11.971-5.607-3.193-7.03-7.09-7.908-12.025-9.019-4.044-.91-8.628-1.944-13.791-6.34C56.639 39.755 30.287 15.234 16.926 0h2.688c13.353 14.888 38.3 38.212 50.492 48.595 4.787 4.075 9.115 5.051 12.933 5.911 5.26 1.184 9.802 2.207 13.407 10.142 3.19 7.023 4.631 6.458 9.418 4.574l.002-.001c2.919-1.149 6.915-2.722 12.72-2.974 10.488-.448 19.311.076 27.841.583 9.399.56 17.871 1.054 26.886.14-7.662.148-15.028-.743-22.644-1.672l-.129-.016c-8.337-1.017-16.965-2.07-27.032-1.98-5.676.051-9.475 1.759-12.25 3.006h-.001l-.009.004c-2.405 1.081-4.305 1.935-6.216 1.186-1.747-.684-3.2-2.637-4.855-6.53-3.024-7.113-6.422-7.922-11.125-9.04-3.568-.849-8.01-1.906-13.06-6.172-3.452-2.915-8.08-6.644-12.982-10.59C49.18 24.025 32.319 10.441 23.107.347A22.509 22.509 0 0121.788 0h7.364c-.172.105-.354.2-.546.282C36.59 8.69 50.299 18.877 62.563 27.985l.026.02c6.966 5.173 13.544 10.06 18.276 14.038 4.635 3.899 8.487 4.842 11.885 5.674 4.679 1.145 8.721 2.134 12.048 10.233 1.33 3.238 2.466 4.944 3.575 5.37 1.047.398 2.446-.272 4.385-1.203l.004-.002c2.896-1.39 6.848-3.288 12.92-3.288h.127l.131.001c10.128.096 18.8 1.427 27.186 2.715 10.143 1.558 19.227 2.942 29.116 1.933-8.585.026-16.703-1.72-25.117-3.543l-.012-.002c-8.19-1.775-16.659-3.61-26.357-4.05-5.874-.272-9.581 1.763-12.297 3.253l-.032.018c-2.1 1.152-3.756 2.06-5.499 1.424-1.642-.604-2.926-2.45-4.427-6.376-2.775-7.256-5.555-7.979-9.764-9.074h-.002c-3.165-.824-7.103-1.85-11.977-5.914-5.877-4.9-14.04-9.772-22.683-14.929-11.904-7.1-24.212-14.445-31.192-22.409A21.936 21.936 0 0131.402 0h2.51c.151.181.309.366.475.555a41.174 41.174 0 002.058 2.161A19.713 19.713 0 0134.51 0h2.345a21.721 21.721 0 001.719 2.138 36.154 36.154 0 001.535 1.586C39.087 2.47 38.283 1.231 37.663 0h2.283c.712 1.228 1.636 2.464 2.812 3.727.39.418.797.826 1.214 1.228A24.14 24.14 0 0140.872 0h2.188c.968 1.84 2.244 3.608 3.885 5.318a26.373 26.373 0 00.912.893A31.463 31.463 0 0144.03 0h2.22c1.672 3.3 3.549 5.556 4.882 6.906 6.749 6.832 16.135 9.186 26.072 11.678l.006.002c8.887 2.228 18.076 4.533 25.178 10.355 4.299 3.524 7.382 4.447 9.858 5.188 4.261 1.276 6.609 2.32 9.26 10.426 1.233 3.767 2.108 4.761 2.625 4.931.593.191 1.683-.578 2.941-1.475l.015-.011c2.699-1.925 6.77-4.828 13.572-4 9.344 1.131 17.646 3.986 25.674 6.748 13.142 4.52 25.555 8.787 40.152 4.348 9.929-3.023 20.193-.49 30.12 1.96l.012.003 1.382.34v2.06l-1.87-.46c-5.67-1.4-11.163-2.755-16.554-3.17 4.327.818 8.598 2.19 12.803 3.545 1.856.599 3.731 1.203 5.621 1.764v2.086c-2.099-.612-4.175-1.282-6.23-1.944l-.004-.002c-5.464-1.762-10.75-3.457-16.03-4.018 4.349 1.003 8.58 2.716 12.741 4.405 3.116 1.265 6.281 2.55 9.523 3.555v2.094c-3.516-1.053-6.922-2.435-10.272-3.795h-.003c-5.35-2.173-10.514-4.267-15.793-4.936 4.45 1.177 8.694 3.283 12.864 5.358l.173.087c4.197 2.09 8.485 4.224 13.031 5.441v2.056c-4.973-1.253-9.583-3.547-14.093-5.792h-.002c-5.186-2.582-10.186-5.06-15.439-5.842 4.499 1.353 8.69 3.858 12.803 6.321h.001c5.244 3.141 10.636 6.37 16.73 7.339v2.027c-6.578-.956-12.241-4.346-17.75-7.644l-.009-.006c-7.325-4.387-14.258-8.518-22.642-6.536 6.503.685 11.778 5.075 16.916 9.363l.083.07c5.881 4.91 11.941 9.968 20.03 9.724 1.069-.031 2.194-.083 3.372-.155v2.003c-1.156.07-2.261.12-3.313.151-.207.006-.414.01-.618.01-8.534 0-14.783-5.216-20.833-10.265l-.002-.002c-4.717-3.938-9.252-7.703-14.586-8.719 4.734 1.825 8.707 5.677 12.594 9.458l.042.041c5.622 5.471 11.424 11.116 19.623 10.832 2.143-.074 4.52-.233 7.093-.469v1.986c-2.612.248-4.968.411-7.025.482-.227.008-.453.012-.677.012-8.683 0-14.662-5.817-20.449-11.449l-.002-.002c-6.138-5.97-11.934-11.607-20.396-9.544a6.362 6.362 0 01-.264.06c6.645.94 11.198 6.85 15.624 12.615l.018.024c5.046 6.575 10.262 13.37 18.631 12.993 4.052-.18 8.987-.683 14.54-1.438v2.016c-5.51.744-10.413 1.24-14.45 1.42-.262.012-.521.018-.777.018-8.945 0-14.331-7.017-19.546-13.811l-.003-.004-.006-.007c-5.346-6.966-10.397-13.547-18.803-11.626-.132.03-.261.057-.391.084l-.311.066c6.794 1.085 10.839 8.053 14.767 14.848 4.641 8.027 9.03 15.614 17.534 15.145 5.726-.312 13.322-1.305 21.986-2.76v2.023c-8.612 1.44-16.166 2.423-21.877 2.734-.291.016-.58.024-.862.024-9.167 0-13.914-8.21-18.51-16.16l-.003-.005c-3.706-6.412-7.25-12.526-12.858-13.763 5.122 2.473 8.33 8.832 11.453 15.061 4.311 8.593 8.385 16.71 16.95 16.2 6.486-.386 15.461-1.675 25.707-3.53v2.028c-10.185 1.837-19.111 3.112-25.587 3.498-.305.018-.607.028-.902.028-9.266.001-13.681-8.802-17.955-17.325l-.001-.003-.007-.012c-3.481-6.943-6.805-13.57-12.502-14.813 5.221 2.575 8.235 9.477 11.168 16.232 3.976 9.158 7.731 17.803 16.357 17.251 7.205-.465 17.596-2.081 29.429-4.364v2.035c-11.765 2.261-22.099 3.86-29.3 4.325a14.29 14.29 0 01-.939.031c-9.357 0-13.434-9.39-17.382-18.48v-.002c-3.236-7.452-6.334-14.556-12.065-15.862 5.271 2.704 8.063 10.121 10.779 17.372l.042.114zm-85.541-10.165a58.657 58.657 0 012.739-.415c4.4-.548 8.533-1.017 12.453-1.437-3.127.273-6.375.582-9.789.953-2.012.221-3.792.54-5.403.9zm20.806-4.32c-4.073.225-8.35.52-12.983.95a43.406 43.406 0 00-5.73.921 51.813 51.813 0 013.094-.438 494.47 494.47 0 0115.619-1.434zm5.224-2.265c-4.911.104-10.092.31-15.791.743a38.9 38.9 0 00-5.905.912 46.087 46.087 0 013.305-.433c6.728-.622 12.731-.974 18.391-1.222zm-3.703-11.62h-.235c-2.341 0-4.335.317-6.08.772a28.976 28.976 0 013.885-.298c10.241-.069 18.981.981 27.421 2.011.905.11 1.799.22 2.689.326l-.39-.06-.388-.059-.01-.001c-8.314-1.277-16.911-2.597-26.892-2.69zm-64.55-31.237C48.6 20.107 34.27 9.46 26.29.733a2.244 2.244 0 01-.083.002c9.365 9.76 25.058 22.401 38.058 32.872l.08.065c5.089 4.1 9.486 7.641 12.938 10.556 4.686 3.96 8.696 4.913 12.232 5.754 4.874 1.16 9.083 2.161 12.502 10.203 1.388 3.262 2.577 4.994 3.744 5.451.701.275 1.542.12 2.573-.259a3.898 3.898 0 01-.677-.19c-1.704-.655-3.113-2.592-4.708-6.477-2.942-7.158-6.185-7.952-10.673-9.05-3.433-.84-7.704-1.887-12.698-6.087-4.691-3.944-11.256-8.82-18.207-13.982zm97.895 28.533c-8.129-2.019-16.534-4.106-26.095-4.718-2.483-.159-4.567.13-6.353.632 1.228-.155 2.562-.222 4.028-.155 9.866.449 18.418 2.301 26.688 4.092l.014.003c2.655.575 5.278 1.14 7.894 1.646a444.507 444.507 0 01-6.176-1.5zm-68.92-21.098c-6.198-5.129-14.641-9.493-23.581-14.113-2.88-1.488-5.781-2.989-8.626-4.529a942.257 942.257 0 006.96 4.182c8.713 5.198 16.942 10.108 22.94 15.11 4.528 3.777 8.07 4.699 11.196 5.513l.006.001c4.462 1.161 7.985 2.078 11.128 10.295 1.204 3.147 2.266 4.852 3.249 5.213.551.204 1.244.014 2.105-.387-.023-.007-.046-.012-.069-.016-.028-.006-.056-.012-.084-.022-1.603-.574-2.847-2.408-4.293-6.33-2.69-7.301-5.32-8.008-9.3-9.076h-.002c-3.037-.816-6.815-1.83-11.628-5.84zm71.064 19.28c-8.064-2.259-16.403-4.595-25.821-5.373-2.502-.208-4.592.076-6.377.594a21.799 21.799 0 014.086-.117c9.74.623 18.236 2.733 26.45 4.773 3.145.781 6.247 1.55 9.344 2.211-2.548-.652-5.101-1.365-7.682-2.088zM69.811 21.884l-.008-.004a654.364 654.364 0 01-4.285-1.864l2.165 1.12.012.007c8.636 4.464 17.565 9.079 23.93 14.345 4.477 3.731 7.872 4.642 10.869 5.446h.001c4.252 1.142 7.611 2.044 10.659 10.317 1.152 3.126 2.163 4.807 3.09 5.14.503.18 1.149-.019 1.955-.424-1.556-.55-2.758-2.373-4.144-6.28-2.61-7.36-4.958-8.013-8.848-9.094-2.905-.807-6.52-1.812-11.267-5.747-6.443-5.316-15.434-9.203-24.129-12.962zm70.608 24.101c-2.506-.303-4.579-.04-6.337.5a19.188 19.188 0 014.124-.013c9.477.963 17.845 3.573 25.938 6.098 3.996 1.246 7.925 2.47 11.867 3.448-3.43-1.01-6.853-2.184-10.327-3.379l-.018-.006c-7.926-2.725-16.12-5.543-25.247-6.648zm23.123 8.492c-7.996-2.494-16.264-5.073-25.539-6.016-2.495-.253-4.572.02-6.342.544a20.477 20.477 0 014.092-.066c9.602.794 18.029 3.154 26.178 5.436l.019.005c3.56.997 7.067 1.974 10.576 2.79-2.98-.825-5.959-1.749-8.978-2.69l-.006-.003zm-90.373-33.35l-.014-.006-.36-.123c8.124 3.527 16.306 7.263 22.419 12.307 4.42 3.663 7.665 4.565 10.53 5.361 4.044 1.124 7.239 2.012 10.196 10.352 1.101 3.106 2.061 4.764 2.932 5.068.459.158 1.079-.06 1.832-.468-1.453-.583-2.587-2.39-3.874-6.185-2.542-7.417-4.622-8.018-8.397-9.108l-.009-.003c-2.771-.801-6.221-1.8-10.894-5.653-6.623-5.444-15.64-8.544-24.36-11.543zm45.555 25.661c1.032 3.048 1.963 4.73 2.768 5.003.417.145 1.012-.097 1.744-.529-1.355-.615-2.427-2.41-3.629-6.085-2.45-7.49-4.398-8.073-7.931-9.131h-.002c-2.648-.793-5.944-1.78-10.552-5.558-6.026-4.94-13.81-7.262-21.575-9.25 6.993 2.523 13.83 5.43 19.253 9.888 4.361 3.594 7.591 4.527 10.187 5.277h.002c3.978 1.15 6.853 1.981 9.735 10.385z",fill:"url(#illustration-04)"}))),l.createElement("div",{className:"relative flex flex-col xl:flex-row justify-between items-center"},l.createElement("h4",{className:"h4 text-white xl:mb-0 text-center"},"Touchlab KMP Insiders Newsletter"),l.createElement("a",{className:"btn text-cyan-600 bg-cyan-100 hover:bg-white shadow text-xl",href:"https://touchlab.co/?s=shownewsletter"},"Subscribe")))))};function n(e){return l.createElement(l.Fragment,null,l.createElement(a.Z,e),l.createElement("div",{className:"mt-8"},l.createElement(r,null)))}},7665:(e,c,t)=>{"use strict";t.d(c,{Z:()=>v});var l=t(7462),a=t(7294),r=t(5742);var n=t(814);var s=t(9960);var o=t(4673);var i=t(7955);function m(e){return a.createElement(i.Z,e)}var h=t(7390),u=t(1470),d=t(3612),p=t(3114);const v={head:function(e){const c=a.Children.map(e.children,(e=>a.isValidElement(e)?function(e){var c;if(null!=(c=e.props)&&c.mdxType&&e.props.originalType){const{mdxType:c,originalType:t,...l}=e.props;return a.createElement(e.props.originalType,l)}return e}(e):e));return a.createElement(r.Z,e,c)},code:function(e){const c=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return a.Children.toArray(e.children).every((e=>{var t;return"string"==typeof e&&!e.includes("\n")||(0,a.isValidElement)(e)&&c.includes(null==(t=e.props)?void 0:t.mdxType)}))?a.createElement("code",e):a.createElement(n.Z,e)},a:function(e){return a.createElement(s.Z,e)},pre:function(e){var c;return a.createElement(n.Z,(0,a.isValidElement)(e.children)&&"code"===(null==(c=e.children.props)?void 0:c.originalType)?e.children.props:{...e})},details:function(e){const c=a.Children.toArray(e.children),t=c.find((e=>{var c;return a.isValidElement(e)&&"summary"===(null==(c=e.props)?void 0:c.mdxType)})),r=a.createElement(a.Fragment,null,c.filter((e=>e!==t)));return a.createElement(o.Z,(0,l.Z)({},e,{summary:t}),r)},ul:h.Z,img:u.Z,h1:e=>a.createElement(m,(0,l.Z)({as:"h1"},e)),h2:e=>a.createElement(m,(0,l.Z)({as:"h2"},e)),h3:e=>a.createElement(m,(0,l.Z)({as:"h3"},e)),h4:e=>a.createElement(m,(0,l.Z)({as:"h4"},e)),h5:e=>a.createElement(m,(0,l.Z)({as:"h5"},e)),h6:e=>a.createElement(m,(0,l.Z)({as:"h6"},e)),admonition:d.Z,mermaid:p.Z,github:function(e){let{org:c,repo:t}=e;const[l,r]=(0,a.useState)(-1);return(0,a.useEffect)((()=>{fetch(`https://api.github.com/repos/${c}/${t}`,{cache:"no-cache",mode:"cors",headers:{Accept:"application/vnd.github+json"}}).then((e=>e.json())).then((e=>{r(e.stargazers_count)}))}),[]),a.createElement("section",null,a.createElement("div",{className:"max-w-2xl mx-auto my-8"},a.createElement("div",{className:"relative bg-white py-4 px-5 md:py-5 md:px-6"},a.createElement("div",{className:"absolute right-0 top-0 -ml-40 pointer-events-none","aria-hidden":"true"},a.createElement("svg",{width:"238",className:"h-full opacity-75",fill:"none",xmlns:"http://www.w3.org/2000/svg"},a.createElement("defs",null,a.createElement("linearGradient",{id:"illustration-04",x1:"369.483",y1:"-84.633",x2:"139.954",y2:"-199.798",gradientUnits:"userSpaceOnUse"},a.createElement("stop",{stopColor:"#000",stopOpacity:".01"}),a.createElement("stop",{offset:"1",stopColor:"#000",stopOpacity:".24"}))),a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",className:"stroke-gray-300",d:"M189.135 89.198c3.624 9.678 7.039 18.799 15.713 18.187 7.885-.548 19.733-2.523 33.152-5.256v2.04c-13.345 2.709-25.125 4.663-33.013 5.211-.331.023-.657.034-.975.034-9.441 0-13.176-9.972-16.792-19.627-3.571-9.536-6.946-18.545-15.389-16.96-13.086 2.455-24.348 3.539-37.385 4.794l-.024.002c-8.07.776-17.217 1.657-27.841 2.98-4.629.58-8.116 1.595-10.919 2.411l-.016.005c-6.68 1.947-10.032 2.924-14.897-6.267-3.62-6.842-8.541-7.827-14.24-8.967h-.001c-4.793-.959-10.225-2.046-15.65-6.76C40.64 52.141 15.48 20.345.66 0H3.13c14.82 20.254 39.089 50.863 49.042 59.515 5.023 4.367 9.956 5.354 14.73 6.31 5.94 1.187 11.552 2.31 15.616 9.991 3.443 6.51 5.39 7.141 9.773 6.057-3.311.19-5.726-1.455-8.768-7.374-3.533-6.876-8.064-7.803-13.8-8.976-4.642-.949-9.902-2.025-15.275-6.679C43.995 49.797 18.704 19.375 4.057 0h2.506C21.226 19.288 45.58 48.524 55.755 57.333c4.977 4.309 9.748 5.285 14.363 6.23l.005.001c5.763 1.178 11.206 2.292 15.178 10.021 3.255 6.333 5.085 6.977 9.146 5.928-3.035.107-5.304-1.569-8.148-7.27-3.45-6.913-7.822-7.829-13.359-8.988-4.49-.939-9.58-2.004-14.902-6.593C47.268 47.376 21.798 18.312 7.406 0h2.572c14.477 18.232 39.16 46.348 49.366 55.147 4.93 4.252 9.544 5.217 14.005 6.15h.002c5.583 1.17 10.856 2.273 14.737 10.053 1.853 3.713 3.336 5.515 4.959 6.027.993.312 2.15.164 3.558-.212-2.77.013-4.89-1.707-7.534-7.175-3.363-6.95-7.578-7.854-12.914-8.998h-.003c-4.34-.93-9.259-1.984-14.528-6.509C50.465 44.901 24.695 17.086 10.69 0h2.583C27.39 17.058 52.088 43.659 62.93 52.965c4.883 4.194 9.337 5.148 13.644 6.07l.002.001c5.404 1.158 10.508 2.253 14.297 10.083 1.74 3.6 3.195 5.421 4.712 5.906 1.453.463 3.288-.17 5.829-1.05l.005-.002c2.872-.995 6.804-2.356 12.263-2.776 10.687-.813 19.576-.84 28.174-.867 8.671-.027 16.548-.055 24.765-.913-6.672.214-13.232-.169-20.311-.59-8.482-.504-17.257-1.025-27.637-.582-5.471.237-9.134 1.68-12.076 2.838-5.4 2.127-8.165 2.774-11.971-5.607-3.193-7.03-7.09-7.908-12.025-9.019-4.044-.91-8.628-1.944-13.791-6.34C56.639 39.755 30.287 15.234 16.926 0h2.688c13.353 14.888 38.3 38.212 50.492 48.595 4.787 4.075 9.115 5.051 12.933 5.911 5.26 1.184 9.802 2.207 13.407 10.142 3.19 7.023 4.631 6.458 9.418 4.574l.002-.001c2.919-1.149 6.915-2.722 12.72-2.974 10.488-.448 19.311.076 27.841.583 9.399.56 17.871 1.054 26.886.14-7.662.148-15.028-.743-22.644-1.672l-.129-.016c-8.337-1.017-16.965-2.07-27.032-1.98-5.676.051-9.475 1.759-12.25 3.006h-.001l-.009.004c-2.405 1.081-4.305 1.935-6.216 1.186-1.747-.684-3.2-2.637-4.855-6.53-3.024-7.113-6.422-7.922-11.125-9.04-3.568-.849-8.01-1.906-13.06-6.172-3.452-2.915-8.08-6.644-12.982-10.59C49.18 24.025 32.319 10.441 23.107.347A22.509 22.509 0 0121.788 0h7.364c-.172.105-.354.2-.546.282C36.59 8.69 50.299 18.877 62.563 27.985l.026.02c6.966 5.173 13.544 10.06 18.276 14.038 4.635 3.899 8.487 4.842 11.885 5.674 4.679 1.145 8.721 2.134 12.048 10.233 1.33 3.238 2.466 4.944 3.575 5.37 1.047.398 2.446-.272 4.385-1.203l.004-.002c2.896-1.39 6.848-3.288 12.92-3.288h.127l.131.001c10.128.096 18.8 1.427 27.186 2.715 10.143 1.558 19.227 2.942 29.116 1.933-8.585.026-16.703-1.72-25.117-3.543l-.012-.002c-8.19-1.775-16.659-3.61-26.357-4.05-5.874-.272-9.581 1.763-12.297 3.253l-.032.018c-2.1 1.152-3.756 2.06-5.499 1.424-1.642-.604-2.926-2.45-4.427-6.376-2.775-7.256-5.555-7.979-9.764-9.074h-.002c-3.165-.824-7.103-1.85-11.977-5.914-5.877-4.9-14.04-9.772-22.683-14.929-11.904-7.1-24.212-14.445-31.192-22.409A21.936 21.936 0 0131.402 0h2.51c.151.181.309.366.475.555a41.174 41.174 0 002.058 2.161A19.713 19.713 0 0134.51 0h2.345a21.721 21.721 0 001.719 2.138 36.154 36.154 0 001.535 1.586C39.087 2.47 38.283 1.231 37.663 0h2.283c.712 1.228 1.636 2.464 2.812 3.727.39.418.797.826 1.214 1.228A24.14 24.14 0 0140.872 0h2.188c.968 1.84 2.244 3.608 3.885 5.318a26.373 26.373 0 00.912.893A31.463 31.463 0 0144.03 0h2.22c1.672 3.3 3.549 5.556 4.882 6.906 6.749 6.832 16.135 9.186 26.072 11.678l.006.002c8.887 2.228 18.076 4.533 25.178 10.355 4.299 3.524 7.382 4.447 9.858 5.188 4.261 1.276 6.609 2.32 9.26 10.426 1.233 3.767 2.108 4.761 2.625 4.931.593.191 1.683-.578 2.941-1.475l.015-.011c2.699-1.925 6.77-4.828 13.572-4 9.344 1.131 17.646 3.986 25.674 6.748 13.142 4.52 25.555 8.787 40.152 4.348 9.929-3.023 20.193-.49 30.12 1.96l.012.003 1.382.34v2.06l-1.87-.46c-5.67-1.4-11.163-2.755-16.554-3.17 4.327.818 8.598 2.19 12.803 3.545 1.856.599 3.731 1.203 5.621 1.764v2.086c-2.099-.612-4.175-1.282-6.23-1.944l-.004-.002c-5.464-1.762-10.75-3.457-16.03-4.018 4.349 1.003 8.58 2.716 12.741 4.405 3.116 1.265 6.281 2.55 9.523 3.555v2.094c-3.516-1.053-6.922-2.435-10.272-3.795h-.003c-5.35-2.173-10.514-4.267-15.793-4.936 4.45 1.177 8.694 3.283 12.864 5.358l.173.087c4.197 2.09 8.485 4.224 13.031 5.441v2.056c-4.973-1.253-9.583-3.547-14.093-5.792h-.002c-5.186-2.582-10.186-5.06-15.439-5.842 4.499 1.353 8.69 3.858 12.803 6.321h.001c5.244 3.141 10.636 6.37 16.73 7.339v2.027c-6.578-.956-12.241-4.346-17.75-7.644l-.009-.006c-7.325-4.387-14.258-8.518-22.642-6.536 6.503.685 11.778 5.075 16.916 9.363l.083.07c5.881 4.91 11.941 9.968 20.03 9.724 1.069-.031 2.194-.083 3.372-.155v2.003c-1.156.07-2.261.12-3.313.151-.207.006-.414.01-.618.01-8.534 0-14.783-5.216-20.833-10.265l-.002-.002c-4.717-3.938-9.252-7.703-14.586-8.719 4.734 1.825 8.707 5.677 12.594 9.458l.042.041c5.622 5.471 11.424 11.116 19.623 10.832 2.143-.074 4.52-.233 7.093-.469v1.986c-2.612.248-4.968.411-7.025.482-.227.008-.453.012-.677.012-8.683 0-14.662-5.817-20.449-11.449l-.002-.002c-6.138-5.97-11.934-11.607-20.396-9.544a6.362 6.362 0 01-.264.06c6.645.94 11.198 6.85 15.624 12.615l.018.024c5.046 6.575 10.262 13.37 18.631 12.993 4.052-.18 8.987-.683 14.54-1.438v2.016c-5.51.744-10.413 1.24-14.45 1.42-.262.012-.521.018-.777.018-8.945 0-14.331-7.017-19.546-13.811l-.003-.004-.006-.007c-5.346-6.966-10.397-13.547-18.803-11.626-.132.03-.261.057-.391.084l-.311.066c6.794 1.085 10.839 8.053 14.767 14.848 4.641 8.027 9.03 15.614 17.534 15.145 5.726-.312 13.322-1.305 21.986-2.76v2.023c-8.612 1.44-16.166 2.423-21.877 2.734-.291.016-.58.024-.862.024-9.167 0-13.914-8.21-18.51-16.16l-.003-.005c-3.706-6.412-7.25-12.526-12.858-13.763 5.122 2.473 8.33 8.832 11.453 15.061 4.311 8.593 8.385 16.71 16.95 16.2 6.486-.386 15.461-1.675 25.707-3.53v2.028c-10.185 1.837-19.111 3.112-25.587 3.498-.305.018-.607.028-.902.028-9.266.001-13.681-8.802-17.955-17.325l-.001-.003-.007-.012c-3.481-6.943-6.805-13.57-12.502-14.813 5.221 2.575 8.235 9.477 11.168 16.232 3.976 9.158 7.731 17.803 16.357 17.251 7.205-.465 17.596-2.081 29.429-4.364v2.035c-11.765 2.261-22.099 3.86-29.3 4.325a14.29 14.29 0 01-.939.031c-9.357 0-13.434-9.39-17.382-18.48v-.002c-3.236-7.452-6.334-14.556-12.065-15.862 5.271 2.704 8.063 10.121 10.779 17.372l.042.114zm-85.541-10.165a58.657 58.657 0 012.739-.415c4.4-.548 8.533-1.017 12.453-1.437-3.127.273-6.375.582-9.789.953-2.012.221-3.792.54-5.403.9zm20.806-4.32c-4.073.225-8.35.52-12.983.95a43.406 43.406 0 00-5.73.921 51.813 51.813 0 013.094-.438 494.47 494.47 0 0115.619-1.434zm5.224-2.265c-4.911.104-10.092.31-15.791.743a38.9 38.9 0 00-5.905.912 46.087 46.087 0 013.305-.433c6.728-.622 12.731-.974 18.391-1.222zm-3.703-11.62h-.235c-2.341 0-4.335.317-6.08.772a28.976 28.976 0 013.885-.298c10.241-.069 18.981.981 27.421 2.011.905.11 1.799.22 2.689.326l-.39-.06-.388-.059-.01-.001c-8.314-1.277-16.911-2.597-26.892-2.69zm-64.55-31.237C48.6 20.107 34.27 9.46 26.29.733a2.244 2.244 0 01-.083.002c9.365 9.76 25.058 22.401 38.058 32.872l.08.065c5.089 4.1 9.486 7.641 12.938 10.556 4.686 3.96 8.696 4.913 12.232 5.754 4.874 1.16 9.083 2.161 12.502 10.203 1.388 3.262 2.577 4.994 3.744 5.451.701.275 1.542.12 2.573-.259a3.898 3.898 0 01-.677-.19c-1.704-.655-3.113-2.592-4.708-6.477-2.942-7.158-6.185-7.952-10.673-9.05-3.433-.84-7.704-1.887-12.698-6.087-4.691-3.944-11.256-8.82-18.207-13.982zm97.895 28.533c-8.129-2.019-16.534-4.106-26.095-4.718-2.483-.159-4.567.13-6.353.632 1.228-.155 2.562-.222 4.028-.155 9.866.449 18.418 2.301 26.688 4.092l.014.003c2.655.575 5.278 1.14 7.894 1.646a444.507 444.507 0 01-6.176-1.5zm-68.92-21.098c-6.198-5.129-14.641-9.493-23.581-14.113-2.88-1.488-5.781-2.989-8.626-4.529a942.257 942.257 0 006.96 4.182c8.713 5.198 16.942 10.108 22.94 15.11 4.528 3.777 8.07 4.699 11.196 5.513l.006.001c4.462 1.161 7.985 2.078 11.128 10.295 1.204 3.147 2.266 4.852 3.249 5.213.551.204 1.244.014 2.105-.387-.023-.007-.046-.012-.069-.016-.028-.006-.056-.012-.084-.022-1.603-.574-2.847-2.408-4.293-6.33-2.69-7.301-5.32-8.008-9.3-9.076h-.002c-3.037-.816-6.815-1.83-11.628-5.84zm71.064 19.28c-8.064-2.259-16.403-4.595-25.821-5.373-2.502-.208-4.592.076-6.377.594a21.799 21.799 0 014.086-.117c9.74.623 18.236 2.733 26.45 4.773 3.145.781 6.247 1.55 9.344 2.211-2.548-.652-5.101-1.365-7.682-2.088zM69.811 21.884l-.008-.004a654.364 654.364 0 01-4.285-1.864l2.165 1.12.012.007c8.636 4.464 17.565 9.079 23.93 14.345 4.477 3.731 7.872 4.642 10.869 5.446h.001c4.252 1.142 7.611 2.044 10.659 10.317 1.152 3.126 2.163 4.807 3.09 5.14.503.18 1.149-.019 1.955-.424-1.556-.55-2.758-2.373-4.144-6.28-2.61-7.36-4.958-8.013-8.848-9.094-2.905-.807-6.52-1.812-11.267-5.747-6.443-5.316-15.434-9.203-24.129-12.962zm70.608 24.101c-2.506-.303-4.579-.04-6.337.5a19.188 19.188 0 014.124-.013c9.477.963 17.845 3.573 25.938 6.098 3.996 1.246 7.925 2.47 11.867 3.448-3.43-1.01-6.853-2.184-10.327-3.379l-.018-.006c-7.926-2.725-16.12-5.543-25.247-6.648zm23.123 8.492c-7.996-2.494-16.264-5.073-25.539-6.016-2.495-.253-4.572.02-6.342.544a20.477 20.477 0 014.092-.066c9.602.794 18.029 3.154 26.178 5.436l.019.005c3.56.997 7.067 1.974 10.576 2.79-2.98-.825-5.959-1.749-8.978-2.69l-.006-.003zm-90.373-33.35l-.014-.006-.36-.123c8.124 3.527 16.306 7.263 22.419 12.307 4.42 3.663 7.665 4.565 10.53 5.361 4.044 1.124 7.239 2.012 10.196 10.352 1.101 3.106 2.061 4.764 2.932 5.068.459.158 1.079-.06 1.832-.468-1.453-.583-2.587-2.39-3.874-6.185-2.542-7.417-4.622-8.018-8.397-9.108l-.009-.003c-2.771-.801-6.221-1.8-10.894-5.653-6.623-5.444-15.64-8.544-24.36-11.543zm45.555 25.661c1.032 3.048 1.963 4.73 2.768 5.003.417.145 1.012-.097 1.744-.529-1.355-.615-2.427-2.41-3.629-6.085-2.45-7.49-4.398-8.073-7.931-9.131h-.002c-2.648-.793-5.944-1.78-10.552-5.558-6.026-4.94-13.81-7.262-21.575-9.25 6.993 2.523 13.83 5.43 19.253 9.888 4.361 3.594 7.591 4.527 10.187 5.277h.002c3.978 1.15 6.853 1.981 9.735 10.385z",fill:"url(#illustration-04)"}))),a.createElement("div",{className:"absolute left-2 -top-2 pointer-events-none z-0 opacity-20 overflow-hidden block md:hidden"},a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",height:"120",width:"120",viewBox:"0 0 48 48"},a.createElement("title",null,"logo github"),a.createElement("g",{className:"stroke-current",className:"nc-icon-wrapper"},a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",className:"stroke-current text-black",d:"M24,0.6c-13.3,0-24,10.7-24,24c0,10.6,6.9,19.6,16.4,22.8 c1.2,0.2,1.6-0.5,1.6-1.2c0-0.6,0-2.1,0-4.1c-6.7,1.5-8.1-3.2-8.1-3.2c-1.1-2.8-2.7-3.5-2.7-3.5c-2.2-1.5,0.2-1.5,0.2-1.5 c2.4,0.2,3.7,2.5,3.7,2.5c2.1,3.7,5.6,2.6,7,2c0.2-1.6,0.8-2.6,1.5-3.2c-5.3-0.6-10.9-2.7-10.9-11.9c0-2.6,0.9-4.8,2.5-6.4 c-0.2-0.6-1.1-3,0.2-6.4c0,0,2-0.6,6.6,2.5c1.9-0.5,4-0.8,6-0.8c2,0,4.1,0.3,6,0.8c4.6-3.1,6.6-2.5,6.6-2.5c1.3,3.3,0.5,5.7,0.2,6.4 c1.5,1.7,2.5,3.8,2.5,6.4c0,9.2-5.6,11.2-11,11.8c0.9,0.7,1.6,2.2,1.6,4.4c0,3.2,0,5.8,0,6.6c0,0.6,0.4,1.4,1.7,1.2 C41.1,44.2,48,35.2,48,24.6C48,11.3,37.3,0.6,24,0.6z"})))),a.createElement("div",{className:"relative flex flex-row justify-between items-center flex-nowrap p-2"},a.createElement("div",{className:"flex-row items-center hidden md:flex"},a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",height:"56",width:"56",viewBox:"0 0 48 48"},a.createElement("title",null,"logo github"),a.createElement("g",{className:"stroke-current",className:"nc-icon-wrapper"},a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",className:"stroke-current text-black",d:"M24,0.6c-13.3,0-24,10.7-24,24c0,10.6,6.9,19.6,16.4,22.8 c1.2,0.2,1.6-0.5,1.6-1.2c0-0.6,0-2.1,0-4.1c-6.7,1.5-8.1-3.2-8.1-3.2c-1.1-2.8-2.7-3.5-2.7-3.5c-2.2-1.5,0.2-1.5,0.2-1.5 c2.4,0.2,3.7,2.5,3.7,2.5c2.1,3.7,5.6,2.6,7,2c0.2-1.6,0.8-2.6,1.5-3.2c-5.3-0.6-10.9-2.7-10.9-11.9c0-2.6,0.9-4.8,2.5-6.4 c-0.2-0.6-1.1-3,0.2-6.4c0,0,2-0.6,6.6,2.5c1.9-0.5,4-0.8,6-0.8c2,0,4.1,0.3,6,0.8c4.6-3.1,6.6-2.5,6.6-2.5c1.3,3.3,0.5,5.7,0.2,6.4 c1.5,1.7,2.5,3.8,2.5,6.4c0,9.2-5.6,11.2-11,11.8c0.9,0.7,1.6,2.2,1.6,4.4c0,3.2,0,5.8,0,6.6c0,0.6,0.4,1.4,1.7,1.2 C41.1,44.2,48,35.2,48,24.6C48,11.3,37.3,0.6,24,0.6z"})))),a.createElement("p",{className:"text-3xl font-bold text-black xl:mb-0 text-center xl:text-left xl:mr-2 xl:mb-0 mb-2"},a.createElement("a",{className:"text-black hover:text-gray-600",href:`https://github.com/${c}`},c)," / ",a.createElement("a",{className:"text-black hover:text-gray-600",href:`https://github.com/${c}/${t}`},t))))))},youtube:function(e){let{videoUrl:c,videoKey:t}=e;const l=t?`https://www.youtube.com/embed/${t}`:c;return a.createElement("section",null,a.createElement("iframe",{className:"w-full aspect-video",src:l,frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}))}}},1748:(e,c,t)=>{var l={"./locale":9234,"./locale.js":9234};function a(e){var c=r(e);return t(c)}function r(e){if(!t.o(l,e)){var c=new Error("Cannot find module '"+e+"'");throw c.code="MODULE_NOT_FOUND",c}return l[e]}a.keys=function(){return Object.keys(l)},a.resolve=r,e.exports=a,a.id=1748}}]); \ No newline at end of file diff --git a/assets/js/17896441.4f19350c.js b/assets/js/17896441.4f19350c.js deleted file mode 100644 index 9dc9c0c7..00000000 --- a/assets/js/17896441.4f19350c.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[918],{5797:(e,c,t)=>{"use strict";t.d(c,{Z:()=>n});var l=t(7294),a=t(4966);const r=function(){return l.createElement("section",null,l.createElement("div",{className:"max-w-6xl mx-auto px-4 sm:px-6"},l.createElement("div",{className:"relative bg-cyan-600 py-4 px-5 md:py-5 md:px-6"},l.createElement("div",{className:"absolute right-0 top-0 -ml-40 pointer-events-none","aria-hidden":"true"},l.createElement("svg",{width:"238",height:"110",fill:"none",xmlns:"http://www.w3.org/2000/svg"},l.createElement("defs",null,l.createElement("linearGradient",{id:"illustration-04",x1:"369.483",y1:"-84.633",x2:"139.954",y2:"-199.798",gradientUnits:"userSpaceOnUse"},l.createElement("stop",{stopColor:"#fff",stopOpacity:".01"}),l.createElement("stop",{offset:"1",stopColor:"#fff",stopOpacity:".24"}))),l.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M189.135 89.198c3.624 9.678 7.039 18.799 15.713 18.187 7.885-.548 19.733-2.523 33.152-5.256v2.04c-13.345 2.709-25.125 4.663-33.013 5.211-.331.023-.657.034-.975.034-9.441 0-13.176-9.972-16.792-19.627-3.571-9.536-6.946-18.545-15.389-16.96-13.086 2.455-24.348 3.539-37.385 4.794l-.024.002c-8.07.776-17.217 1.657-27.841 2.98-4.629.58-8.116 1.595-10.919 2.411l-.016.005c-6.68 1.947-10.032 2.924-14.897-6.267-3.62-6.842-8.541-7.827-14.24-8.967h-.001c-4.793-.959-10.225-2.046-15.65-6.76C40.64 52.141 15.48 20.345.66 0H3.13c14.82 20.254 39.089 50.863 49.042 59.515 5.023 4.367 9.956 5.354 14.73 6.31 5.94 1.187 11.552 2.31 15.616 9.991 3.443 6.51 5.39 7.141 9.773 6.057-3.311.19-5.726-1.455-8.768-7.374-3.533-6.876-8.064-7.803-13.8-8.976-4.642-.949-9.902-2.025-15.275-6.679C43.995 49.797 18.704 19.375 4.057 0h2.506C21.226 19.288 45.58 48.524 55.755 57.333c4.977 4.309 9.748 5.285 14.363 6.23l.005.001c5.763 1.178 11.206 2.292 15.178 10.021 3.255 6.333 5.085 6.977 9.146 5.928-3.035.107-5.304-1.569-8.148-7.27-3.45-6.913-7.822-7.829-13.359-8.988-4.49-.939-9.58-2.004-14.902-6.593C47.268 47.376 21.798 18.312 7.406 0h2.572c14.477 18.232 39.16 46.348 49.366 55.147 4.93 4.252 9.544 5.217 14.005 6.15h.002c5.583 1.17 10.856 2.273 14.737 10.053 1.853 3.713 3.336 5.515 4.959 6.027.993.312 2.15.164 3.558-.212-2.77.013-4.89-1.707-7.534-7.175-3.363-6.95-7.578-7.854-12.914-8.998h-.003c-4.34-.93-9.259-1.984-14.528-6.509C50.465 44.901 24.695 17.086 10.69 0h2.583C27.39 17.058 52.088 43.659 62.93 52.965c4.883 4.194 9.337 5.148 13.644 6.07l.002.001c5.404 1.158 10.508 2.253 14.297 10.083 1.74 3.6 3.195 5.421 4.712 5.906 1.453.463 3.288-.17 5.829-1.05l.005-.002c2.872-.995 6.804-2.356 12.263-2.776 10.687-.813 19.576-.84 28.174-.867 8.671-.027 16.548-.055 24.765-.913-6.672.214-13.232-.169-20.311-.59-8.482-.504-17.257-1.025-27.637-.582-5.471.237-9.134 1.68-12.076 2.838-5.4 2.127-8.165 2.774-11.971-5.607-3.193-7.03-7.09-7.908-12.025-9.019-4.044-.91-8.628-1.944-13.791-6.34C56.639 39.755 30.287 15.234 16.926 0h2.688c13.353 14.888 38.3 38.212 50.492 48.595 4.787 4.075 9.115 5.051 12.933 5.911 5.26 1.184 9.802 2.207 13.407 10.142 3.19 7.023 4.631 6.458 9.418 4.574l.002-.001c2.919-1.149 6.915-2.722 12.72-2.974 10.488-.448 19.311.076 27.841.583 9.399.56 17.871 1.054 26.886.14-7.662.148-15.028-.743-22.644-1.672l-.129-.016c-8.337-1.017-16.965-2.07-27.032-1.98-5.676.051-9.475 1.759-12.25 3.006h-.001l-.009.004c-2.405 1.081-4.305 1.935-6.216 1.186-1.747-.684-3.2-2.637-4.855-6.53-3.024-7.113-6.422-7.922-11.125-9.04-3.568-.849-8.01-1.906-13.06-6.172-3.452-2.915-8.08-6.644-12.982-10.59C49.18 24.025 32.319 10.441 23.107.347A22.509 22.509 0 0121.788 0h7.364c-.172.105-.354.2-.546.282C36.59 8.69 50.299 18.877 62.563 27.985l.026.02c6.966 5.173 13.544 10.06 18.276 14.038 4.635 3.899 8.487 4.842 11.885 5.674 4.679 1.145 8.721 2.134 12.048 10.233 1.33 3.238 2.466 4.944 3.575 5.37 1.047.398 2.446-.272 4.385-1.203l.004-.002c2.896-1.39 6.848-3.288 12.92-3.288h.127l.131.001c10.128.096 18.8 1.427 27.186 2.715 10.143 1.558 19.227 2.942 29.116 1.933-8.585.026-16.703-1.72-25.117-3.543l-.012-.002c-8.19-1.775-16.659-3.61-26.357-4.05-5.874-.272-9.581 1.763-12.297 3.253l-.032.018c-2.1 1.152-3.756 2.06-5.499 1.424-1.642-.604-2.926-2.45-4.427-6.376-2.775-7.256-5.555-7.979-9.764-9.074h-.002c-3.165-.824-7.103-1.85-11.977-5.914-5.877-4.9-14.04-9.772-22.683-14.929-11.904-7.1-24.212-14.445-31.192-22.409A21.936 21.936 0 0131.402 0h2.51c.151.181.309.366.475.555a41.174 41.174 0 002.058 2.161A19.713 19.713 0 0134.51 0h2.345a21.721 21.721 0 001.719 2.138 36.154 36.154 0 001.535 1.586C39.087 2.47 38.283 1.231 37.663 0h2.283c.712 1.228 1.636 2.464 2.812 3.727.39.418.797.826 1.214 1.228A24.14 24.14 0 0140.872 0h2.188c.968 1.84 2.244 3.608 3.885 5.318a26.373 26.373 0 00.912.893A31.463 31.463 0 0144.03 0h2.22c1.672 3.3 3.549 5.556 4.882 6.906 6.749 6.832 16.135 9.186 26.072 11.678l.006.002c8.887 2.228 18.076 4.533 25.178 10.355 4.299 3.524 7.382 4.447 9.858 5.188 4.261 1.276 6.609 2.32 9.26 10.426 1.233 3.767 2.108 4.761 2.625 4.931.593.191 1.683-.578 2.941-1.475l.015-.011c2.699-1.925 6.77-4.828 13.572-4 9.344 1.131 17.646 3.986 25.674 6.748 13.142 4.52 25.555 8.787 40.152 4.348 9.929-3.023 20.193-.49 30.12 1.96l.012.003 1.382.34v2.06l-1.87-.46c-5.67-1.4-11.163-2.755-16.554-3.17 4.327.818 8.598 2.19 12.803 3.545 1.856.599 3.731 1.203 5.621 1.764v2.086c-2.099-.612-4.175-1.282-6.23-1.944l-.004-.002c-5.464-1.762-10.75-3.457-16.03-4.018 4.349 1.003 8.58 2.716 12.741 4.405 3.116 1.265 6.281 2.55 9.523 3.555v2.094c-3.516-1.053-6.922-2.435-10.272-3.795h-.003c-5.35-2.173-10.514-4.267-15.793-4.936 4.45 1.177 8.694 3.283 12.864 5.358l.173.087c4.197 2.09 8.485 4.224 13.031 5.441v2.056c-4.973-1.253-9.583-3.547-14.093-5.792h-.002c-5.186-2.582-10.186-5.06-15.439-5.842 4.499 1.353 8.69 3.858 12.803 6.321h.001c5.244 3.141 10.636 6.37 16.73 7.339v2.027c-6.578-.956-12.241-4.346-17.75-7.644l-.009-.006c-7.325-4.387-14.258-8.518-22.642-6.536 6.503.685 11.778 5.075 16.916 9.363l.083.07c5.881 4.91 11.941 9.968 20.03 9.724 1.069-.031 2.194-.083 3.372-.155v2.003c-1.156.07-2.261.12-3.313.151-.207.006-.414.01-.618.01-8.534 0-14.783-5.216-20.833-10.265l-.002-.002c-4.717-3.938-9.252-7.703-14.586-8.719 4.734 1.825 8.707 5.677 12.594 9.458l.042.041c5.622 5.471 11.424 11.116 19.623 10.832 2.143-.074 4.52-.233 7.093-.469v1.986c-2.612.248-4.968.411-7.025.482-.227.008-.453.012-.677.012-8.683 0-14.662-5.817-20.449-11.449l-.002-.002c-6.138-5.97-11.934-11.607-20.396-9.544a6.362 6.362 0 01-.264.06c6.645.94 11.198 6.85 15.624 12.615l.018.024c5.046 6.575 10.262 13.37 18.631 12.993 4.052-.18 8.987-.683 14.54-1.438v2.016c-5.51.744-10.413 1.24-14.45 1.42-.262.012-.521.018-.777.018-8.945 0-14.331-7.017-19.546-13.811l-.003-.004-.006-.007c-5.346-6.966-10.397-13.547-18.803-11.626-.132.03-.261.057-.391.084l-.311.066c6.794 1.085 10.839 8.053 14.767 14.848 4.641 8.027 9.03 15.614 17.534 15.145 5.726-.312 13.322-1.305 21.986-2.76v2.023c-8.612 1.44-16.166 2.423-21.877 2.734-.291.016-.58.024-.862.024-9.167 0-13.914-8.21-18.51-16.16l-.003-.005c-3.706-6.412-7.25-12.526-12.858-13.763 5.122 2.473 8.33 8.832 11.453 15.061 4.311 8.593 8.385 16.71 16.95 16.2 6.486-.386 15.461-1.675 25.707-3.53v2.028c-10.185 1.837-19.111 3.112-25.587 3.498-.305.018-.607.028-.902.028-9.266.001-13.681-8.802-17.955-17.325l-.001-.003-.007-.012c-3.481-6.943-6.805-13.57-12.502-14.813 5.221 2.575 8.235 9.477 11.168 16.232 3.976 9.158 7.731 17.803 16.357 17.251 7.205-.465 17.596-2.081 29.429-4.364v2.035c-11.765 2.261-22.099 3.86-29.3 4.325a14.29 14.29 0 01-.939.031c-9.357 0-13.434-9.39-17.382-18.48v-.002c-3.236-7.452-6.334-14.556-12.065-15.862 5.271 2.704 8.063 10.121 10.779 17.372l.042.114zm-85.541-10.165a58.657 58.657 0 012.739-.415c4.4-.548 8.533-1.017 12.453-1.437-3.127.273-6.375.582-9.789.953-2.012.221-3.792.54-5.403.9zm20.806-4.32c-4.073.225-8.35.52-12.983.95a43.406 43.406 0 00-5.73.921 51.813 51.813 0 013.094-.438 494.47 494.47 0 0115.619-1.434zm5.224-2.265c-4.911.104-10.092.31-15.791.743a38.9 38.9 0 00-5.905.912 46.087 46.087 0 013.305-.433c6.728-.622 12.731-.974 18.391-1.222zm-3.703-11.62h-.235c-2.341 0-4.335.317-6.08.772a28.976 28.976 0 013.885-.298c10.241-.069 18.981.981 27.421 2.011.905.11 1.799.22 2.689.326l-.39-.06-.388-.059-.01-.001c-8.314-1.277-16.911-2.597-26.892-2.69zm-64.55-31.237C48.6 20.107 34.27 9.46 26.29.733a2.244 2.244 0 01-.083.002c9.365 9.76 25.058 22.401 38.058 32.872l.08.065c5.089 4.1 9.486 7.641 12.938 10.556 4.686 3.96 8.696 4.913 12.232 5.754 4.874 1.16 9.083 2.161 12.502 10.203 1.388 3.262 2.577 4.994 3.744 5.451.701.275 1.542.12 2.573-.259a3.898 3.898 0 01-.677-.19c-1.704-.655-3.113-2.592-4.708-6.477-2.942-7.158-6.185-7.952-10.673-9.05-3.433-.84-7.704-1.887-12.698-6.087-4.691-3.944-11.256-8.82-18.207-13.982zm97.895 28.533c-8.129-2.019-16.534-4.106-26.095-4.718-2.483-.159-4.567.13-6.353.632 1.228-.155 2.562-.222 4.028-.155 9.866.449 18.418 2.301 26.688 4.092l.014.003c2.655.575 5.278 1.14 7.894 1.646a444.507 444.507 0 01-6.176-1.5zm-68.92-21.098c-6.198-5.129-14.641-9.493-23.581-14.113-2.88-1.488-5.781-2.989-8.626-4.529a942.257 942.257 0 006.96 4.182c8.713 5.198 16.942 10.108 22.94 15.11 4.528 3.777 8.07 4.699 11.196 5.513l.006.001c4.462 1.161 7.985 2.078 11.128 10.295 1.204 3.147 2.266 4.852 3.249 5.213.551.204 1.244.014 2.105-.387-.023-.007-.046-.012-.069-.016-.028-.006-.056-.012-.084-.022-1.603-.574-2.847-2.408-4.293-6.33-2.69-7.301-5.32-8.008-9.3-9.076h-.002c-3.037-.816-6.815-1.83-11.628-5.84zm71.064 19.28c-8.064-2.259-16.403-4.595-25.821-5.373-2.502-.208-4.592.076-6.377.594a21.799 21.799 0 014.086-.117c9.74.623 18.236 2.733 26.45 4.773 3.145.781 6.247 1.55 9.344 2.211-2.548-.652-5.101-1.365-7.682-2.088zM69.811 21.884l-.008-.004a654.364 654.364 0 01-4.285-1.864l2.165 1.12.012.007c8.636 4.464 17.565 9.079 23.93 14.345 4.477 3.731 7.872 4.642 10.869 5.446h.001c4.252 1.142 7.611 2.044 10.659 10.317 1.152 3.126 2.163 4.807 3.09 5.14.503.18 1.149-.019 1.955-.424-1.556-.55-2.758-2.373-4.144-6.28-2.61-7.36-4.958-8.013-8.848-9.094-2.905-.807-6.52-1.812-11.267-5.747-6.443-5.316-15.434-9.203-24.129-12.962zm70.608 24.101c-2.506-.303-4.579-.04-6.337.5a19.188 19.188 0 014.124-.013c9.477.963 17.845 3.573 25.938 6.098 3.996 1.246 7.925 2.47 11.867 3.448-3.43-1.01-6.853-2.184-10.327-3.379l-.018-.006c-7.926-2.725-16.12-5.543-25.247-6.648zm23.123 8.492c-7.996-2.494-16.264-5.073-25.539-6.016-2.495-.253-4.572.02-6.342.544a20.477 20.477 0 014.092-.066c9.602.794 18.029 3.154 26.178 5.436l.019.005c3.56.997 7.067 1.974 10.576 2.79-2.98-.825-5.959-1.749-8.978-2.69l-.006-.003zm-90.373-33.35l-.014-.006-.36-.123c8.124 3.527 16.306 7.263 22.419 12.307 4.42 3.663 7.665 4.565 10.53 5.361 4.044 1.124 7.239 2.012 10.196 10.352 1.101 3.106 2.061 4.764 2.932 5.068.459.158 1.079-.06 1.832-.468-1.453-.583-2.587-2.39-3.874-6.185-2.542-7.417-4.622-8.018-8.397-9.108l-.009-.003c-2.771-.801-6.221-1.8-10.894-5.653-6.623-5.444-15.64-8.544-24.36-11.543zm45.555 25.661c1.032 3.048 1.963 4.73 2.768 5.003.417.145 1.012-.097 1.744-.529-1.355-.615-2.427-2.41-3.629-6.085-2.45-7.49-4.398-8.073-7.931-9.131h-.002c-2.648-.793-5.944-1.78-10.552-5.558-6.026-4.94-13.81-7.262-21.575-9.25 6.993 2.523 13.83 5.43 19.253 9.888 4.361 3.594 7.591 4.527 10.187 5.277h.002c3.978 1.15 6.853 1.981 9.735 10.385z",fill:"url(#illustration-04)"}))),l.createElement("div",{className:"relative flex flex-col xl:flex-row justify-between items-center"},l.createElement("h4",{className:"h4 text-white xl:mb-0 text-center"},"Touchlab KMP Insiders Newsletter"),l.createElement("a",{className:"btn text-cyan-600 bg-cyan-100 hover:bg-white shadow text-xl",href:"https://form.typeform.com/to/MJTpmm"},"Subscribe")))))};function n(e){return l.createElement(l.Fragment,null,l.createElement(a.Z,e),l.createElement("div",{className:"mt-8"},l.createElement(r,null)))}},7665:(e,c,t)=>{"use strict";t.d(c,{Z:()=>v});var l=t(7462),a=t(7294),r=t(5742);var n=t(814);var s=t(9960);var o=t(4673);var i=t(7955);function m(e){return a.createElement(i.Z,e)}var h=t(7390),u=t(1470),d=t(3612),p=t(3114);const v={head:function(e){const c=a.Children.map(e.children,(e=>a.isValidElement(e)?function(e){var c;if(null!=(c=e.props)&&c.mdxType&&e.props.originalType){const{mdxType:c,originalType:t,...l}=e.props;return a.createElement(e.props.originalType,l)}return e}(e):e));return a.createElement(r.Z,e,c)},code:function(e){const c=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return a.Children.toArray(e.children).every((e=>{var t;return"string"==typeof e&&!e.includes("\n")||(0,a.isValidElement)(e)&&c.includes(null==(t=e.props)?void 0:t.mdxType)}))?a.createElement("code",e):a.createElement(n.Z,e)},a:function(e){return a.createElement(s.Z,e)},pre:function(e){var c;return a.createElement(n.Z,(0,a.isValidElement)(e.children)&&"code"===(null==(c=e.children.props)?void 0:c.originalType)?e.children.props:{...e})},details:function(e){const c=a.Children.toArray(e.children),t=c.find((e=>{var c;return a.isValidElement(e)&&"summary"===(null==(c=e.props)?void 0:c.mdxType)})),r=a.createElement(a.Fragment,null,c.filter((e=>e!==t)));return a.createElement(o.Z,(0,l.Z)({},e,{summary:t}),r)},ul:h.Z,img:u.Z,h1:e=>a.createElement(m,(0,l.Z)({as:"h1"},e)),h2:e=>a.createElement(m,(0,l.Z)({as:"h2"},e)),h3:e=>a.createElement(m,(0,l.Z)({as:"h3"},e)),h4:e=>a.createElement(m,(0,l.Z)({as:"h4"},e)),h5:e=>a.createElement(m,(0,l.Z)({as:"h5"},e)),h6:e=>a.createElement(m,(0,l.Z)({as:"h6"},e)),admonition:d.Z,mermaid:p.Z,github:function(e){let{org:c,repo:t}=e;const[l,r]=(0,a.useState)(-1);return(0,a.useEffect)((()=>{fetch(`https://api.github.com/repos/${c}/${t}`,{cache:"no-cache",mode:"cors",headers:{Accept:"application/vnd.github+json"}}).then((e=>e.json())).then((e=>{r(e.stargazers_count)}))}),[]),a.createElement("section",null,a.createElement("div",{className:"max-w-2xl mx-auto my-8"},a.createElement("div",{className:"relative bg-white py-4 px-5 md:py-5 md:px-6"},a.createElement("div",{className:"absolute right-0 top-0 -ml-40 pointer-events-none","aria-hidden":"true"},a.createElement("svg",{width:"238",className:"h-full opacity-75",fill:"none",xmlns:"http://www.w3.org/2000/svg"},a.createElement("defs",null,a.createElement("linearGradient",{id:"illustration-04",x1:"369.483",y1:"-84.633",x2:"139.954",y2:"-199.798",gradientUnits:"userSpaceOnUse"},a.createElement("stop",{stopColor:"#000",stopOpacity:".01"}),a.createElement("stop",{offset:"1",stopColor:"#000",stopOpacity:".24"}))),a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",className:"stroke-gray-300",d:"M189.135 89.198c3.624 9.678 7.039 18.799 15.713 18.187 7.885-.548 19.733-2.523 33.152-5.256v2.04c-13.345 2.709-25.125 4.663-33.013 5.211-.331.023-.657.034-.975.034-9.441 0-13.176-9.972-16.792-19.627-3.571-9.536-6.946-18.545-15.389-16.96-13.086 2.455-24.348 3.539-37.385 4.794l-.024.002c-8.07.776-17.217 1.657-27.841 2.98-4.629.58-8.116 1.595-10.919 2.411l-.016.005c-6.68 1.947-10.032 2.924-14.897-6.267-3.62-6.842-8.541-7.827-14.24-8.967h-.001c-4.793-.959-10.225-2.046-15.65-6.76C40.64 52.141 15.48 20.345.66 0H3.13c14.82 20.254 39.089 50.863 49.042 59.515 5.023 4.367 9.956 5.354 14.73 6.31 5.94 1.187 11.552 2.31 15.616 9.991 3.443 6.51 5.39 7.141 9.773 6.057-3.311.19-5.726-1.455-8.768-7.374-3.533-6.876-8.064-7.803-13.8-8.976-4.642-.949-9.902-2.025-15.275-6.679C43.995 49.797 18.704 19.375 4.057 0h2.506C21.226 19.288 45.58 48.524 55.755 57.333c4.977 4.309 9.748 5.285 14.363 6.23l.005.001c5.763 1.178 11.206 2.292 15.178 10.021 3.255 6.333 5.085 6.977 9.146 5.928-3.035.107-5.304-1.569-8.148-7.27-3.45-6.913-7.822-7.829-13.359-8.988-4.49-.939-9.58-2.004-14.902-6.593C47.268 47.376 21.798 18.312 7.406 0h2.572c14.477 18.232 39.16 46.348 49.366 55.147 4.93 4.252 9.544 5.217 14.005 6.15h.002c5.583 1.17 10.856 2.273 14.737 10.053 1.853 3.713 3.336 5.515 4.959 6.027.993.312 2.15.164 3.558-.212-2.77.013-4.89-1.707-7.534-7.175-3.363-6.95-7.578-7.854-12.914-8.998h-.003c-4.34-.93-9.259-1.984-14.528-6.509C50.465 44.901 24.695 17.086 10.69 0h2.583C27.39 17.058 52.088 43.659 62.93 52.965c4.883 4.194 9.337 5.148 13.644 6.07l.002.001c5.404 1.158 10.508 2.253 14.297 10.083 1.74 3.6 3.195 5.421 4.712 5.906 1.453.463 3.288-.17 5.829-1.05l.005-.002c2.872-.995 6.804-2.356 12.263-2.776 10.687-.813 19.576-.84 28.174-.867 8.671-.027 16.548-.055 24.765-.913-6.672.214-13.232-.169-20.311-.59-8.482-.504-17.257-1.025-27.637-.582-5.471.237-9.134 1.68-12.076 2.838-5.4 2.127-8.165 2.774-11.971-5.607-3.193-7.03-7.09-7.908-12.025-9.019-4.044-.91-8.628-1.944-13.791-6.34C56.639 39.755 30.287 15.234 16.926 0h2.688c13.353 14.888 38.3 38.212 50.492 48.595 4.787 4.075 9.115 5.051 12.933 5.911 5.26 1.184 9.802 2.207 13.407 10.142 3.19 7.023 4.631 6.458 9.418 4.574l.002-.001c2.919-1.149 6.915-2.722 12.72-2.974 10.488-.448 19.311.076 27.841.583 9.399.56 17.871 1.054 26.886.14-7.662.148-15.028-.743-22.644-1.672l-.129-.016c-8.337-1.017-16.965-2.07-27.032-1.98-5.676.051-9.475 1.759-12.25 3.006h-.001l-.009.004c-2.405 1.081-4.305 1.935-6.216 1.186-1.747-.684-3.2-2.637-4.855-6.53-3.024-7.113-6.422-7.922-11.125-9.04-3.568-.849-8.01-1.906-13.06-6.172-3.452-2.915-8.08-6.644-12.982-10.59C49.18 24.025 32.319 10.441 23.107.347A22.509 22.509 0 0121.788 0h7.364c-.172.105-.354.2-.546.282C36.59 8.69 50.299 18.877 62.563 27.985l.026.02c6.966 5.173 13.544 10.06 18.276 14.038 4.635 3.899 8.487 4.842 11.885 5.674 4.679 1.145 8.721 2.134 12.048 10.233 1.33 3.238 2.466 4.944 3.575 5.37 1.047.398 2.446-.272 4.385-1.203l.004-.002c2.896-1.39 6.848-3.288 12.92-3.288h.127l.131.001c10.128.096 18.8 1.427 27.186 2.715 10.143 1.558 19.227 2.942 29.116 1.933-8.585.026-16.703-1.72-25.117-3.543l-.012-.002c-8.19-1.775-16.659-3.61-26.357-4.05-5.874-.272-9.581 1.763-12.297 3.253l-.032.018c-2.1 1.152-3.756 2.06-5.499 1.424-1.642-.604-2.926-2.45-4.427-6.376-2.775-7.256-5.555-7.979-9.764-9.074h-.002c-3.165-.824-7.103-1.85-11.977-5.914-5.877-4.9-14.04-9.772-22.683-14.929-11.904-7.1-24.212-14.445-31.192-22.409A21.936 21.936 0 0131.402 0h2.51c.151.181.309.366.475.555a41.174 41.174 0 002.058 2.161A19.713 19.713 0 0134.51 0h2.345a21.721 21.721 0 001.719 2.138 36.154 36.154 0 001.535 1.586C39.087 2.47 38.283 1.231 37.663 0h2.283c.712 1.228 1.636 2.464 2.812 3.727.39.418.797.826 1.214 1.228A24.14 24.14 0 0140.872 0h2.188c.968 1.84 2.244 3.608 3.885 5.318a26.373 26.373 0 00.912.893A31.463 31.463 0 0144.03 0h2.22c1.672 3.3 3.549 5.556 4.882 6.906 6.749 6.832 16.135 9.186 26.072 11.678l.006.002c8.887 2.228 18.076 4.533 25.178 10.355 4.299 3.524 7.382 4.447 9.858 5.188 4.261 1.276 6.609 2.32 9.26 10.426 1.233 3.767 2.108 4.761 2.625 4.931.593.191 1.683-.578 2.941-1.475l.015-.011c2.699-1.925 6.77-4.828 13.572-4 9.344 1.131 17.646 3.986 25.674 6.748 13.142 4.52 25.555 8.787 40.152 4.348 9.929-3.023 20.193-.49 30.12 1.96l.012.003 1.382.34v2.06l-1.87-.46c-5.67-1.4-11.163-2.755-16.554-3.17 4.327.818 8.598 2.19 12.803 3.545 1.856.599 3.731 1.203 5.621 1.764v2.086c-2.099-.612-4.175-1.282-6.23-1.944l-.004-.002c-5.464-1.762-10.75-3.457-16.03-4.018 4.349 1.003 8.58 2.716 12.741 4.405 3.116 1.265 6.281 2.55 9.523 3.555v2.094c-3.516-1.053-6.922-2.435-10.272-3.795h-.003c-5.35-2.173-10.514-4.267-15.793-4.936 4.45 1.177 8.694 3.283 12.864 5.358l.173.087c4.197 2.09 8.485 4.224 13.031 5.441v2.056c-4.973-1.253-9.583-3.547-14.093-5.792h-.002c-5.186-2.582-10.186-5.06-15.439-5.842 4.499 1.353 8.69 3.858 12.803 6.321h.001c5.244 3.141 10.636 6.37 16.73 7.339v2.027c-6.578-.956-12.241-4.346-17.75-7.644l-.009-.006c-7.325-4.387-14.258-8.518-22.642-6.536 6.503.685 11.778 5.075 16.916 9.363l.083.07c5.881 4.91 11.941 9.968 20.03 9.724 1.069-.031 2.194-.083 3.372-.155v2.003c-1.156.07-2.261.12-3.313.151-.207.006-.414.01-.618.01-8.534 0-14.783-5.216-20.833-10.265l-.002-.002c-4.717-3.938-9.252-7.703-14.586-8.719 4.734 1.825 8.707 5.677 12.594 9.458l.042.041c5.622 5.471 11.424 11.116 19.623 10.832 2.143-.074 4.52-.233 7.093-.469v1.986c-2.612.248-4.968.411-7.025.482-.227.008-.453.012-.677.012-8.683 0-14.662-5.817-20.449-11.449l-.002-.002c-6.138-5.97-11.934-11.607-20.396-9.544a6.362 6.362 0 01-.264.06c6.645.94 11.198 6.85 15.624 12.615l.018.024c5.046 6.575 10.262 13.37 18.631 12.993 4.052-.18 8.987-.683 14.54-1.438v2.016c-5.51.744-10.413 1.24-14.45 1.42-.262.012-.521.018-.777.018-8.945 0-14.331-7.017-19.546-13.811l-.003-.004-.006-.007c-5.346-6.966-10.397-13.547-18.803-11.626-.132.03-.261.057-.391.084l-.311.066c6.794 1.085 10.839 8.053 14.767 14.848 4.641 8.027 9.03 15.614 17.534 15.145 5.726-.312 13.322-1.305 21.986-2.76v2.023c-8.612 1.44-16.166 2.423-21.877 2.734-.291.016-.58.024-.862.024-9.167 0-13.914-8.21-18.51-16.16l-.003-.005c-3.706-6.412-7.25-12.526-12.858-13.763 5.122 2.473 8.33 8.832 11.453 15.061 4.311 8.593 8.385 16.71 16.95 16.2 6.486-.386 15.461-1.675 25.707-3.53v2.028c-10.185 1.837-19.111 3.112-25.587 3.498-.305.018-.607.028-.902.028-9.266.001-13.681-8.802-17.955-17.325l-.001-.003-.007-.012c-3.481-6.943-6.805-13.57-12.502-14.813 5.221 2.575 8.235 9.477 11.168 16.232 3.976 9.158 7.731 17.803 16.357 17.251 7.205-.465 17.596-2.081 29.429-4.364v2.035c-11.765 2.261-22.099 3.86-29.3 4.325a14.29 14.29 0 01-.939.031c-9.357 0-13.434-9.39-17.382-18.48v-.002c-3.236-7.452-6.334-14.556-12.065-15.862 5.271 2.704 8.063 10.121 10.779 17.372l.042.114zm-85.541-10.165a58.657 58.657 0 012.739-.415c4.4-.548 8.533-1.017 12.453-1.437-3.127.273-6.375.582-9.789.953-2.012.221-3.792.54-5.403.9zm20.806-4.32c-4.073.225-8.35.52-12.983.95a43.406 43.406 0 00-5.73.921 51.813 51.813 0 013.094-.438 494.47 494.47 0 0115.619-1.434zm5.224-2.265c-4.911.104-10.092.31-15.791.743a38.9 38.9 0 00-5.905.912 46.087 46.087 0 013.305-.433c6.728-.622 12.731-.974 18.391-1.222zm-3.703-11.62h-.235c-2.341 0-4.335.317-6.08.772a28.976 28.976 0 013.885-.298c10.241-.069 18.981.981 27.421 2.011.905.11 1.799.22 2.689.326l-.39-.06-.388-.059-.01-.001c-8.314-1.277-16.911-2.597-26.892-2.69zm-64.55-31.237C48.6 20.107 34.27 9.46 26.29.733a2.244 2.244 0 01-.083.002c9.365 9.76 25.058 22.401 38.058 32.872l.08.065c5.089 4.1 9.486 7.641 12.938 10.556 4.686 3.96 8.696 4.913 12.232 5.754 4.874 1.16 9.083 2.161 12.502 10.203 1.388 3.262 2.577 4.994 3.744 5.451.701.275 1.542.12 2.573-.259a3.898 3.898 0 01-.677-.19c-1.704-.655-3.113-2.592-4.708-6.477-2.942-7.158-6.185-7.952-10.673-9.05-3.433-.84-7.704-1.887-12.698-6.087-4.691-3.944-11.256-8.82-18.207-13.982zm97.895 28.533c-8.129-2.019-16.534-4.106-26.095-4.718-2.483-.159-4.567.13-6.353.632 1.228-.155 2.562-.222 4.028-.155 9.866.449 18.418 2.301 26.688 4.092l.014.003c2.655.575 5.278 1.14 7.894 1.646a444.507 444.507 0 01-6.176-1.5zm-68.92-21.098c-6.198-5.129-14.641-9.493-23.581-14.113-2.88-1.488-5.781-2.989-8.626-4.529a942.257 942.257 0 006.96 4.182c8.713 5.198 16.942 10.108 22.94 15.11 4.528 3.777 8.07 4.699 11.196 5.513l.006.001c4.462 1.161 7.985 2.078 11.128 10.295 1.204 3.147 2.266 4.852 3.249 5.213.551.204 1.244.014 2.105-.387-.023-.007-.046-.012-.069-.016-.028-.006-.056-.012-.084-.022-1.603-.574-2.847-2.408-4.293-6.33-2.69-7.301-5.32-8.008-9.3-9.076h-.002c-3.037-.816-6.815-1.83-11.628-5.84zm71.064 19.28c-8.064-2.259-16.403-4.595-25.821-5.373-2.502-.208-4.592.076-6.377.594a21.799 21.799 0 014.086-.117c9.74.623 18.236 2.733 26.45 4.773 3.145.781 6.247 1.55 9.344 2.211-2.548-.652-5.101-1.365-7.682-2.088zM69.811 21.884l-.008-.004a654.364 654.364 0 01-4.285-1.864l2.165 1.12.012.007c8.636 4.464 17.565 9.079 23.93 14.345 4.477 3.731 7.872 4.642 10.869 5.446h.001c4.252 1.142 7.611 2.044 10.659 10.317 1.152 3.126 2.163 4.807 3.09 5.14.503.18 1.149-.019 1.955-.424-1.556-.55-2.758-2.373-4.144-6.28-2.61-7.36-4.958-8.013-8.848-9.094-2.905-.807-6.52-1.812-11.267-5.747-6.443-5.316-15.434-9.203-24.129-12.962zm70.608 24.101c-2.506-.303-4.579-.04-6.337.5a19.188 19.188 0 014.124-.013c9.477.963 17.845 3.573 25.938 6.098 3.996 1.246 7.925 2.47 11.867 3.448-3.43-1.01-6.853-2.184-10.327-3.379l-.018-.006c-7.926-2.725-16.12-5.543-25.247-6.648zm23.123 8.492c-7.996-2.494-16.264-5.073-25.539-6.016-2.495-.253-4.572.02-6.342.544a20.477 20.477 0 014.092-.066c9.602.794 18.029 3.154 26.178 5.436l.019.005c3.56.997 7.067 1.974 10.576 2.79-2.98-.825-5.959-1.749-8.978-2.69l-.006-.003zm-90.373-33.35l-.014-.006-.36-.123c8.124 3.527 16.306 7.263 22.419 12.307 4.42 3.663 7.665 4.565 10.53 5.361 4.044 1.124 7.239 2.012 10.196 10.352 1.101 3.106 2.061 4.764 2.932 5.068.459.158 1.079-.06 1.832-.468-1.453-.583-2.587-2.39-3.874-6.185-2.542-7.417-4.622-8.018-8.397-9.108l-.009-.003c-2.771-.801-6.221-1.8-10.894-5.653-6.623-5.444-15.64-8.544-24.36-11.543zm45.555 25.661c1.032 3.048 1.963 4.73 2.768 5.003.417.145 1.012-.097 1.744-.529-1.355-.615-2.427-2.41-3.629-6.085-2.45-7.49-4.398-8.073-7.931-9.131h-.002c-2.648-.793-5.944-1.78-10.552-5.558-6.026-4.94-13.81-7.262-21.575-9.25 6.993 2.523 13.83 5.43 19.253 9.888 4.361 3.594 7.591 4.527 10.187 5.277h.002c3.978 1.15 6.853 1.981 9.735 10.385z",fill:"url(#illustration-04)"}))),a.createElement("div",{className:"absolute left-2 -top-2 pointer-events-none z-0 opacity-20 overflow-hidden block md:hidden"},a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",height:"120",width:"120",viewBox:"0 0 48 48"},a.createElement("title",null,"logo github"),a.createElement("g",{className:"stroke-current",className:"nc-icon-wrapper"},a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",className:"stroke-current text-black",d:"M24,0.6c-13.3,0-24,10.7-24,24c0,10.6,6.9,19.6,16.4,22.8 c1.2,0.2,1.6-0.5,1.6-1.2c0-0.6,0-2.1,0-4.1c-6.7,1.5-8.1-3.2-8.1-3.2c-1.1-2.8-2.7-3.5-2.7-3.5c-2.2-1.5,0.2-1.5,0.2-1.5 c2.4,0.2,3.7,2.5,3.7,2.5c2.1,3.7,5.6,2.6,7,2c0.2-1.6,0.8-2.6,1.5-3.2c-5.3-0.6-10.9-2.7-10.9-11.9c0-2.6,0.9-4.8,2.5-6.4 c-0.2-0.6-1.1-3,0.2-6.4c0,0,2-0.6,6.6,2.5c1.9-0.5,4-0.8,6-0.8c2,0,4.1,0.3,6,0.8c4.6-3.1,6.6-2.5,6.6-2.5c1.3,3.3,0.5,5.7,0.2,6.4 c1.5,1.7,2.5,3.8,2.5,6.4c0,9.2-5.6,11.2-11,11.8c0.9,0.7,1.6,2.2,1.6,4.4c0,3.2,0,5.8,0,6.6c0,0.6,0.4,1.4,1.7,1.2 C41.1,44.2,48,35.2,48,24.6C48,11.3,37.3,0.6,24,0.6z"})))),a.createElement("div",{className:"relative flex flex-row justify-between items-center flex-nowrap p-2"},a.createElement("div",{className:"flex-row items-center hidden md:flex"},a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",height:"56",width:"56",viewBox:"0 0 48 48"},a.createElement("title",null,"logo github"),a.createElement("g",{className:"stroke-current",className:"nc-icon-wrapper"},a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",className:"stroke-current text-black",d:"M24,0.6c-13.3,0-24,10.7-24,24c0,10.6,6.9,19.6,16.4,22.8 c1.2,0.2,1.6-0.5,1.6-1.2c0-0.6,0-2.1,0-4.1c-6.7,1.5-8.1-3.2-8.1-3.2c-1.1-2.8-2.7-3.5-2.7-3.5c-2.2-1.5,0.2-1.5,0.2-1.5 c2.4,0.2,3.7,2.5,3.7,2.5c2.1,3.7,5.6,2.6,7,2c0.2-1.6,0.8-2.6,1.5-3.2c-5.3-0.6-10.9-2.7-10.9-11.9c0-2.6,0.9-4.8,2.5-6.4 c-0.2-0.6-1.1-3,0.2-6.4c0,0,2-0.6,6.6,2.5c1.9-0.5,4-0.8,6-0.8c2,0,4.1,0.3,6,0.8c4.6-3.1,6.6-2.5,6.6-2.5c1.3,3.3,0.5,5.7,0.2,6.4 c1.5,1.7,2.5,3.8,2.5,6.4c0,9.2-5.6,11.2-11,11.8c0.9,0.7,1.6,2.2,1.6,4.4c0,3.2,0,5.8,0,6.6c0,0.6,0.4,1.4,1.7,1.2 C41.1,44.2,48,35.2,48,24.6C48,11.3,37.3,0.6,24,0.6z"})))),a.createElement("p",{className:"text-3xl font-bold text-black xl:mb-0 text-center xl:text-left xl:mr-2 xl:mb-0 mb-2"},a.createElement("a",{className:"text-black hover:text-gray-600",href:`https://github.com/${c}`},c)," / ",a.createElement("a",{className:"text-black hover:text-gray-600",href:`https://github.com/${c}/${t}`},t))))))},youtube:function(e){let{videoUrl:c,videoKey:t}=e;const l=t?`https://www.youtube.com/embed/${t}`:c;return a.createElement("section",null,a.createElement("iframe",{className:"w-full aspect-video",src:l,frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}))}}},1748:(e,c,t)=>{var l={"./locale":9234,"./locale.js":9234};function a(e){var c=r(e);return t(c)}function r(e){if(!t.o(l,e)){var c=new Error("Cannot find module '"+e+"'");throw c.code="MODULE_NOT_FOUND",c}return l[e]}a.keys=function(){return Object.keys(l)},a.resolve=r,e.exports=a,a.id=1748}}]); \ No newline at end of file diff --git a/assets/js/1b8c0795.a1b1fb2a.js b/assets/js/1b8c0795.a1b1fb2a.js new file mode 100644 index 00000000..a2e012bd --- /dev/null +++ b/assets/js/1b8c0795.a1b1fb2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[710],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(r),g=a,h=m["".concat(l,".").concat(g)]||m[g]||d[g]||i;return r?n.createElement(h,o(o({ref:t},c),{},{components:r})):n.createElement(h,o({ref:t},c))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const i={sidebar_position:27},o="Crash Reporting",s={unversionedId:"crashreporting/index",id:"crashreporting/index",title:"Crash Reporting",description:'Crash reporting is primarily handled with CrashKiOS. Kermit provides LogWriter instances to write breadcrumb/log statements to the crash reporting tools, and sending soft "handled" exceptions when Throwable instances are logged, based on configuration.',source:"@site/docs/crashreporting/index.md",sourceDirName:"crashreporting",slug:"/crashreporting/",permalink:"/docs/crashreporting/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/crashreporting/index.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:27,frontMatter:{sidebar_position:27},sidebar:"tutorialSidebar",previous:{title:"iOS Logging",permalink:"/docs/IOS_LOGGING"},next:{title:"Crashlytics",permalink:"/docs/crashreporting/CRASHLYTICS"}},l={},p=[{value:"Crashlytics",id:"crashlytics",level:2},{value:"Bugsnag",id:"bugsnag",level:2},{value:"Configuring crash log writers",id:"configuring-crash-log-writers",level:2},{value:"minSeverity: Severity",id:"minseverity-severity",level:3},{value:"minCrashSeverity: Severity?",id:"mincrashseverity-severity",level:3},{value:"messageStringFormatter: MessageStringFormatter",id:"messagestringformatter-messagestringformatter",level:3}],c={toc:p};function d(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"crash-reporting"},"Crash Reporting"),(0,a.kt)("p",null,"Crash reporting is primarily handled with ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/"},"CrashKiOS"),". Kermit provides ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter"),' instances to write breadcrumb/log statements to the crash reporting tools, and sending soft "handled" exceptions when ',(0,a.kt)("inlineCode",{parentName:"p"},"Throwable")," instances are logged, based on configuration."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Earlier versions of Kermit implemented crash reporting directly, but logging and crash reporting are really different domains. Crash reporting support was moved back into CrashKiOS, and Kermit simply provides a logging interface into those tools.")),(0,a.kt)("p",null,"Kermit and CrashKiOS currently support ",(0,a.kt)("a",{parentName:"p",href:"https://firebase.google.com/"},"Firebase Crashlytics")," and ",(0,a.kt)("a",{parentName:"p",href:"https://www.bugsnag.com/"},"Bugsnag"),"."),(0,a.kt)("h2",{id:"crashlytics"},"Crashlytics"),(0,a.kt)("p",null,"See ",(0,a.kt)("a",{parentName:"p",href:"CRASHLYTICS"},"Crashlytics Setup")),(0,a.kt)("h2",{id:"bugsnag"},"Bugsnag"),(0,a.kt)("p",null,"See ",(0,a.kt)("a",{parentName:"p",href:"BUGSNAG"},"Bugsnag Setup")),(0,a.kt)("h2",{id:"configuring-crash-log-writers"},"Configuring crash log writers"),(0,a.kt)("p",null,"Both crash ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," implementations take 3 parameters:"),(0,a.kt)("h3",{id:"minseverity-severity"},(0,a.kt)("inlineCode",{parentName:"h3"},"minSeverity: Severity")),(0,a.kt)("p",null,"This is the minimum severity that will be logged to the crash reporter's breadcrumb cache. The default severity is ",(0,a.kt)("inlineCode",{parentName:"p"},"Info"),". That means ",(0,a.kt)("inlineCode",{parentName:"p"},"Debug")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Verbose")," statements will be ignored."),(0,a.kt)("h3",{id:"mincrashseverity-severity"},(0,a.kt)("inlineCode",{parentName:"h3"},"minCrashSeverity: Severity?")),(0,a.kt)("p",null,"All log statements can take a ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable"),". If you send a ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable")," to a crash ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter"),", if the log statement itself is equal to or above ",(0,a.kt)("inlineCode",{parentName:"p"},"minCrashSeverity"),", the ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable")," will be sent as a soft/handled exception."),(0,a.kt)("p",null,"The default value is ",(0,a.kt)("inlineCode",{parentName:"p"},"Warn"),", so all log statements with a ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable"),", with log severity of ",(0,a.kt)("inlineCode",{parentName:"p"},"Warn")," or higher, will create an exception report."),(0,a.kt)("p",null,"To disable sending exception reports, pass ",(0,a.kt)("inlineCode",{parentName:"p"},"null"),"."),(0,a.kt)("h3",{id:"messagestringformatter-messagestringformatter"},(0,a.kt)("inlineCode",{parentName:"h3"},"messageStringFormatter: MessageStringFormatter")),(0,a.kt)("p",null,"See ",(0,a.kt)("a",{parentName:"p",href:"/docs/configuration/MESSAGE_FORMATTING"},"Message Formatting")," for details of how to format log message strings. ",(0,a.kt)("inlineCode",{parentName:"p"},"DefaultFormatter")," is the default value."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1b8c0795.b66b2d70.js b/assets/js/1b8c0795.b66b2d70.js deleted file mode 100644 index 59e45af6..00000000 --- a/assets/js/1b8c0795.b66b2d70.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[710],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(r),g=a,h=m["".concat(l,".").concat(g)]||m[g]||d[g]||i;return r?n.createElement(h,o(o({ref:t},c),{},{components:r})):n.createElement(h,o({ref:t},c))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const i={sidebar_position:27},o="Crash Reporting",s={unversionedId:"crashreporting/index",id:"crashreporting/index",title:"Crash Reporting",description:'Crash reporting is primarily handled with CrashKiOS. Kermit provides LogWriter instances to write breadcrumb/log statements to the crash reporting tools, and sending soft "handled" exceptions when Throwable instances are logged, based on configuration.',source:"@site/docs/crashreporting/index.md",sourceDirName:"crashreporting",slug:"/crashreporting/",permalink:"/docs/crashreporting/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/crashreporting/index.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:27,frontMatter:{sidebar_position:27},sidebar:"tutorialSidebar",previous:{title:"iOS Logging",permalink:"/docs/IOS_LOGGING"},next:{title:"Crashlytics",permalink:"/docs/crashreporting/CRASHLYTICS"}},l={},p=[{value:"Crashlytics",id:"crashlytics",level:2},{value:"Bugsnag",id:"bugsnag",level:2},{value:"Configuring crash log writers",id:"configuring-crash-log-writers",level:2},{value:"minSeverity: Severity",id:"minseverity-severity",level:3},{value:"minCrashSeverity: Severity?",id:"mincrashseverity-severity",level:3},{value:"messageStringFormatter: MessageStringFormatter",id:"messagestringformatter-messagestringformatter",level:3}],c={toc:p};function d(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"crash-reporting"},"Crash Reporting"),(0,a.kt)("p",null,"Crash reporting is primarily handled with ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/"},"CrashKiOS"),". Kermit provides ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter"),' instances to write breadcrumb/log statements to the crash reporting tools, and sending soft "handled" exceptions when ',(0,a.kt)("inlineCode",{parentName:"p"},"Throwable")," instances are logged, based on configuration."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Earlier versions of Kermit implemented crash reporting directly, but logging and crash reporting are really different domains. Crash reporting support was moved back into CrashKiOS, and Kermit simply provides a logging interface into those tools.")),(0,a.kt)("p",null,"Kermit and CrashKiOS currently support ",(0,a.kt)("a",{parentName:"p",href:"https://firebase.google.com/"},"Firebase Crashlytics")," and ",(0,a.kt)("a",{parentName:"p",href:"https://www.bugsnag.com/"},"Bugsnag"),"."),(0,a.kt)("h2",{id:"crashlytics"},"Crashlytics"),(0,a.kt)("p",null,"See ",(0,a.kt)("a",{parentName:"p",href:"CRASHLYTICS"},"Crashlytics Setup")),(0,a.kt)("h2",{id:"bugsnag"},"Bugsnag"),(0,a.kt)("p",null,"See ",(0,a.kt)("a",{parentName:"p",href:"BUGSNAG"},"Bugsnag Setup")),(0,a.kt)("h2",{id:"configuring-crash-log-writers"},"Configuring crash log writers"),(0,a.kt)("p",null,"Both crash ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," implementations take 3 parameters:"),(0,a.kt)("h3",{id:"minseverity-severity"},(0,a.kt)("inlineCode",{parentName:"h3"},"minSeverity: Severity")),(0,a.kt)("p",null,"This is the minimum severity that will be logged to the crash reporter's breadcrumb cache. The default severity is ",(0,a.kt)("inlineCode",{parentName:"p"},"Info"),". That means ",(0,a.kt)("inlineCode",{parentName:"p"},"Debug")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Verbose")," statements will be ignored."),(0,a.kt)("h3",{id:"mincrashseverity-severity"},(0,a.kt)("inlineCode",{parentName:"h3"},"minCrashSeverity: Severity?")),(0,a.kt)("p",null,"All log statements can take a ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable"),". If you send a ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable")," to a crash ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter"),", if the log statement itself is equal to or above ",(0,a.kt)("inlineCode",{parentName:"p"},"minCrashSeverity"),", the ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable")," will be sent as a soft/handled exception."),(0,a.kt)("p",null,"The default value is ",(0,a.kt)("inlineCode",{parentName:"p"},"Warn"),", so all log statements with a ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable"),", with log severity of ",(0,a.kt)("inlineCode",{parentName:"p"},"Warn")," or higher, will create an exception report."),(0,a.kt)("p",null,"To disable sending exception reports, pass ",(0,a.kt)("inlineCode",{parentName:"p"},"null"),"."),(0,a.kt)("h3",{id:"messagestringformatter-messagestringformatter"},(0,a.kt)("inlineCode",{parentName:"h3"},"messageStringFormatter: MessageStringFormatter")),(0,a.kt)("p",null,"See ",(0,a.kt)("a",{parentName:"p",href:"/docs/configuration/MESSAGE_FORMATTING"},"Message Formatting")," for details of how to format log message strings. ",(0,a.kt)("inlineCode",{parentName:"p"},"DefaultFormatter")," is the default value."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2c56297f.73b8ef3c.js b/assets/js/2c56297f.73b8ef3c.js new file mode 100644 index 00000000..ec08b800 --- /dev/null +++ b/assets/js/2c56297f.73b8ef3c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[330],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=c(r),d=o,f=m["".concat(s,".").concat(d)]||m[d]||p[d]||a;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const a={},i="Custom Logger API",l={unversionedId:"details/CUSTOM_API",id:"details/CUSTOM_API",title:"Custom Logger API",description:"The main module most users will include is kermit. However, much of the configuration and other underlying functionality has been moved to kermit-core. The main kermit module is a relatively thin API layer that sits on top of kermit-core.",source:"@site/docs/details/CUSTOM_API.md",sourceDirName:"details",slug:"/details/CUSTOM_API",permalink:"/docs/details/CUSTOM_API",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/details/CUSTOM_API.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"LogWriter",permalink:"/docs/details/LOG_WRITER"}},s={},c=[],u={toc:c};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"custom-logger-api"},"Custom Logger API"),(0,o.kt)("p",null,"The main module most users will include is ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit"),". However, much of the configuration and other underlying functionality has been moved to ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core"),". The main ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit")," module is a relatively thin API layer that sits on top of ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core"),"."),(0,o.kt)("p",null,"Over the past few years, we've had feedback about the API design choices made in Kermit. Some of that feedback makes sense and has been incorporated. Other feedback is really just personal preference, and would conflict with the existing design."),(0,o.kt)("p",null,"Rather than trying to make everybody happy, we've structured Kermit's modules so you can create your own API interface on top of the underlying ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core")," module. That will allow you to use compatible extensions like Crashlytics and Bugsnag, but interface with the underlying Kermit system with whatever API you prefer."),(0,o.kt)("p",null,"For example, if you wanted a very simple logger with only two methods, you would make ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core")," a dependency rather than ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit"),", and write your own implementation:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'object MyLogger : BaseLogger(loggerConfigInit(platformLogWriter())) {\n fun info(message: String){\n log(Severity.Info, "MyLogger", null, message)\n }\n \n fun error(message: String, throwable: Throwable){\n log(Severity.Error, "MyLogger", throwable, message)\n }\n}\n')),(0,o.kt)("p",null,"For a more complex example, see the implementation of ",(0,o.kt)("inlineCode",{parentName:"p"},"co.touchlab.kermit.Logger")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2c56297f.9df73147.js b/assets/js/2c56297f.9df73147.js deleted file mode 100644 index bdad258e..00000000 --- a/assets/js/2c56297f.9df73147.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[330],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=c(r),d=o,f=p["".concat(s,".").concat(d)]||p[d]||m[d]||a;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=p;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const a={},i="Custom Logger API",l={unversionedId:"details/CUSTOM_API",id:"details/CUSTOM_API",title:"Custom Logger API",description:"The main module most users will include is kermit. However, much of the configuration and other underlying functionality has been moved to kermit-core. The main kermit module is a relatively thin API layer that sits on top of kermit-core.",source:"@site/docs/details/CUSTOM_API.md",sourceDirName:"details",slug:"/details/CUSTOM_API",permalink:"/docs/details/CUSTOM_API",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/details/CUSTOM_API.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"LogWriter",permalink:"/docs/details/LOG_WRITER"}},s={},c=[],u={toc:c};function m(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"custom-logger-api"},"Custom Logger API"),(0,o.kt)("p",null,"The main module most users will include is ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit"),". However, much of the configuration and other underlying functionality has been moved to ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core"),". The main ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit")," module is a relatively thin API layer that sits on top of ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core"),"."),(0,o.kt)("p",null,"Over the past few years, we've had feedback about the API design choices made in Kermit. Some of that feedback makes sense and has been incorporated. Other feedback is really just personal preference, and would conflict with the existing design."),(0,o.kt)("p",null,"Rather than trying to make everybody happy, we've structured Kermit's modules so you can create your own API interface on top of the underlying ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core")," module. That will allow you to use compatible extensions like Crashlytics and Bugsnag, but interface with the underlying Kermit system with whatever API you prefer."),(0,o.kt)("p",null,"For example, if you wanted a very simple logger with only two methods, you would make ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-core")," a dependency rather than ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit"),", and write your own implementation:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'object MyLogger : BaseLogger(loggerConfigInit(platformLogWriter())) {\n fun info(message: String){\n log(Severity.Info, "MyLogger", null, message)\n }\n \n fun error(message: String, throwable: Throwable){\n log(Severity.Error, "MyLogger", throwable, message)\n }\n}\n')),(0,o.kt)("p",null,"For a more complex example, see the implementation of ",(0,o.kt)("inlineCode",{parentName:"p"},"co.touchlab.kermit.Logger")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/583db3ef.6ae4a4ec.js b/assets/js/583db3ef.6ae4a4ec.js deleted file mode 100644 index 03ebc6a1..00000000 --- a/assets/js/583db3ef.6ae4a4ec.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[363],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},p),{},{components:n})):r.createElement(m,a({ref:t},p))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:30},a="Extensions",s={unversionedId:"extensions/index",id:"extensions/index",title:"Extensions",description:"Crashlytics",source:"@site/docs/extensions/index.md",sourceDirName:"extensions",slug:"/extensions/",permalink:"/docs/extensions/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/extensions/index.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:30,frontMatter:{sidebar_position:30},sidebar:"tutorialSidebar",previous:{title:"Bugsnag",permalink:"/docs/crashreporting/BUGSNAG"},next:{title:"Koin Integration",permalink:"/docs/extensions/KOIN"}},c={},l=[{value:"Crashlytics",id:"crashlytics",level:2},{value:"Bugsnag",id:"bugsnag",level:2},{value:"Koin",id:"koin",level:2}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"extensions"},"Extensions"),(0,o.kt)("h2",{id:"crashlytics"},(0,o.kt)("a",{parentName:"h2",href:"../crashreporting/CRASHLYTICS"},"Crashlytics")),(0,o.kt)("p",null,"Crashlytics log statement writing."),(0,o.kt)("h2",{id:"bugsnag"},(0,o.kt)("a",{parentName:"h2",href:"../crashreporting/BUGSNAG"},"Bugsnag")),(0,o.kt)("p",null,"Bugsnag breadcrumb writing."),(0,o.kt)("h2",{id:"koin"},(0,o.kt)("a",{parentName:"h2",href:"KOIN"},"Koin")),(0,o.kt)("p",null,"Integration with Koin, for easy logger injection."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/583db3ef.ef549bb5.js b/assets/js/583db3ef.ef549bb5.js new file mode 100644 index 00000000..3cdc9e9e --- /dev/null +++ b/assets/js/583db3ef.ef549bb5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[363],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=i,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(m,a(a({ref:t},p),{},{components:n})):r.createElement(m,a({ref:t},p))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:30},a="Extensions",s={unversionedId:"extensions/index",id:"extensions/index",title:"Extensions",description:"Crashlytics",source:"@site/docs/extensions/index.md",sourceDirName:"extensions",slug:"/extensions/",permalink:"/docs/extensions/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/extensions/index.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:30,frontMatter:{sidebar_position:30},sidebar:"tutorialSidebar",previous:{title:"Bugsnag",permalink:"/docs/crashreporting/BUGSNAG"},next:{title:"Koin Integration",permalink:"/docs/extensions/KOIN"}},c={},l=[{value:"Crashlytics",id:"crashlytics",level:2},{value:"Bugsnag",id:"bugsnag",level:2},{value:"Koin",id:"koin",level:2}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"extensions"},"Extensions"),(0,i.kt)("h2",{id:"crashlytics"},(0,i.kt)("a",{parentName:"h2",href:"../crashreporting/CRASHLYTICS"},"Crashlytics")),(0,i.kt)("p",null,"Crashlytics log statement writing."),(0,i.kt)("h2",{id:"bugsnag"},(0,i.kt)("a",{parentName:"h2",href:"../crashreporting/BUGSNAG"},"Bugsnag")),(0,i.kt)("p",null,"Bugsnag breadcrumb writing."),(0,i.kt)("h2",{id:"koin"},(0,i.kt)("a",{parentName:"h2",href:"KOIN"},"Koin")),(0,i.kt)("p",null,"Integration with Koin, for easy logger injection."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/58e6863e.6d137e00.js b/assets/js/58e6863e.b6937826.js similarity index 51% rename from assets/js/58e6863e.6d137e00.js rename to assets/js/58e6863e.b6937826.js index 9a19100f..6a0ed306 100644 --- a/assets/js/58e6863e.6d137e00.js +++ b/assets/js/58e6863e.b6937826.js @@ -1 +1 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[162],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(r),d=i,g=u["".concat(s,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(g,a(a({ref:t},p),{},{components:r})):n.createElement(g,a({ref:t},p))}));function d(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,a[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:26},a="iOS Logging",l={unversionedId:"IOS_LOGGING",id:"IOS_LOGGING",title:"iOS Logging",description:"There are three LogWriter implementations for iOS.",source:"@site/docs/IOS_LOGGING.md",sourceDirName:".",slug:"/IOS_LOGGING",permalink:"/docs/IOS_LOGGING",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/IOS_LOGGING.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:26,frontMatter:{sidebar_position:26},sidebar:"tutorialSidebar",previous:{title:"Testing",permalink:"/docs/TESTING"},next:{title:"Crash Reporting",permalink:"/docs/crashreporting/"}},s={},c=[{value:"XcodeSeverityWriter",id:"xcodeseveritywriter",level:2},{value:"OSLogWriter",id:"oslogwriter",level:2},{value:"NSLogWriter",id:"nslogwriter",level:2}],p={toc:c};function m(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"ios-logging"},"iOS Logging"),(0,i.kt)("p",null,"There are three ",(0,i.kt)("inlineCode",{parentName:"p"},"LogWriter")," implementations for iOS."),(0,i.kt)("h2",{id:"xcodeseveritywriter"},"XcodeSeverityWriter"),(0,i.kt)("p",null,"This is the default ",(0,i.kt)("inlineCode",{parentName:"p"},"LogWriter"),". It is designed for local development. Each severity is represented with an emoji. ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable")," instances sent to this writer will be written with ",(0,i.kt)("inlineCode",{parentName:"p"},"println")," rather than oslog because oslog trims long strings."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"2023-03-05 08:48:03.864138-0500 KermitSampleIOS[58575:7607179] \ud83d\udfe2 Try a log\n2023-03-05 08:48:04.622452-0500 KermitSampleIOS[58575:7607442] [Bugsnag] [INFO] Sent session 7D3188F7-2B37-4189-9F92-63BC7172D01B\n2023-03-05 08:48:09.999884-0500 KermitSampleIOS[58575:7607179] \ud83d\udfe2 Common click count: 1\n2023-03-05 08:48:11.333941-0500 KermitSampleIOS[58575:7607179] \ud83d\udd35 Common click count: 2\n2023-03-05 08:48:13.104265-0500 KermitSampleIOS[58575:7607179] \ud83d\udfe1 Common click count: 3\n2023-03-05 08:48:13.568351-0500 KermitSampleIOS[58575:7607179] \ud83d\udd34 Common click count: 4\n")),(0,i.kt)("h2",{id:"oslogwriter"},"OSLogWriter"),(0,i.kt)("p",null,"This is the parent class of ",(0,i.kt)("inlineCode",{parentName:"p"},"XcodeSeverityWriter"),". There is no emoji added for severity, and ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable")," is sent as a string to oslog. This may trim exceptions. You can implement a custom version that writes each line of a stack trace to oslog, or whatever else you'd like to do. Override ",(0,i.kt)("inlineCode",{parentName:"p"},"logThrowable"),"."),(0,i.kt)("h2",{id:"nslogwriter"},"NSLogWriter"),(0,i.kt)("p",null,"Legacy implementation using ",(0,i.kt)("inlineCode",{parentName:"p"},"NSLog"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[162],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(r),d=i,g=u["".concat(s,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(g,a(a({ref:t},p),{},{components:r})):n.createElement(g,a({ref:t},p))}));function d(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,a[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:26},a="iOS Logging",l={unversionedId:"IOS_LOGGING",id:"IOS_LOGGING",title:"iOS Logging",description:"There are three LogWriter implementations for iOS.",source:"@site/docs/IOS_LOGGING.md",sourceDirName:".",slug:"/IOS_LOGGING",permalink:"/docs/IOS_LOGGING",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/IOS_LOGGING.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:26,frontMatter:{sidebar_position:26},sidebar:"tutorialSidebar",previous:{title:"Testing",permalink:"/docs/TESTING"},next:{title:"Crash Reporting",permalink:"/docs/crashreporting/"}},s={},c=[{value:"XcodeSeverityWriter",id:"xcodeseveritywriter",level:2},{value:"OSLogWriter",id:"oslogwriter",level:2},{value:"NSLogWriter",id:"nslogwriter",level:2}],p={toc:c};function m(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"ios-logging"},"iOS Logging"),(0,i.kt)("p",null,"There are three ",(0,i.kt)("inlineCode",{parentName:"p"},"LogWriter")," implementations for iOS."),(0,i.kt)("h2",{id:"xcodeseveritywriter"},"XcodeSeverityWriter"),(0,i.kt)("p",null,"This is the default ",(0,i.kt)("inlineCode",{parentName:"p"},"LogWriter"),". It is designed for local development. Each severity is represented with an emoji. ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable")," instances sent to this writer will be written with ",(0,i.kt)("inlineCode",{parentName:"p"},"println")," rather than oslog because oslog trims long strings."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"2023-03-05 08:48:03.864138-0500 KermitSampleIOS[58575:7607179] \ud83d\udfe2 Try a log\n2023-03-05 08:48:04.622452-0500 KermitSampleIOS[58575:7607442] [Bugsnag] [INFO] Sent session 7D3188F7-2B37-4189-9F92-63BC7172D01B\n2023-03-05 08:48:09.999884-0500 KermitSampleIOS[58575:7607179] \ud83d\udfe2 Common click count: 1\n2023-03-05 08:48:11.333941-0500 KermitSampleIOS[58575:7607179] \ud83d\udd35 Common click count: 2\n2023-03-05 08:48:13.104265-0500 KermitSampleIOS[58575:7607179] \ud83d\udfe1 Common click count: 3\n2023-03-05 08:48:13.568351-0500 KermitSampleIOS[58575:7607179] \ud83d\udd34 Common click count: 4\n")),(0,i.kt)("h2",{id:"oslogwriter"},"OSLogWriter"),(0,i.kt)("p",null,"This is the parent class of ",(0,i.kt)("inlineCode",{parentName:"p"},"XcodeSeverityWriter"),". There is no emoji added for severity, and ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable")," is sent as a string to oslog. This may trim exceptions. You can implement a custom version that writes each line of a stack trace to oslog, or whatever else you'd like to do. Override ",(0,i.kt)("inlineCode",{parentName:"p"},"logThrowable"),"."),(0,i.kt)("h2",{id:"nslogwriter"},"NSLogWriter"),(0,i.kt)("p",null,"Legacy implementation using ",(0,i.kt)("inlineCode",{parentName:"p"},"NSLog"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/599169ee.850e57f5.js b/assets/js/599169ee.dc251485.js similarity index 60% rename from assets/js/599169ee.850e57f5.js rename to assets/js/599169ee.dc251485.js index d704d263..407de22f 100644 --- a/assets/js/599169ee.850e57f5.js +++ b/assets/js/599169ee.dc251485.js @@ -1 +1 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[656],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(r),h=a,m=d["".concat(c,".").concat(h)]||d[h]||u[h]||o;return r?n.createElement(m,i(i({ref:t},p),{},{components:r})):n.createElement(m,i({ref:t},p))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:10},i="Crashlytics",s={unversionedId:"crashreporting/CRASHLYTICS",id:"crashreporting/CRASHLYTICS",title:"Crashlytics",description:"Setup",source:"@site/docs/crashreporting/CRASHLYTICS.md",sourceDirName:"crashreporting",slug:"/crashreporting/CRASHLYTICS",permalink:"/docs/crashreporting/CRASHLYTICS",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/crashreporting/CRASHLYTICS.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Crash Reporting",permalink:"/docs/crashreporting/"},next:{title:"Bugsnag",permalink:"/docs/crashreporting/BUGSNAG"}},c={},l=[{value:"Setup",id:"setup",level:2},{value:"Add the dependency",id:"add-the-dependency",level:2},{value:"Add the log writer",id:"add-the-log-writer",level:2},{value:"Custom Values",id:"custom-values",level:2}],p={toc:l};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"crashlytics"},"Crashlytics"),(0,a.kt)("h2",{id:"setup"},"Setup"),(0,a.kt)("p",null,"You first need to configure Crashlytics and CrashKiOS initialization. See ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/crashlytics"},"the CrashKiOS Crashlytics Tutorial Doc"),"."),(0,a.kt)("h2",{id:"add-the-dependency"},"Add the dependency"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n implementation("co.touchlab:kermit-crashlytics:2.0.3")\n }\n}\n')),(0,a.kt)("h2",{id:"add-the-log-writer"},"Add the log writer"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(CrashlyticsLogWriter())\n")),(0,a.kt)("h2",{id:"custom-values"},"Custom Values"),(0,a.kt)("p",null,"You can add custom values to Crashlytics, but not through Kermit. ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/crashlytics#sending-extra-info-to-crashlytics"},"Call CrashKiOS directly"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'CrashlyticsKotlin.setCustomValue("someKey", "someValue")\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[656],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(r),h=a,m=d["".concat(c,".").concat(h)]||d[h]||u[h]||o;return r?n.createElement(m,i(i({ref:t},p),{},{components:r})):n.createElement(m,i({ref:t},p))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:10},i="Crashlytics",s={unversionedId:"crashreporting/CRASHLYTICS",id:"crashreporting/CRASHLYTICS",title:"Crashlytics",description:"Setup",source:"@site/docs/crashreporting/CRASHLYTICS.md",sourceDirName:"crashreporting",slug:"/crashreporting/CRASHLYTICS",permalink:"/docs/crashreporting/CRASHLYTICS",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/crashreporting/CRASHLYTICS.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Crash Reporting",permalink:"/docs/crashreporting/"},next:{title:"Bugsnag",permalink:"/docs/crashreporting/BUGSNAG"}},c={},l=[{value:"Setup",id:"setup",level:2},{value:"Add the dependency",id:"add-the-dependency",level:2},{value:"Add the log writer",id:"add-the-log-writer",level:2},{value:"Custom Values",id:"custom-values",level:2}],p={toc:l};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"crashlytics"},"Crashlytics"),(0,a.kt)("h2",{id:"setup"},"Setup"),(0,a.kt)("p",null,"You first need to configure Crashlytics and CrashKiOS initialization. See ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/crashlytics"},"the CrashKiOS Crashlytics Tutorial Doc"),"."),(0,a.kt)("h2",{id:"add-the-dependency"},"Add the dependency"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n implementation("co.touchlab:kermit-crashlytics:2.0.3")\n }\n}\n')),(0,a.kt)("h2",{id:"add-the-log-writer"},"Add the log writer"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(CrashlyticsLogWriter())\n")),(0,a.kt)("h2",{id:"custom-values"},"Custom Values"),(0,a.kt)("p",null,"You can add custom values to Crashlytics, but not through Kermit. ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/crashlytics#sending-extra-info-to-crashlytics"},"Call CrashKiOS directly"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'CrashlyticsKotlin.setCustomValue("someKey", "someValue")\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6505a119.916927fb.js b/assets/js/6505a119.220bd22b.js similarity index 56% rename from assets/js/6505a119.916927fb.js rename to assets/js/6505a119.220bd22b.js index 53c18b84..66f64eb6 100644 --- a/assets/js/6505a119.916927fb.js +++ b/assets/js/6505a119.220bd22b.js @@ -1 +1 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[787],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=s(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={},i="Non-Kotlin Environments",l={unversionedId:"configuration/NON_KOTLIN",id:"configuration/NON_KOTLIN",title:"Non-Kotlin Environments",description:"You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose.",source:"@site/docs/configuration/NON_KOTLIN.md",sourceDirName:"configuration",slug:"/configuration/NON_KOTLIN",permalink:"/docs/configuration/NON_KOTLIN",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/NON_KOTLIN.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Message Formatting",permalink:"/docs/configuration/MESSAGE_FORMATTING"},next:{title:"Testing",permalink:"/docs/TESTING"}},c={},s=[],p={toc:s};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"non-kotlin-environments"},"Non-Kotlin Environments"),(0,o.kt)("p",null,"You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose."),(0,o.kt)("p",null,"Earlier versions of Kermit were designed to be Swift-friendly, but that sacrificed the Kotlin-friendly API, and since the primary use-case is calling Kermit from Kotlin, that seemed like a bad compromise."),(0,o.kt)("p",null,"We've added a module called ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-simple")," which adds explicit call signatures to the API, to provide for the cases where default parameters make more sense in a Kotlin context."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'kotlin {\n sourceSets {\n val commonMain by getting {\n dependencies {\n // etc\n implementation("co.touchlab:kermit:2.0.3")\n }\n }\n\n val iosMain by getting {\n dependencies {\n // etc\n api("co.touchlab:kermit-simple:2.0.3")\n }\n }\n }\n\n cocoapods {\n framework {\n export("co.touchlab:kermit-simple:2.0.3")\n }\n }\n}\n')),(0,o.kt)("p",null," You will need to export ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-simple"),", as in the example above."),(0,o.kt)("p",null," From Swift, this will allow you to call methods without all of the parameters explicitly added."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-swift"},'let log = // Get a Logger instance\nlog.i(messageString: "Try a log")\nlog.w(messageString: "Throw", throwable: someException)\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[787],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=s(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={},i="Non-Kotlin Environments",l={unversionedId:"configuration/NON_KOTLIN",id:"configuration/NON_KOTLIN",title:"Non-Kotlin Environments",description:"You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose.",source:"@site/docs/configuration/NON_KOTLIN.md",sourceDirName:"configuration",slug:"/configuration/NON_KOTLIN",permalink:"/docs/configuration/NON_KOTLIN",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/NON_KOTLIN.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Message Formatting",permalink:"/docs/configuration/MESSAGE_FORMATTING"},next:{title:"Testing",permalink:"/docs/TESTING"}},c={},s=[],p={toc:s};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"non-kotlin-environments"},"Non-Kotlin Environments"),(0,o.kt)("p",null,"You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose."),(0,o.kt)("p",null,"Earlier versions of Kermit were designed to be Swift-friendly, but that sacrificed the Kotlin-friendly API, and since the primary use-case is calling Kermit from Kotlin, that seemed like a bad compromise."),(0,o.kt)("p",null,"We've added a module called ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-simple")," which adds explicit call signatures to the API, to provide for the cases where default parameters make more sense in a Kotlin context."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'kotlin {\n sourceSets {\n val commonMain by getting {\n dependencies {\n // etc\n implementation("co.touchlab:kermit:2.0.3")\n }\n }\n\n val iosMain by getting {\n dependencies {\n // etc\n api("co.touchlab:kermit-simple:2.0.3")\n }\n }\n }\n\n cocoapods {\n framework {\n export("co.touchlab:kermit-simple:2.0.3")\n }\n }\n}\n')),(0,o.kt)("p",null," You will need to export ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-simple"),", as in the example above."),(0,o.kt)("p",null," From Swift, this will allow you to call methods without all of the parameters explicitly added."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-swift"},'let log = // Get a Logger instance\nlog.i(messageString: "Try a log")\nlog.w(messageString: "Throw", throwable: someException)\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6a4033d2.35991a45.js b/assets/js/6a4033d2.35991a45.js new file mode 100644 index 00000000..6b2b9973 --- /dev/null +++ b/assets/js/6a4033d2.35991a45.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[299],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(r),g=a,m=d["".concat(s,".").concat(g)]||d[g]||p[g]||o;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={},i="Bugsnag",l={unversionedId:"crashreporting/BUGSNAG",id:"crashreporting/BUGSNAG",title:"Bugsnag",description:"Setup",source:"@site/docs/crashreporting/BUGSNAG.md",sourceDirName:"crashreporting",slug:"/crashreporting/BUGSNAG",permalink:"/docs/crashreporting/BUGSNAG",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/crashreporting/BUGSNAG.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Crashlytics",permalink:"/docs/crashreporting/CRASHLYTICS"},next:{title:"Extensions",permalink:"/docs/extensions/"}},s={},c=[{value:"Setup",id:"setup",level:2},{value:"Add the dependency",id:"add-the-dependency",level:2},{value:"Add the log writer",id:"add-the-log-writer",level:2},{value:"Custom Values",id:"custom-values",level:2}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"bugsnag"},"Bugsnag"),(0,a.kt)("h2",{id:"setup"},"Setup"),(0,a.kt)("p",null,"You first need to configure Bugsnag and CrashKiOS initialization. See ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/bugsnag"},"the CrashKiOS Bugsnag Tutorial Doc"),"."),(0,a.kt)("h2",{id:"add-the-dependency"},"Add the dependency"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n implementation("co.touchlab:kermit-bugsnag:2.0.3")\n }\n}\n')),(0,a.kt)("h2",{id:"add-the-log-writer"},"Add the log writer"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(BugsnagLogWriter())\n")),(0,a.kt)("h2",{id:"custom-values"},"Custom Values"),(0,a.kt)("p",null,"You can add custom values to Bugsnag, but not through Kermit. ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/bugsnag#sending-extra-info-to-bugsnag"},"Call CrashKiOS directly"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'BugsnagKotlin.setCustomValue("someKey", "someValue")\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6a4033d2.c0b40d6d.js b/assets/js/6a4033d2.c0b40d6d.js deleted file mode 100644 index ad8046fe..00000000 --- a/assets/js/6a4033d2.c0b40d6d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[299],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),g=a,m=d["".concat(l,".").concat(g)]||d[g]||p[g]||o;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={},i="Bugsnag",s={unversionedId:"crashreporting/BUGSNAG",id:"crashreporting/BUGSNAG",title:"Bugsnag",description:"Setup",source:"@site/docs/crashreporting/BUGSNAG.md",sourceDirName:"crashreporting",slug:"/crashreporting/BUGSNAG",permalink:"/docs/crashreporting/BUGSNAG",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/crashreporting/BUGSNAG.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Crashlytics",permalink:"/docs/crashreporting/CRASHLYTICS"},next:{title:"Extensions",permalink:"/docs/extensions/"}},l={},c=[{value:"Setup",id:"setup",level:2},{value:"Add the dependency",id:"add-the-dependency",level:2},{value:"Add the log writer",id:"add-the-log-writer",level:2},{value:"Custom Values",id:"custom-values",level:2}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"bugsnag"},"Bugsnag"),(0,a.kt)("h2",{id:"setup"},"Setup"),(0,a.kt)("p",null,"You first need to configure Bugsnag and CrashKiOS initialization. See ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/bugsnag"},"the CrashKiOS Bugsnag Tutorial Doc"),"."),(0,a.kt)("h2",{id:"add-the-dependency"},"Add the dependency"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n implementation("co.touchlab:kermit-bugsnag:2.0.3")\n }\n}\n')),(0,a.kt)("h2",{id:"add-the-log-writer"},"Add the log writer"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(BugsnagLogWriter())\n")),(0,a.kt)("h2",{id:"custom-values"},"Custom Values"),(0,a.kt)("p",null,"You can add custom values to Bugsnag, but not through Kermit. ",(0,a.kt)("a",{parentName:"p",href:"https://crashkios.touchlab.co/docs/bugsnag#sending-extra-info-to-bugsnag"},"Call CrashKiOS directly"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'BugsnagKotlin.setCustomValue("someKey", "someValue")\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6c52285e.8af70598.js b/assets/js/6c52285e.8af70598.js deleted file mode 100644 index 2c773d80..00000000 --- a/assets/js/6c52285e.8af70598.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[861],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),g=o,m=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return n?r.createElement(m,i(i({ref:t},c),{},{components:n})):r.createElement(m,i({ref:t},c))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:25},i="Testing",s={unversionedId:"TESTING",id:"TESTING",title:"Testing",description:"Kermit includes a test dependency, intended for use when testing application code that interacts",source:"@site/docs/TESTING.md",sourceDirName:".",slug:"/TESTING",permalink:"/docs/TESTING",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/TESTING.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:25,frontMatter:{sidebar_position:25},sidebar:"tutorialSidebar",previous:{title:"Non-Kotlin Environments",permalink:"/docs/configuration/NON_KOTLIN"},next:{title:"iOS Logging",permalink:"/docs/IOS_LOGGING"}},l={},p=[{value:"Add to your dependencies",id:"add-to-your-dependencies",level:2},{value:"Use in your tests",id:"use-in-your-tests",level:2},{value:"Logging on Android",id:"logging-on-android",level:2}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"testing"},"Testing"),(0,o.kt)("p",null,"Kermit includes a test dependency, intended for use when testing application code that interacts\nwith Kermit APIs but doesn't want to write to actual logs. This includes a ",(0,o.kt)("inlineCode",{parentName:"p"},"TestLogWriter")," which\nholds the string outputs of log statements, and has APIs for asserting on what logs are present."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The test APIs are not yet stable, and\nrequire ",(0,o.kt)("a",{parentName:"p",href:"https://kotlinlang.org/docs/opt-in-requirements.html#opt-in-to-using-api"},"opting into"),"\nthe ",(0,o.kt)("inlineCode",{parentName:"p"},"@ExperimentalKermitApi")," annotation. The current API is based on what we use to test Kermit internally. It may\nchange dramatically before we stabilize it as we consider more real-world use-cases.")),(0,o.kt)("h2",{id:"add-to-your-dependencies"},"Add to your dependencies"),(0,o.kt)("p",null,"Typically you would depend on this from your test sources."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'sourceSets {\n commonTest {\n dependencies {\n implementation("co.touchlab:kermit-test:2.0.3") //Add latest version\n }\n }\n}\n')),(0,o.kt)("h2",{id:"use-in-your-tests"},"Use in your tests"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"We strongly recommend you ",(0,o.kt)("em",{parentName:"p"},"inject")," logger instances into your classes rather than simply calling the\n(global) static ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," as it will make testing easier.")),(0,o.kt)("p",null,"Suppose you have a test"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},"@OptIn(ExperimentalKermitApi::class)\nclass MyExampleTest {\n private val testLogWriter = TestLogWriter(\n loggable = Severity.Verbose // accept everything\n )\n private val kermit = Logger(\n TestConfig(\n minSeverity = Severity.Debug,\n logWriterList = listOf(testLogWriter)\n )\n )\n \n // ...\n}\n")),(0,o.kt)("p",null,"You can either interact with the latest log entry that was produced - "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'@Test\nfun somethingInterestingHappened() {\n // ...\n\n testLogWriter.assertCount(1)\n\n // calls assertTrue() on the result of the lambda\n testLogWriter.assertLast {\n message == "the message" && severity == Severity.Info && tag == "my-tag" && throwable == null\n }\n}\n')),(0,o.kt)("p",null,"or you can interact with the list of log entries directly"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'@Test\nfun somethingElseInterestingHappened() {\n // ...\n\n testLogWriter.assertCount(10)\n\n with(testLogWriter.logs[3]) {\n assertEquals("the message", message)\n assertEquals(Severity.Info, severity)\n assertEquals("my-tag", tag)\n assertNull(throwable)\n }\n}\n')),(0,o.kt)("h2",{id:"logging-on-android"},"Logging on Android"),(0,o.kt)("p",null,"The ",(0,o.kt)("em",{parentName:"p"},"default")," setup of Kermit aims to make ",(0,o.kt)("em",{parentName:"p"},"production")," logging as simple as possible. This\nmeans that the platform logger for Android defaults to passing the log through to Android's logcat\n",(0,o.kt)("inlineCode",{parentName:"p"},"Log()")," method. Be sure to configure your tests accordingly, as this wont function when running\nunit tests on your local machine!"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6c52285e.a9dd1b20.js b/assets/js/6c52285e.a9dd1b20.js new file mode 100644 index 00000000..6a4f582f --- /dev/null +++ b/assets/js/6c52285e.a9dd1b20.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[861],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),g=o,m=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return n?r.createElement(m,i(i({ref:t},c),{},{components:n})):r.createElement(m,i({ref:t},c))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:25},i="Testing",s={unversionedId:"TESTING",id:"TESTING",title:"Testing",description:"Kermit includes a test dependency, intended for use when testing application code that interacts",source:"@site/docs/TESTING.md",sourceDirName:".",slug:"/TESTING",permalink:"/docs/TESTING",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/TESTING.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:25,frontMatter:{sidebar_position:25},sidebar:"tutorialSidebar",previous:{title:"Non-Kotlin Environments",permalink:"/docs/configuration/NON_KOTLIN"},next:{title:"iOS Logging",permalink:"/docs/IOS_LOGGING"}},l={},p=[{value:"Add to your dependencies",id:"add-to-your-dependencies",level:2},{value:"Use in your tests",id:"use-in-your-tests",level:2},{value:"Logging on Android",id:"logging-on-android",level:2}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"testing"},"Testing"),(0,o.kt)("p",null,"Kermit includes a test dependency, intended for use when testing application code that interacts\nwith Kermit APIs but doesn't want to write to actual logs. This includes a ",(0,o.kt)("inlineCode",{parentName:"p"},"TestLogWriter")," which\nholds the string outputs of log statements, and has APIs for asserting on what logs are present."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The test APIs are not yet stable, and\nrequire ",(0,o.kt)("a",{parentName:"p",href:"https://kotlinlang.org/docs/opt-in-requirements.html#opt-in-to-using-api"},"opting into"),"\nthe ",(0,o.kt)("inlineCode",{parentName:"p"},"@ExperimentalKermitApi")," annotation. The current API is based on what we use to test Kermit internally. It may\nchange dramatically before we stabilize it as we consider more real-world use-cases.")),(0,o.kt)("h2",{id:"add-to-your-dependencies"},"Add to your dependencies"),(0,o.kt)("p",null,"Typically you would depend on this from your test sources."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'sourceSets {\n commonTest {\n dependencies {\n implementation("co.touchlab:kermit-test:2.0.3") //Add latest version\n }\n }\n}\n')),(0,o.kt)("h2",{id:"use-in-your-tests"},"Use in your tests"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"We strongly recommend you ",(0,o.kt)("em",{parentName:"p"},"inject")," logger instances into your classes rather than simply calling the\n(global) static ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," as it will make testing easier.")),(0,o.kt)("p",null,"Suppose you have a test"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},"@OptIn(ExperimentalKermitApi::class)\nclass MyExampleTest {\n private val testLogWriter = TestLogWriter(\n loggable = Severity.Verbose // accept everything\n )\n private val kermit = Logger(\n TestConfig(\n minSeverity = Severity.Debug,\n logWriterList = listOf(testLogWriter)\n )\n )\n \n // ...\n}\n")),(0,o.kt)("p",null,"You can either interact with the latest log entry that was produced - "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'@Test\nfun somethingInterestingHappened() {\n // ...\n\n testLogWriter.assertCount(1)\n\n // calls assertTrue() on the result of the lambda\n testLogWriter.assertLast {\n message == "the message" && severity == Severity.Info && tag == "my-tag" && throwable == null\n }\n}\n')),(0,o.kt)("p",null,"or you can interact with the list of log entries directly"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'@Test\nfun somethingElseInterestingHappened() {\n // ...\n\n testLogWriter.assertCount(10)\n\n with(testLogWriter.logs[3]) {\n assertEquals("the message", message)\n assertEquals(Severity.Info, severity)\n assertEquals("my-tag", tag)\n assertNull(throwable)\n }\n}\n')),(0,o.kt)("h2",{id:"logging-on-android"},"Logging on Android"),(0,o.kt)("p",null,"The ",(0,o.kt)("em",{parentName:"p"},"default")," setup of Kermit aims to make ",(0,o.kt)("em",{parentName:"p"},"production")," logging as simple as possible. This\nmeans that the platform logger for Android defaults to passing the log through to Android's logcat\n",(0,o.kt)("inlineCode",{parentName:"p"},"Log()")," method. Be sure to configure your tests accordingly, as this wont function when running\nunit tests on your local machine!"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6f0769b5.858626ce.js b/assets/js/6f0769b5.3bab0d40.js similarity index 51% rename from assets/js/6f0769b5.858626ce.js rename to assets/js/6f0769b5.3bab0d40.js index 36de6f5b..0939ffe1 100644 --- a/assets/js/6f0769b5.858626ce.js +++ b/assets/js/6f0769b5.3bab0d40.js @@ -1 +1 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[832],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),g=o,m=u["".concat(s,".").concat(g)]||u[g]||d[g]||i;return n?r.createElement(m,a(a({ref:t},p),{},{components:n})):r.createElement(m,a({ref:t},p))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(7462),o=(n(7294),n(3905));const i={},a="Koin Integration",l={unversionedId:"extensions/KOIN",id:"extensions/KOIN",title:"Koin Integration",description:"Kermit's Koin integation comes in two parts - a logger implementation that writes",source:"@site/docs/extensions/KOIN.md",sourceDirName:"extensions",slug:"/extensions/KOIN",permalink:"/docs/extensions/KOIN",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/extensions/KOIN.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Extensions",permalink:"/docs/extensions/"},next:{title:"Technical Details",permalink:"/docs/category/technical-details"}},s={},c=[{value:"Setup",id:"setup",level:2},{value:"Add the dependency",id:"add-the-dependency",level:3},{value:"Register the logger with Koin",id:"register-the-logger-with-koin",level:3},{value:"Dependency Injection Helpers",id:"dependency-injection-helpers",level:2}],p={toc:c};function d(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"koin-integration"},"Koin Integration"),(0,o.kt)("p",null,"Kermit's Koin integation comes in two parts - a logger implementation that writes\nKoin logger output to Kermit, and dependency injection helpers."),(0,o.kt)("h2",{id:"setup"},"Setup"),(0,o.kt)("h3",{id:"add-the-dependency"},"Add the dependency"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n implementation("co.touchlab:kermit-koin:2.0.3")\n }\n}\n')),(0,o.kt)("h3",{id:"register-the-logger-with-koin"},"Register the logger with Koin"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'val koinApplication = startKoin {\n logger(\n KermitKoinLogger(Logger.withTag("koin"))\n )\n\n modules(/* modulesList */)\n}\n')),(0,o.kt)("p",null,"Obviously you will want to have initialized Kermit before registering a logger with Koin, and the\ntag you pass is optional. That said, it's useful to tag the Koin output to be able to filter and\nsee what is going on. Once you have registered the logger, all of the normal ",(0,o.kt)("em",{parentName:"p"},"Koin")," logging will\nbe piped through to Kermit. This is especially helpful when checking your module dependencies from\nunit tests!"),(0,o.kt)("h2",{id:"dependency-injection-helpers"},"Dependency Injection Helpers"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"kermitLoggerModule()")," method returns a Koin module that declares a factory for logger instances. If\nyou don't want to make use of the Koin factory, there's a ",(0,o.kt)("inlineCode",{parentName:"p"},"getLoggerWithTag()")," extension method you can\ncall directly."),(0,o.kt)("p",null,"We prefer injecting logger instances rather than using the global ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," instance, especially when\nwe know we'll be unit testing a section of code."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[832],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),g=o,m=u["".concat(s,".").concat(g)]||u[g]||d[g]||i;return n?r.createElement(m,a(a({ref:t},p),{},{components:n})):r.createElement(m,a({ref:t},p))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(7462),o=(n(7294),n(3905));const i={},a="Koin Integration",l={unversionedId:"extensions/KOIN",id:"extensions/KOIN",title:"Koin Integration",description:"Kermit's Koin integation comes in two parts - a logger implementation that writes",source:"@site/docs/extensions/KOIN.md",sourceDirName:"extensions",slug:"/extensions/KOIN",permalink:"/docs/extensions/KOIN",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/extensions/KOIN.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Extensions",permalink:"/docs/extensions/"},next:{title:"Technical Details",permalink:"/docs/category/technical-details"}},s={},c=[{value:"Setup",id:"setup",level:2},{value:"Add the dependency",id:"add-the-dependency",level:3},{value:"Register the logger with Koin",id:"register-the-logger-with-koin",level:3},{value:"Dependency Injection Helpers",id:"dependency-injection-helpers",level:2}],p={toc:c};function d(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"koin-integration"},"Koin Integration"),(0,o.kt)("p",null,"Kermit's Koin integation comes in two parts - a logger implementation that writes\nKoin logger output to Kermit, and dependency injection helpers."),(0,o.kt)("h2",{id:"setup"},"Setup"),(0,o.kt)("h3",{id:"add-the-dependency"},"Add the dependency"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n implementation("co.touchlab:kermit-koin:2.0.3")\n }\n}\n')),(0,o.kt)("h3",{id:"register-the-logger-with-koin"},"Register the logger with Koin"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'val koinApplication = startKoin {\n logger(\n KermitKoinLogger(Logger.withTag("koin"))\n )\n\n modules(/* modulesList */)\n}\n')),(0,o.kt)("p",null,"Obviously you will want to have initialized Kermit before registering a logger with Koin, and the\ntag you pass is optional. That said, it's useful to tag the Koin output to be able to filter and\nsee what is going on. Once you have registered the logger, all of the normal ",(0,o.kt)("em",{parentName:"p"},"Koin")," logging will\nbe piped through to Kermit. This is especially helpful when checking your module dependencies from\nunit tests!"),(0,o.kt)("h2",{id:"dependency-injection-helpers"},"Dependency Injection Helpers"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"kermitLoggerModule()")," method returns a Koin module that declares a factory for logger instances. If\nyou don't want to make use of the Koin factory, there's a ",(0,o.kt)("inlineCode",{parentName:"p"},"getLoggerWithTag()")," extension method you can\ncall directly."),(0,o.kt)("p",null,"We prefer injecting logger instances rather than using the global ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," instance, especially when\nwe know we'll be unit testing a section of code."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/73b49f1e.dffa05e0.js b/assets/js/73b49f1e.dffa05e0.js deleted file mode 100644 index aafcf27e..00000000 --- a/assets/js/73b49f1e.dffa05e0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[19],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function a(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=o.createContext({}),p=function(e){var t=o.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=p(e.components);return o.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),g=p(r),m=n,d=g["".concat(s,".").concat(m)]||g[m]||u[m]||i;return r?o.createElement(d,a(a({ref:t},c),{},{components:r})):o.createElement(d,a({ref:t},c))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,a=new Array(i);a[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:n,a[1]=l;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var o=r(7462),n=(r(7294),r(3905));const i={sidebar_position:20},a="LogWriter",l={unversionedId:"details/LOG_WRITER",id:"details/LOG_WRITER",title:"LogWriter",description:"LogWriter takes care of deciding where to log the messages.",source:"@site/docs/details/LOG_WRITER.md",sourceDirName:"details",slug:"/details/LOG_WRITER",permalink:"/docs/details/LOG_WRITER",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/details/LOG_WRITER.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:20,frontMatter:{sidebar_position:20},sidebar:"tutorialSidebar",previous:{title:"Technical Details",permalink:"/docs/category/technical-details"},next:{title:"Custom Logger API",permalink:"/docs/details/CUSTOM_API"}},s={},p=[{value:"Prebuilt LogWriters",id:"prebuilt-logwriters",level:3},{value:"Custom LogWriter",id:"custom-logwriter",level:3}],c={toc:p};function u(e){let{components:t,...r}=e;return(0,n.kt)("wrapper",(0,o.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"logwriter"},"LogWriter"),(0,n.kt)("p",null,"LogWriter takes care of deciding where to log the messages."),(0,n.kt)("h3",{id:"prebuilt-logwriters"},"Prebuilt LogWriters"),(0,n.kt)("p",null,"By default ",(0,n.kt)("inlineCode",{parentName:"p"},"Kermit")," provides default ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," for each platform"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"CommonWriter")," - Uses println to send logs in Kotlin"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"LogcatWriter")," - Uses LogCat to send logs in Android"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"OSLogWriter")," - Uses os log to send logs in iOS"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"ConsoleWriter")," - Uses console to log in JS")),(0,n.kt)("p",null,"These can be created and passed into the ",(0,n.kt)("inlineCode",{parentName:"p"},"Logger")," object during initialization"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(listOf(LogcatWriter(), CommonWriter()))\n")),(0,n.kt)("p",null,"Selecting loggers for each platform can either be done with platform-specific entry points, or using an expect/actual factory function."),(0,n.kt)("p",null,"Kermit ships with a ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/touchlab/Kermit/blob/main/kermit-core/src/commonMain/kotlin/co/touchlab/kermit/platformLogWriter.kt"},"default factory function")," that provides a ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," suited to local development."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"package co.touchlab.kermit\n\nexpect fun platformLogWriter(messageStringFormatter: MessageStringFormatter = DefaultFormatter): LogWriter\n")),(0,n.kt)("p",null,"You can implement a factory function for your project similar to the one above."),(0,n.kt)("h3",{id:"custom-logwriter"},"Custom LogWriter"),(0,n.kt)("p",null,"If you want to have a custom implementation to send logs to your own server, or a 3rd party tool or simply because default implementation doesn't fit your need, then you would need to extend the ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," class and provide your own instance."),(0,n.kt)("p",null,"For a simple ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," you only need to implement the ",(0,n.kt)("inlineCode",{parentName:"p"},"log")," method, which handles all log messages."),(0,n.kt)("p",null,"Simple implementation would look like below,"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"class YourCustomWriter : LogWriter() {\n override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {\n // Handle logging here\n }\n}\n")),(0,n.kt)("p",null,"Custom loggers may also override ",(0,n.kt)("inlineCode",{parentName:"p"},"isLoggable"),". Kermit will check this value before logging to this LogWriter."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"open fun isLoggable(tag: String, severity: Severity): Boolean = true\n")),(0,n.kt)("p",null,"If your custom logger should only send messages in production, the implementation could look like the following:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"// LogWriter\nclass YourCustomWriter(private val isProduction:Boolean) : LogWriter() {\n override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {\n // Do something custom\n }\n\n override fun isLoggable(tag: String, severity: Severity): Boolean = isProduction\n}\n\n// Usage \nval logWriter = YourCustomWriter(someProdFlag)\nval logger = Logger(loggerConfigInit(logWriter))\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/73b49f1e.ed30c356.js b/assets/js/73b49f1e.ed30c356.js new file mode 100644 index 00000000..934a8048 --- /dev/null +++ b/assets/js/73b49f1e.ed30c356.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[19],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function a(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=o.createContext({}),p=function(e){var t=o.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=p(e.components);return o.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),g=p(r),m=n,d=g["".concat(s,".").concat(m)]||g[m]||u[m]||i;return r?o.createElement(d,a(a({ref:t},c),{},{components:r})):o.createElement(d,a({ref:t},c))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,a=new Array(i);a[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:n,a[1]=l;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var o=r(7462),n=(r(7294),r(3905));const i={sidebar_position:20},a="LogWriter",l={unversionedId:"details/LOG_WRITER",id:"details/LOG_WRITER",title:"LogWriter",description:"LogWriter takes care of deciding where to log the messages.",source:"@site/docs/details/LOG_WRITER.md",sourceDirName:"details",slug:"/details/LOG_WRITER",permalink:"/docs/details/LOG_WRITER",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/details/LOG_WRITER.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:20,frontMatter:{sidebar_position:20},sidebar:"tutorialSidebar",previous:{title:"Technical Details",permalink:"/docs/category/technical-details"},next:{title:"Custom Logger API",permalink:"/docs/details/CUSTOM_API"}},s={},p=[{value:"Prebuilt LogWriters",id:"prebuilt-logwriters",level:3},{value:"Custom LogWriter",id:"custom-logwriter",level:3}],c={toc:p};function u(e){let{components:t,...r}=e;return(0,n.kt)("wrapper",(0,o.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"logwriter"},"LogWriter"),(0,n.kt)("p",null,"LogWriter takes care of deciding where to log the messages."),(0,n.kt)("h3",{id:"prebuilt-logwriters"},"Prebuilt LogWriters"),(0,n.kt)("p",null,"By default ",(0,n.kt)("inlineCode",{parentName:"p"},"Kermit")," provides default ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," for each platform"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"CommonWriter")," - Uses println to send logs in Kotlin"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"LogcatWriter")," - Uses LogCat to send logs in Android"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"OSLogWriter")," - Uses os log to send logs in iOS"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"ConsoleWriter")," - Uses console to log in JS")),(0,n.kt)("p",null,"These can be created and passed into the ",(0,n.kt)("inlineCode",{parentName:"p"},"Logger")," object during initialization"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(listOf(LogcatWriter(), CommonWriter()))\n")),(0,n.kt)("p",null,"Selecting loggers for each platform can either be done with platform-specific entry points, or using an expect/actual factory function."),(0,n.kt)("p",null,"Kermit ships with a ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/touchlab/Kermit/blob/main/kermit-core/src/commonMain/kotlin/co/touchlab/kermit/platformLogWriter.kt"},"default factory function")," that provides a ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," suited to local development."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"package co.touchlab.kermit\n\nexpect fun platformLogWriter(messageStringFormatter: MessageStringFormatter = DefaultFormatter): LogWriter\n")),(0,n.kt)("p",null,"You can implement a factory function for your project similar to the one above."),(0,n.kt)("h3",{id:"custom-logwriter"},"Custom LogWriter"),(0,n.kt)("p",null,"If you want to have a custom implementation to send logs to your own server, or a 3rd party tool or simply because default implementation doesn't fit your need, then you would need to extend the ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," class and provide your own instance."),(0,n.kt)("p",null,"For a simple ",(0,n.kt)("inlineCode",{parentName:"p"},"LogWriter")," you only need to implement the ",(0,n.kt)("inlineCode",{parentName:"p"},"log")," method, which handles all log messages."),(0,n.kt)("p",null,"Simple implementation would look like below,"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"class YourCustomWriter : LogWriter() {\n override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {\n // Handle logging here\n }\n}\n")),(0,n.kt)("p",null,"Custom loggers may also override ",(0,n.kt)("inlineCode",{parentName:"p"},"isLoggable"),". Kermit will check this value before logging to this LogWriter."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"open fun isLoggable(tag: String, severity: Severity): Boolean = true\n")),(0,n.kt)("p",null,"If your custom logger should only send messages in production, the implementation could look like the following:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-kotlin"},"// LogWriter\nclass YourCustomWriter(private val isProduction:Boolean) : LogWriter() {\n override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {\n // Do something custom\n }\n\n override fun isLoggable(tag: String, severity: Severity): Boolean = isProduction\n}\n\n// Usage \nval logWriter = YourCustomWriter(someProdFlag)\nval logger = Logger(loggerConfigInit(logWriter))\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/77037996.037b7e95.js b/assets/js/77037996.037b7e95.js deleted file mode 100644 index 56737bec..00000000 --- a/assets/js/77037996.037b7e95.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[463],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),m=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=m(e.components);return a.createElement(s.Provider,{value:t},e.children)},g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=m(n),u=r,c=d["".concat(s,".").concat(u)]||d[u]||g[u]||o;return n?a.createElement(c,i(i({ref:t},p),{},{components:n})):a.createElement(c,i({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var m=2;m{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>m});var a=n(7462),r=(n(7294),n(3905));const o={},i="Message Formatting",l={unversionedId:"configuration/MESSAGE_FORMATTING",id:"configuration/MESSAGE_FORMATTING",title:"Message Formatting",description:"To make message formatting more uniform and flexible, many of the LogWriter instances can take a MessageStringFormatter parameter. This allows you to control how log messages are presented and apply common formatting.",source:"@site/docs/configuration/MESSAGE_FORMATTING.md",sourceDirName:"configuration",slug:"/configuration/MESSAGE_FORMATTING",permalink:"/docs/configuration/MESSAGE_FORMATTING",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/MESSAGE_FORMATTING.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Logger Setup",permalink:"/docs/configuration/LOGGER_SETUP"},next:{title:"Non-Kotlin Environments",permalink:"/docs/configuration/NON_KOTLIN"}},s={},m=[{value:"Log Message Components",id:"log-message-components",level:2},{value:"Implementations",id:"implementations",level:2},{value:"DefaultLogFormatter",id:"defaultlogformatter",level:3},{value:"NoTagFormatter",id:"notagformatter",level:3},{value:"SimpleLogFormatter",id:"simplelogformatter",level:3},{value:"Configuration",id:"configuration",level:2}],p={toc:m};function g(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"message-formatting"},"Message Formatting"),(0,r.kt)("p",null,"To make message formatting more uniform and flexible, many of the ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances can take a ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," parameter. This allows you to control how log messages are presented and apply common formatting."),(0,r.kt)("admonition",{title:"TL;DR",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you don't want tags to be printed in your iOS or JS log statements, give your ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances ",(0,r.kt)("inlineCode",{parentName:"p"},"NoTagFormatter"),". This will suppress printing tag in log message strings. Tag will still be sent to Android log messages."),(0,r.kt)("p",{parentName:"admonition"},"For the global ",(0,r.kt)("inlineCode",{parentName:"p"},"Logger")," and the platform ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter"),", config would look like the following:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(platformLogWriter(NoTagFormatter))\n")),(0,r.kt)("p",{parentName:"admonition"},"For most use cases, this is all you need to know about formatters. The rest of this doc explains them in more detail.")),(0,r.kt)("h2",{id:"log-message-components"},"Log Message Components"),(0,r.kt)("p",null,"There are 3 parts to a message: Severity, Tag, and the Message itself. All loggers accept a log message string, but support for severity and tag vary between systems. Here is a breakdown of support for a few commonly used logging systems."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"System"),(0,r.kt)("th",{parentName:"tr",align:null},"Severity"),(0,r.kt)("th",{parentName:"tr",align:null},"Tag"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSLog (iOS)"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"JS-Console"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"SystemWriter (jvm)"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Common (println)"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")))),(0,r.kt)("p",null,"The main purpose of ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," is to manage situations where the logging system does not support either Severity or Tag. The ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instance will pass null's to the ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," in cases where the ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," natively supports Severity or Tag."),(0,r.kt)("p",null,"For example, the ",(0,r.kt)("inlineCode",{parentName:"p"},"DefaultLogFormatter")," will result in the following message strings depending on platform:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},"// Log call\nLogger.w(tag = \"ATag\") { \"A Log Message\" }\n\n// Android\n// 'A Log Message'\n\n// OSLog\n// '(ATag) A Log Message'\n\n// Common\n// 'Warn: (ATag) A Log Message'\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"You ",(0,r.kt)("em",{parentName:"p"},"can")," use ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," to implement custom message strings. Maybe, say, add a special date format to each line. However, Kermit uses them to manage Severity and Tag for systems that don't natively support those constructs. Note: the Android ",(0,r.kt)("inlineCode",{parentName:"p"},"LogcatWriter")," does not currently use a ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter"),". You would need to create a custom implementation to support that.")),(0,r.kt)("h2",{id:"implementations"},"Implementations"),(0,r.kt)("p",null,"Kermit provides a few implementations out of the box."),(0,r.kt)("h3",{id:"defaultlogformatter"},(0,r.kt)("inlineCode",{parentName:"h3"},"DefaultLogFormatter")),(0,r.kt)("p",null,"This is the standard format that all compatible ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances get by default. Messages are formatted as in the examples above."),(0,r.kt)("h3",{id:"notagformatter"},(0,r.kt)("inlineCode",{parentName:"h3"},"NoTagFormatter")),(0,r.kt)("p",null,"Tags are really an Android convention. Other platforms can feel cluttered with them. You can simply ignore them with ",(0,r.kt)("inlineCode",{parentName:"p"},"NoTagFormatter"),". Logging will function the same for Android, and other platforms will ignore the Tag."),(0,r.kt)("h3",{id:"simplelogformatter"},(0,r.kt)("inlineCode",{parentName:"h3"},"SimpleLogFormatter")),(0,r.kt)("p",null,"This formatter skips tags and severity. It just prints the message."),(0,r.kt)("h2",{id:"configuration"},"Configuration"),(0,r.kt)("p",null,"To simplify setting platform ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances, you can pass a ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"platformLogWriter"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},"platformLogWriter(NoTagLogFormatter)\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/77037996.e02d3ebf.js b/assets/js/77037996.e02d3ebf.js new file mode 100644 index 00000000..0fa721f0 --- /dev/null +++ b/assets/js/77037996.e02d3ebf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[463],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),m=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=m(e.components);return a.createElement(s.Provider,{value:t},e.children)},g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=m(n),u=r,c=d["".concat(s,".").concat(u)]||d[u]||g[u]||o;return n?a.createElement(c,i(i({ref:t},p),{},{components:n})):a.createElement(c,i({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var m=2;m{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>m});var a=n(7462),r=(n(7294),n(3905));const o={},i="Message Formatting",l={unversionedId:"configuration/MESSAGE_FORMATTING",id:"configuration/MESSAGE_FORMATTING",title:"Message Formatting",description:"To make message formatting more uniform and flexible, many of the LogWriter instances can take a MessageStringFormatter parameter. This allows you to control how log messages are presented and apply common formatting.",source:"@site/docs/configuration/MESSAGE_FORMATTING.md",sourceDirName:"configuration",slug:"/configuration/MESSAGE_FORMATTING",permalink:"/docs/configuration/MESSAGE_FORMATTING",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/MESSAGE_FORMATTING.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Logger Setup",permalink:"/docs/configuration/LOGGER_SETUP"},next:{title:"Non-Kotlin Environments",permalink:"/docs/configuration/NON_KOTLIN"}},s={},m=[{value:"Log Message Components",id:"log-message-components",level:2},{value:"Implementations",id:"implementations",level:2},{value:"DefaultLogFormatter",id:"defaultlogformatter",level:3},{value:"NoTagFormatter",id:"notagformatter",level:3},{value:"SimpleLogFormatter",id:"simplelogformatter",level:3},{value:"Configuration",id:"configuration",level:2}],p={toc:m};function g(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"message-formatting"},"Message Formatting"),(0,r.kt)("p",null,"To make message formatting more uniform and flexible, many of the ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances can take a ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," parameter. This allows you to control how log messages are presented and apply common formatting."),(0,r.kt)("admonition",{title:"TL;DR",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you don't want tags to be printed in your iOS or JS log statements, give your ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances ",(0,r.kt)("inlineCode",{parentName:"p"},"NoTagFormatter"),". This will suppress printing tag in log message strings. Tag will still be sent to Android log messages."),(0,r.kt)("p",{parentName:"admonition"},"For the global ",(0,r.kt)("inlineCode",{parentName:"p"},"Logger")," and the platform ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter"),", config would look like the following:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},"Logger.setLogWriters(platformLogWriter(NoTagFormatter))\n")),(0,r.kt)("p",{parentName:"admonition"},"For most use cases, this is all you need to know about formatters. The rest of this doc explains them in more detail.")),(0,r.kt)("h2",{id:"log-message-components"},"Log Message Components"),(0,r.kt)("p",null,"There are 3 parts to a message: Severity, Tag, and the Message itself. All loggers accept a log message string, but support for severity and tag vary between systems. Here is a breakdown of support for a few commonly used logging systems."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"System"),(0,r.kt)("th",{parentName:"tr",align:null},"Severity"),(0,r.kt)("th",{parentName:"tr",align:null},"Tag"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSLog (iOS)"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"JS-Console"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"SystemWriter (jvm)"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Common (println)"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c")))),(0,r.kt)("p",null,"The main purpose of ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," is to manage situations where the logging system does not support either Severity or Tag. The ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instance will pass null's to the ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," in cases where the ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," natively supports Severity or Tag."),(0,r.kt)("p",null,"For example, the ",(0,r.kt)("inlineCode",{parentName:"p"},"DefaultLogFormatter")," will result in the following message strings depending on platform:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},"// Log call\nLogger.w(tag = \"ATag\") { \"A Log Message\" }\n\n// Android\n// 'A Log Message'\n\n// OSLog\n// '(ATag) A Log Message'\n\n// Common\n// 'Warn: (ATag) A Log Message'\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"You ",(0,r.kt)("em",{parentName:"p"},"can")," use ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," to implement custom message strings. Maybe, say, add a special date format to each line. However, Kermit uses them to manage Severity and Tag for systems that don't natively support those constructs. Note: the Android ",(0,r.kt)("inlineCode",{parentName:"p"},"LogcatWriter")," does not currently use a ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter"),". You would need to create a custom implementation to support that.")),(0,r.kt)("h2",{id:"implementations"},"Implementations"),(0,r.kt)("p",null,"Kermit provides a few implementations out of the box."),(0,r.kt)("h3",{id:"defaultlogformatter"},(0,r.kt)("inlineCode",{parentName:"h3"},"DefaultLogFormatter")),(0,r.kt)("p",null,"This is the standard format that all compatible ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances get by default. Messages are formatted as in the examples above."),(0,r.kt)("h3",{id:"notagformatter"},(0,r.kt)("inlineCode",{parentName:"h3"},"NoTagFormatter")),(0,r.kt)("p",null,"Tags are really an Android convention. Other platforms can feel cluttered with them. You can simply ignore them with ",(0,r.kt)("inlineCode",{parentName:"p"},"NoTagFormatter"),". Logging will function the same for Android, and other platforms will ignore the Tag."),(0,r.kt)("h3",{id:"simplelogformatter"},(0,r.kt)("inlineCode",{parentName:"h3"},"SimpleLogFormatter")),(0,r.kt)("p",null,"This formatter skips tags and severity. It just prints the message."),(0,r.kt)("h2",{id:"configuration"},"Configuration"),(0,r.kt)("p",null,"To simplify setting platform ",(0,r.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances, you can pass a ",(0,r.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"platformLogWriter"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},"platformLogWriter(NoTagLogFormatter)\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c377a04b.4d3db33e.js b/assets/js/c377a04b.4d3db33e.js new file mode 100644 index 00000000..adf56996 --- /dev/null +++ b/assets/js/c377a04b.4d3db33e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[971],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>c});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=o.createContext({}),s=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=s(e.components);return o.createElement(p.Provider,{value:t},e.children)},g={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=s(n),c=a,m=u["".concat(p,".").concat(c)]||u[c]||g[c]||r;return n?o.createElement(m,i(i({ref:t},d),{},{components:n})):o.createElement(m,i({ref:t},d))}));function c(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>g,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var o=n(7462),a=(n(7294),n(3905));const r={id:"intro",sidebar_position:10},i="Kermit the log",l={unversionedId:"intro",id:"intro",title:"Kermit the log",description:"Kermit is a Kotlin Multiplatform logging library.",source:"@site/docs/index.md",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/index.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:10,frontMatter:{id:"intro",sidebar_position:10},sidebar:"tutorialSidebar",next:{title:"Configuration",permalink:"/docs/configuration/"}},p={},s=[{value:"Getting Started",id:"getting-started",level:2},{value:"1. Add Dependency",id:"1-add-dependency",level:3},{value:"2. Log",id:"2-log",level:3},{value:"Default LogWriter",id:"default-logwriter",level:3},{value:"Basic Concepts",id:"basic-concepts",level:2},{value:"Logger",id:"logger",level:3},{value:"LogWriter",id:"logwriter",level:3},{value:"Severity",id:"severity",level:3},{value:"Usage",id:"usage",level:2},{value:"A Note About Tags",id:"a-note-about-tags",level:3},{value:"Deprecated Gradle properties",id:"deprecated-gradle-properties",level:2}],d={toc:s};function g(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"kermit-the-log"},"Kermit ",(0,a.kt)("sub",null,"the log")),(0,a.kt)("p",null,"Kermit is a Kotlin Multiplatform logging library."),(0,a.kt)("p",null,"It's primary purpose is to allow log statements from Kotlin code to be written to composable log outputs. Out of the box, the library defaults to platform-specific loggers such as ",(0,a.kt)("inlineCode",{parentName:"p"},"Logcat")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"OSLog"),", but is easy to extend and configure."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"Check out ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/touchlab/KaMPKit"},"KaMP Kit")," to get started developing for Kotlin Multiplatform")),(0,a.kt)("h2",{id:"getting-started"},"Getting Started"),(0,a.kt)("p",null,"Configuration for different environments can get more complex, but the default config out of the box is fairly simple."),(0,a.kt)("h3",{id:"1-add-dependency"},"1. Add Dependency"),(0,a.kt)("p",null,"The Kermit dependency should be added to your ",(0,a.kt)("inlineCode",{parentName:"p"},"commonMain")," source set in your Kotlin Multiplatform module."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n ...\n implementation("co.touchlab:kermit:2.0.3") //Add latest version\n }\n}\n')),(0,a.kt)("h3",{id:"2-log"},"2. Log"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.i { "Hello World" }\n')),(0,a.kt)("h3",{id:"default-logwriter"},"Default LogWriter"),(0,a.kt)("p",null,"By default, Kermit includes a LogWriter instance for each platform that is configured for ",(0,a.kt)("strong",{parentName:"p"},"development"),"."),(0,a.kt)("p",null,"On Android it writes to ",(0,a.kt)("inlineCode",{parentName:"p"},"Logcat"),", on iOS it writes to ",(0,a.kt)("inlineCode",{parentName:"p"},"OSLog"),", and for JS it writes to ",(0,a.kt)("inlineCode",{parentName:"p"},"console"),"."),(0,a.kt)("h2",{id:"basic-concepts"},"Basic Concepts"),(0,a.kt)("p",null,"The basic components you'll need to be aware of are ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"Severity"),"."),(0,a.kt)("h3",{id:"logger"},"Logger"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," takes log calls from your code and dispatches them to ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances. There are different methods\non ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," corresponding to different log ",(0,a.kt)("inlineCode",{parentName:"p"},"Severity")," levels. In order of least to most severe: ",(0,a.kt)("inlineCode",{parentName:"p"},"v(), d(), i(), w(), e(),")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"a()"),"."),(0,a.kt)("p",null,"You configure the ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger"),", then call log methods on it. That's the basic interaction with Kermit."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.i { "Hello World" }\n\ntry {\n somethingRisky()\n}\ncatch(t: Throwable){\n Logger.w(t) { "That could\'ve gone better" }\n}\n')),(0,a.kt)("h3",{id:"logwriter"},"LogWriter"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," actually sends log messages to different log outputs. You add ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances to a ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger"),"."),(0,a.kt)("p",null,"Kermit includes a ",(0,a.kt)("inlineCode",{parentName:"p"},"CommonWriter")," and various platform-specific ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances. Through other modules, Kermit also allows logging crash info to Crashlytics and Bugsnag."),(0,a.kt)("p",null,"For more info on included ",(0,a.kt)("inlineCode",{parentName:"p"},"LogWriter")," types, and to create your own, see ",(0,a.kt)("a",{parentName:"p",href:"/docs/details/LOG_WRITER"},"LOG_WRITER")),(0,a.kt)("h3",{id:"severity"},"Severity"),(0,a.kt)("p",null,"Severity levels follow common logging library patterns and should be generally familiar. You can control what will and won't get logged based on severity. So, say you only want to log ",(0,a.kt)("inlineCode",{parentName:"p"},"Warn")," and up, you can tell the logger. We'll cover that more in ",(0,a.kt)("a",{parentName:"p",href:"#Configuration"},"Configuration")),(0,a.kt)("h2",{id:"usage"},"Usage"),(0,a.kt)("p",null,"The primary logging artifact is ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/touchlab/Kermit/blob/kpg/api_reformat2/kermit/src/commonMain/kotlin/co/touchlab/kermit/Logger.kt"},"Logger"),". It defines the severity-level logging methods. It has a Kotlin-aware api relying on default parameters and lambda syntax."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"To log from non-Kotlin clients, that don't support calling Kotlin's default parameters, see ",(0,a.kt)("a",{parentName:"p",href:"/docs/configuration/NON_KOTLIN"},"NON_KOTLIN"),". A common use case would be calling Kermit from Swift or JS.")),(0,a.kt)("p",null,"For each severity, there are two methods. One takes a ",(0,a.kt)("inlineCode",{parentName:"p"},"String")," log message directly, the other takes a function parameter that returns a string. The function is only evaluated if the log will be written. Which you use is personal preference. They both will log to the same places, but the function parameter version may avoid unecessary ",(0,a.kt)("inlineCode",{parentName:"p"},"String")," creation and evaluation."),(0,a.kt)("p",null,"Here are what the ",(0,a.kt)("inlineCode",{parentName:"p"},"w")," method definitions look like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"// Trailing function parameter\nfun w(throwable: Throwable? = null, tag: String = this.tag, message: () -> String)\n\n// String message parameter\nfun w(messageString: String, throwable: Throwable? = null, tag: String = this.tag)\n")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The function parameter is at the end of the function to support Kotlin's ",(0,a.kt)("a",{parentName:"p",href:"https://kotlinlang.org/docs/lambdas.html#passing-trailing-lambdas"},"trailing lambda syntax"),".")),(0,a.kt)("p",null,"In its most basic form, logging looks like this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.i { "Hello World" }\n')),(0,a.kt)("p",null,"Some other examples with tags and ",(0,a.kt)("inlineCode",{parentName:"p"},"Throwable")," params."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.w("MyTag") { "Hello World $someData" }\n// etc\nLogger.e(ex) { "Something failed" }\n// or\nLogger.e("Something failed", ex)\n')),(0,a.kt)("h3",{id:"a-note-about-tags"},"A Note About Tags"),(0,a.kt)("p",null,"Tags are much more common on Android, as Logcat has tag arguments, and it is the default logger on Android. It would be difficult to have a Kotlin Multiplatform library without them, but they don't really fit into other platforms as easily."),(0,a.kt)("p",null,"Kermit's default tag is an empty string. You can supply a tag param to each log call, change the base default tag, or create a ",(0,a.kt)("inlineCode",{parentName:"p"},"Logger")," instance with it's own tag. For example, create a field in a ViewModel with the tag set to the class name (a common Android pattern):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'class MyViewModel:ViewModel {\n private val log = Logger.withTag("MyViewModel")\n}\n')),(0,a.kt)("p",null,"Platform-specific loggers can be configured to ignore tags on output, or you can customize their display easily. We'll discuss these options more in ",(0,a.kt)("a",{parentName:"p",href:"/docs/configuration/"},"Configuration"),"."),(0,a.kt)("h2",{id:"deprecated-gradle-properties"},"Deprecated Gradle properties"),(0,a.kt)("p",null,"Per the official ",(0,a.kt)("a",{parentName:"p",href:"https://kotlinlang.org/docs/multiplatform-compatibility-guide.html#deprecated-gradle-properties-for-hierarchical-structure-support"},"Kotlin documentation")," we took the opportunity\nwith the Kermit 2.0 release to remove deprecated ",(0,a.kt)("inlineCode",{parentName:"p"},"gradle.properties")," values. We encourage you to do the same!"))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c377a04b.64431cee.js b/assets/js/c377a04b.64431cee.js deleted file mode 100644 index 7ec28ab0..00000000 --- a/assets/js/c377a04b.64431cee.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[971],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>c});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=s(n),c=o,m=u["".concat(p,".").concat(c)]||u[c]||g[c]||r;return n?a.createElement(m,i(i({ref:t},d),{},{components:n})):a.createElement(m,i({ref:t},d))}));function c(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>g,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var a=n(7462),o=(n(7294),n(3905));const r={id:"intro",sidebar_position:10},i="Kermit the log",l={unversionedId:"intro",id:"intro",title:"Kermit the log",description:"Kermit is a Kotlin Multiplatform logging library.",source:"@site/docs/index.md",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/index.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:10,frontMatter:{id:"intro",sidebar_position:10},sidebar:"tutorialSidebar",next:{title:"Configuration",permalink:"/docs/configuration/"}},p={},s=[{value:"Getting Started",id:"getting-started",level:2},{value:"1. Add Dependency",id:"1-add-dependency",level:3},{value:"2. Log",id:"2-log",level:3},{value:"Default LogWriter",id:"default-logwriter",level:3},{value:"Basic Concepts",id:"basic-concepts",level:2},{value:"Logger",id:"logger",level:3},{value:"LogWriter",id:"logwriter",level:3},{value:"Severity",id:"severity",level:3},{value:"Usage",id:"usage",level:2},{value:"A Note About Tags",id:"a-note-about-tags",level:3},{value:"Deprecated Gradle properties",id:"deprecated-gradle-properties",level:2}],d={toc:s};function g(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kermit-the-log"},"Kermit ",(0,o.kt)("sub",null,"the log")),(0,o.kt)("p",null,"Kermit is a Kotlin Multiplatform logging library."),(0,o.kt)("p",null,"It's primary purpose is to allow log statements from Kotlin code to be written to composable log outputs. Out of the box, the library defaults to platform-specific loggers such as ",(0,o.kt)("inlineCode",{parentName:"p"},"Logcat")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"OSLog"),", but is easy to extend and configure."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Check out ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/touchlab/KaMPKit"},"KaMP Kit")," to get started developing for Kotlin Multiplatform")),(0,o.kt)("h2",{id:"getting-started"},"Getting Started"),(0,o.kt)("p",null,"Configuration for different environments can get more complex, but the default config out of the box is fairly simple."),(0,o.kt)("h3",{id:"1-add-dependency"},"1. Add Dependency"),(0,o.kt)("p",null,"The Kermit dependency should be added to your ",(0,o.kt)("inlineCode",{parentName:"p"},"commonMain")," source set in your Kotlin Multiplatform module."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'commonMain {\n dependencies {\n ...\n implementation("co.touchlab:kermit:2.0.3") //Add latest version\n }\n}\n')),(0,o.kt)("h3",{id:"2-log"},"2. Log"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.i { "Hello World" }\n')),(0,o.kt)("h3",{id:"default-logwriter"},"Default LogWriter"),(0,o.kt)("p",null,"By default, Kermit includes a LogWriter instance for each platform that is configured for ",(0,o.kt)("strong",{parentName:"p"},"development"),"."),(0,o.kt)("p",null,"On Android it writes to ",(0,o.kt)("inlineCode",{parentName:"p"},"Logcat"),", on iOS it writes to ",(0,o.kt)("inlineCode",{parentName:"p"},"OSLog"),", and for JS it writes to ",(0,o.kt)("inlineCode",{parentName:"p"},"console"),"."),(0,o.kt)("h2",{id:"basic-concepts"},"Basic Concepts"),(0,o.kt)("p",null,"The basic components you'll need to be aware of are ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"Severity"),"."),(0,o.kt)("h3",{id:"logger"},"Logger"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," takes log calls from your code and dispatches them to ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances. There are different methods\non ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," corresponding to different log ",(0,o.kt)("inlineCode",{parentName:"p"},"Severity")," levels. In order of least to most severe: ",(0,o.kt)("inlineCode",{parentName:"p"},"v(), d(), i(), w(), e(),")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"a()"),"."),(0,o.kt)("p",null,"You configure the ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger"),", then call log methods on it. That's the basic interaction with Kermit."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.i { "Hello World" }\n\ntry {\n somethingRisky()\n}\ncatch(t: Throwable){\n Logger.w(t) { "That could\'ve gone better" }\n}\n')),(0,o.kt)("h3",{id:"logwriter"},"LogWriter"),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," actually sends log messages to different log outputs. You add ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances to a ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger"),"."),(0,o.kt)("p",null,"Kermit includes a ",(0,o.kt)("inlineCode",{parentName:"p"},"CommonWriter")," and various platform-specific ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances. Through other modules, Kermit also allows logging crash info to Crashlytics and Bugsnag."),(0,o.kt)("p",null,"For more info on included ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," types, and to create your own, see ",(0,o.kt)("a",{parentName:"p",href:"/docs/details/LOG_WRITER"},"LOG_WRITER")),(0,o.kt)("h3",{id:"severity"},"Severity"),(0,o.kt)("p",null,"Severity levels follow common logging library patterns and should be generally familiar. You can control what will and won't get logged based on severity. So, say you only want to log ",(0,o.kt)("inlineCode",{parentName:"p"},"Warn")," and up, you can tell the logger. We'll cover that more in ",(0,o.kt)("a",{parentName:"p",href:"#Configuration"},"Configuration")),(0,o.kt)("h2",{id:"usage"},"Usage"),(0,o.kt)("p",null,"The primary logging artifact is ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/touchlab/Kermit/blob/kpg/api_reformat2/kermit/src/commonMain/kotlin/co/touchlab/kermit/Logger.kt"},"Logger"),". It defines the severity-level logging methods. It has a Kotlin-aware api relying on default parameters and lambda syntax."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"To log from non-Kotlin clients, that don't support calling Kotlin's default parameters, see ",(0,o.kt)("a",{parentName:"p",href:"/docs/configuration/NON_KOTLIN"},"NON_KOTLIN"),". A common use case would be calling Kermit from Swift or JS.")),(0,o.kt)("p",null,"For each severity, there are two methods. One takes a ",(0,o.kt)("inlineCode",{parentName:"p"},"String")," log message directly, the other takes a function parameter that returns a string. The function is only evaluated if the log will be written. Which you use is personal preference. They both will log to the same places, but the function parameter version may avoid unecessary ",(0,o.kt)("inlineCode",{parentName:"p"},"String")," creation and evaluation."),(0,o.kt)("p",null,"Here are what the ",(0,o.kt)("inlineCode",{parentName:"p"},"w")," method definitions look like:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},"// Trailing function parameter\nfun w(throwable: Throwable? = null, tag: String = this.tag, message: () -> String)\n\n// String message parameter\nfun w(messageString: String, throwable: Throwable? = null, tag: String = this.tag)\n")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The function parameter is at the end of the function to support Kotlin's ",(0,o.kt)("a",{parentName:"p",href:"https://kotlinlang.org/docs/lambdas.html#passing-trailing-lambdas"},"trailing lambda syntax"),".")),(0,o.kt)("p",null,"In its most basic form, logging looks like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.i { "Hello World" }\n')),(0,o.kt)("p",null,"Some other examples with tags and ",(0,o.kt)("inlineCode",{parentName:"p"},"Throwable")," params."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'Logger.w("MyTag") { "Hello World $someData" }\n// etc\nLogger.e(ex) { "Something failed" }\n// or\nLogger.e("Something failed", ex)\n')),(0,o.kt)("h3",{id:"a-note-about-tags"},"A Note About Tags"),(0,o.kt)("p",null,"Tags are much more common on Android, as Logcat has tag arguments, and it is the default logger on Android. It would be difficult to have a Kotlin Multiplatform library without them, but they don't really fit into other platforms as easily."),(0,o.kt)("p",null,"Kermit's default tag is an empty string. You can supply a tag param to each log call, change the base default tag, or create a ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," instance with it's own tag. For example, create a field in a ViewModel with the tag set to the class name (a common Android pattern):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'class MyViewModel:ViewModel {\n private val log = Logger.withTag("MyViewModel")\n}\n')),(0,o.kt)("p",null,"Platform-specific loggers can be configured to ignore tags on output, or you can customize their display easily. We'll discuss these options more in ",(0,o.kt)("a",{parentName:"p",href:"/docs/configuration/"},"Configuration"),"."),(0,o.kt)("h2",{id:"deprecated-gradle-properties"},"Deprecated Gradle properties"),(0,o.kt)("p",null,"Per the official ",(0,o.kt)("a",{parentName:"p",href:"https://kotlinlang.org/docs/multiplatform-compatibility-guide.html#deprecated-gradle-properties-for-hierarchical-structure-support"},"Kotlin documentation")," we took the opportunity\nwith the Kermit 2.0 release to remove deprecated ",(0,o.kt)("inlineCode",{parentName:"p"},"gradle.properties")," values. We encourage you to do the same!"))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f6d78023.39581966.js b/assets/js/f6d78023.7c6c100e.js similarity index 59% rename from assets/js/f6d78023.39581966.js rename to assets/js/f6d78023.7c6c100e.js index aa362cfb..ac8c202a 100644 --- a/assets/js/f6d78023.39581966.js +++ b/assets/js/f6d78023.7c6c100e.js @@ -1 +1 @@ -"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[16],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=o,f=d["".concat(s,".").concat(m)]||d[m]||p[m]||i;return n?r.createElement(f,a(a({ref:t},u),{},{components:n})):r.createElement(f,a({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:20},a="Configuration",l={unversionedId:"configuration/index",id:"configuration/index",title:"Configuration",description:"Logger Setup",source:"@site/docs/configuration/index.md",sourceDirName:"configuration",slug:"/configuration/",permalink:"/docs/configuration/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/index.md",tags:[],version:"current",lastUpdatedBy:"Jigar Brahmbhatt",lastUpdatedAt:1706976218,formattedLastUpdatedAt:"Feb 3, 2024",sidebarPosition:20,frontMatter:{sidebar_position:20},sidebar:"tutorialSidebar",previous:{title:"Kermit the log",permalink:"/docs/"},next:{title:"Logger Setup",permalink:"/docs/configuration/LOGGER_SETUP"}},s={},c=[{value:"Logger Setup",id:"logger-setup",level:2},{value:"Message Formatting",id:"message-formatting",level:2},{value:"Non-Kotlin Environments",id:"non-kotlin-environments",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"configuration"},"Configuration"),(0,o.kt)("h2",{id:"logger-setup"},(0,o.kt)("a",{parentName:"h2",href:"LOGGER_SETUP"},"Logger Setup")),(0,o.kt)("p",null,"Logger setup includes various topics, including static vs mutable, and adding non-default ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances."),(0,o.kt)("h2",{id:"message-formatting"},(0,o.kt)("a",{parentName:"h2",href:"MESSAGE_FORMATTING"},"Message Formatting")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances sometimes need to include tag or severity in the log message string. You may also want to add some custom info to the message strings. ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," allows for central formatting configuration."),(0,o.kt)("h2",{id:"non-kotlin-environments"},(0,o.kt)("a",{parentName:"h2",href:"NON_KOTLIN"},"Non-Kotlin Environments")),(0,o.kt)("p",null,"Kermit's API is designed to be Kotlin-friendly. That includes methods with default parameters. To call Kermit from other environments, for example Swift, you'll probably want to add and export ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-simple"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktouchlab=self.webpackChunktouchlab||[]).push([[16],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=o,f=d["".concat(s,".").concat(m)]||d[m]||p[m]||i;return n?r.createElement(f,a(a({ref:t},u),{},{components:n})):r.createElement(f,a({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:20},a="Configuration",l={unversionedId:"configuration/index",id:"configuration/index",title:"Configuration",description:"Logger Setup",source:"@site/docs/configuration/index.md",sourceDirName:"configuration",slug:"/configuration/",permalink:"/docs/configuration/",draft:!1,editUrl:"https://github.com/touchlab/Kermit/tree/main/website/docs/configuration/index.md",tags:[],version:"current",lastUpdatedBy:"Kevin Galligan",lastUpdatedAt:1714492154,formattedLastUpdatedAt:"Apr 30, 2024",sidebarPosition:20,frontMatter:{sidebar_position:20},sidebar:"tutorialSidebar",previous:{title:"Kermit the log",permalink:"/docs/"},next:{title:"Logger Setup",permalink:"/docs/configuration/LOGGER_SETUP"}},s={},c=[{value:"Logger Setup",id:"logger-setup",level:2},{value:"Message Formatting",id:"message-formatting",level:2},{value:"Non-Kotlin Environments",id:"non-kotlin-environments",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"configuration"},"Configuration"),(0,o.kt)("h2",{id:"logger-setup"},(0,o.kt)("a",{parentName:"h2",href:"LOGGER_SETUP"},"Logger Setup")),(0,o.kt)("p",null,"Logger setup includes various topics, including static vs mutable, and adding non-default ",(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances."),(0,o.kt)("h2",{id:"message-formatting"},(0,o.kt)("a",{parentName:"h2",href:"MESSAGE_FORMATTING"},"Message Formatting")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"LogWriter")," instances sometimes need to include tag or severity in the log message string. You may also want to add some custom info to the message strings. ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageStringFormatter")," allows for central formatting configuration."),(0,o.kt)("h2",{id:"non-kotlin-environments"},(0,o.kt)("a",{parentName:"h2",href:"NON_KOTLIN"},"Non-Kotlin Environments")),(0,o.kt)("p",null,"Kermit's API is designed to be Kotlin-friendly. That includes methods with default parameters. To call Kermit from other environments, for example Swift, you'll probably want to add and export ",(0,o.kt)("inlineCode",{parentName:"p"},"kermit-simple"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.09b40836.js b/assets/js/runtime~main.09b40836.js deleted file mode 100644 index 0eff6fb8..00000000 --- a/assets/js/runtime~main.09b40836.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var e,t,r,a,o,f={},n={};function d(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={id:e,loaded:!1,exports:{}};return f[e].call(r.exports,r,r.exports,d),r.loaded=!0,r.exports}d.m=f,e=[],d.O=(t,r,a,o)=>{if(!r){var f=1/0;for(b=0;b=o)&&Object.keys(d.O).every((e=>d.O[e](r[c])))?r.splice(c--,1):(n=!1,o0&&e[b-1][2]>o;b--)e[b]=e[b-1];e[b]=[r,a,o]},d.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return d.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,d.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);d.r(o);var f={};t=t||[null,r({}),r([]),r(r)];for(var n=2&a&&e;"object"==typeof n&&!~t.indexOf(n);n=r(n))Object.getOwnPropertyNames(n).forEach((t=>f[t]=()=>e[t]));return f.default=()=>e,d.d(o,f),o},d.d=(e,t)=>{for(var r in t)d.o(t,r)&&!d.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},d.f={},d.e=e=>Promise.all(Object.keys(d.f).reduce(((t,r)=>(d.f[r](e,t),t)),[])),d.u=e=>"assets/js/"+({16:"f6d78023",19:"73b49f1e",53:"935f2afb",162:"58e6863e",165:"dc49a7e1",198:"6e9656ad",237:"1df93b7f",299:"6a4033d2",330:"2c56297f",363:"583db3ef",377:"efd0e1b0",463:"77037996",514:"1be78505",582:"77cf246b",656:"599169ee",667:"f582e6b9",710:"1b8c0795",787:"6505a119",817:"14eb3368",832:"6f0769b5",837:"d6c23c28",861:"6c52285e",918:"17896441",920:"1a4e3797",962:"018e43cb",971:"c377a04b"}[e]||e)+"."+{16:"39581966",19:"dffa05e0",53:"6de8d6f5",162:"6d137e00",165:"d35e5ea8",198:"7c3fea4b",204:"607a5b50",237:"cc1ca6fe",299:"c0b40d6d",330:"9df73147",347:"497f2026",363:"6ae4a4ec",377:"1031bc29",443:"4145d4a3",463:"037b7e95",514:"85a1fd2e",525:"fa5f41ee",582:"274ce2ba",656:"850e57f5",667:"08c45434",710:"b66b2d70",787:"916927fb",817:"bbe7cbed",832:"858626ce",837:"eefd7ea4",861:"8af70598",918:"4f19350c",920:"524ee84a",962:"27c12fa7",963:"e7552f2c",971:"64431cee"}[e]+".js",d.miniCssF=e=>{},d.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),d.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},o="touchlab:",d.l=(e,t,r,f)=>{if(a[e])a[e].push(t);else{var n,c;if(void 0!==r)for(var i=document.getElementsByTagName("script"),b=0;b{n.onerror=n.onload=null,clearTimeout(s);var o=a[e];if(delete a[e],n.parentNode&&n.parentNode.removeChild(n),o&&o.forEach((e=>e(r))),t)return t(r)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:n}),12e4);n.onerror=u.bind(null,n.onerror),n.onload=u.bind(null,n.onload),c&&document.head.appendChild(n)}},d.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},d.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),d.p="/",d.gca=function(e){return e={17896441:"918",77037996:"463",f6d78023:"16","73b49f1e":"19","935f2afb":"53","58e6863e":"162",dc49a7e1:"165","6e9656ad":"198","1df93b7f":"237","6a4033d2":"299","2c56297f":"330","583db3ef":"363",efd0e1b0:"377","1be78505":"514","77cf246b":"582","599169ee":"656",f582e6b9:"667","1b8c0795":"710","6505a119":"787","14eb3368":"817","6f0769b5":"832",d6c23c28:"837","6c52285e":"861","1a4e3797":"920","018e43cb":"962",c377a04b:"971"}[e]||e,d.p+d.u(e)},(()=>{var e={303:0,532:0};d.f.j=(t,r)=>{var a=d.o(e,t)?e[t]:void 0;if(0!==a)if(a)r.push(a[2]);else if(/^(303|532)$/.test(t))e[t]=0;else{var o=new Promise(((r,o)=>a=e[t]=[r,o]));r.push(a[2]=o);var f=d.p+d.u(t),n=new Error;d.l(f,(r=>{if(d.o(e,t)&&(0!==(a=e[t])&&(e[t]=void 0),a)){var o=r&&("load"===r.type?"missing":r.type),f=r&&r.target&&r.target.src;n.message="Loading chunk "+t+" failed.\n("+o+": "+f+")",n.name="ChunkLoadError",n.type=o,n.request=f,a[1](n)}}),"chunk-"+t,t)}},d.O.j=t=>0===e[t];var t=(t,r)=>{var a,o,f=r[0],n=r[1],c=r[2],i=0;if(f.some((t=>0!==e[t]))){for(a in n)d.o(n,a)&&(d.m[a]=n[a]);if(c)var b=c(d)}for(t&&t(r);i{"use strict";var e,t,r,a,o,f={},n={};function c(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={id:e,loaded:!1,exports:{}};return f[e].call(r.exports,r,r.exports,c),r.loaded=!0,r.exports}c.m=f,e=[],c.O=(t,r,a,o)=>{if(!r){var f=1/0;for(i=0;i=o)&&Object.keys(c.O).every((e=>c.O[e](r[d])))?r.splice(d--,1):(n=!1,o0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[r,a,o]},c.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return c.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);c.r(o);var f={};t=t||[null,r({}),r([]),r(r)];for(var n=2&a&&e;"object"==typeof n&&!~t.indexOf(n);n=r(n))Object.getOwnPropertyNames(n).forEach((t=>f[t]=()=>e[t]));return f.default=()=>e,c.d(o,f),o},c.d=(e,t)=>{for(var r in t)c.o(t,r)&&!c.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((t,r)=>(c.f[r](e,t),t)),[])),c.u=e=>"assets/js/"+({16:"f6d78023",19:"73b49f1e",53:"935f2afb",162:"58e6863e",165:"dc49a7e1",198:"6e9656ad",237:"1df93b7f",299:"6a4033d2",330:"2c56297f",363:"583db3ef",377:"efd0e1b0",463:"77037996",514:"1be78505",582:"77cf246b",656:"599169ee",667:"f582e6b9",710:"1b8c0795",787:"6505a119",817:"14eb3368",832:"6f0769b5",837:"d6c23c28",861:"6c52285e",918:"17896441",920:"1a4e3797",962:"018e43cb",971:"c377a04b"}[e]||e)+"."+{16:"7c6c100e",19:"ed30c356",53:"6de8d6f5",162:"b6937826",165:"d35e5ea8",198:"7c3fea4b",204:"607a5b50",237:"cc1ca6fe",299:"35991a45",330:"73b8ef3c",347:"497f2026",363:"ef549bb5",377:"1031bc29",443:"4145d4a3",463:"e02d3ebf",514:"85a1fd2e",525:"fa5f41ee",582:"274ce2ba",656:"dc251485",667:"08c45434",710:"a1b1fb2a",787:"220bd22b",817:"bc29483f",832:"3bab0d40",837:"eefd7ea4",861:"a9dd1b20",918:"2d2e3b09",920:"524ee84a",962:"8ba55a2b",963:"e7552f2c",971:"4d3db33e"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},o="touchlab:",c.l=(e,t,r,f)=>{if(a[e])a[e].push(t);else{var n,d;if(void 0!==r)for(var b=document.getElementsByTagName("script"),i=0;i{n.onerror=n.onload=null,clearTimeout(s);var o=a[e];if(delete a[e],n.parentNode&&n.parentNode.removeChild(n),o&&o.forEach((e=>e(r))),t)return t(r)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:n}),12e4);n.onerror=u.bind(null,n.onerror),n.onload=u.bind(null,n.onload),d&&document.head.appendChild(n)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),c.p="/",c.gca=function(e){return e={17896441:"918",77037996:"463",f6d78023:"16","73b49f1e":"19","935f2afb":"53","58e6863e":"162",dc49a7e1:"165","6e9656ad":"198","1df93b7f":"237","6a4033d2":"299","2c56297f":"330","583db3ef":"363",efd0e1b0:"377","1be78505":"514","77cf246b":"582","599169ee":"656",f582e6b9:"667","1b8c0795":"710","6505a119":"787","14eb3368":"817","6f0769b5":"832",d6c23c28:"837","6c52285e":"861","1a4e3797":"920","018e43cb":"962",c377a04b:"971"}[e]||e,c.p+c.u(e)},(()=>{var e={303:0,532:0};c.f.j=(t,r)=>{var a=c.o(e,t)?e[t]:void 0;if(0!==a)if(a)r.push(a[2]);else if(/^(303|532)$/.test(t))e[t]=0;else{var o=new Promise(((r,o)=>a=e[t]=[r,o]));r.push(a[2]=o);var f=c.p+c.u(t),n=new Error;c.l(f,(r=>{if(c.o(e,t)&&(0!==(a=e[t])&&(e[t]=void 0),a)){var o=r&&("load"===r.type?"missing":r.type),f=r&&r.target&&r.target.src;n.message="Loading chunk "+t+" failed.\n("+o+": "+f+")",n.name="ChunkLoadError",n.type=o,n.request=f,a[1](n)}}),"chunk-"+t,t)}},c.O.j=t=>0===e[t];var t=(t,r)=>{var a,o,f=r[0],n=r[1],d=r[2],b=0;if(f.some((t=>0!==e[t]))){for(a in n)c.o(n,a)&&(c.m[a]=n[a]);if(d)var i=d(c)}for(t&&t(r);b - +
-

iOS Logging

There are three LogWriter implementations for iOS.

XcodeSeverityWriter

This is the default LogWriter. It is designed for local development. Each severity is represented with an emoji. Throwable instances sent to this writer will be written with println rather than oslog because oslog trims long strings.

2023-03-05 08:48:03.864138-0500 KermitSampleIOS[58575:7607179] 🟢 Try a log
2023-03-05 08:48:04.622452-0500 KermitSampleIOS[58575:7607442] [Bugsnag] [INFO] Sent session 7D3188F7-2B37-4189-9F92-63BC7172D01B
2023-03-05 08:48:09.999884-0500 KermitSampleIOS[58575:7607179] 🟢 Common click count: 1
2023-03-05 08:48:11.333941-0500 KermitSampleIOS[58575:7607179] 🔵 Common click count: 2
2023-03-05 08:48:13.104265-0500 KermitSampleIOS[58575:7607179] 🟡 Common click count: 3
2023-03-05 08:48:13.568351-0500 KermitSampleIOS[58575:7607179] 🔴 Common click count: 4

OSLogWriter

This is the parent class of XcodeSeverityWriter. There is no emoji added for severity, and Throwable is sent as a string to oslog. This may trim exceptions. You can implement a custom version that writes each line of a stack trace to oslog, or whatever else you'd like to do. Override logThrowable.

NSLogWriter

Legacy implementation using NSLog.

Touchlab KMP Insiders Newsletter

Subscribe
- +

iOS Logging

There are three LogWriter implementations for iOS.

XcodeSeverityWriter

This is the default LogWriter. It is designed for local development. Each severity is represented with an emoji. Throwable instances sent to this writer will be written with println rather than oslog because oslog trims long strings.

2023-03-05 08:48:03.864138-0500 KermitSampleIOS[58575:7607179] 🟢 Try a log
2023-03-05 08:48:04.622452-0500 KermitSampleIOS[58575:7607442] [Bugsnag] [INFO] Sent session 7D3188F7-2B37-4189-9F92-63BC7172D01B
2023-03-05 08:48:09.999884-0500 KermitSampleIOS[58575:7607179] 🟢 Common click count: 1
2023-03-05 08:48:11.333941-0500 KermitSampleIOS[58575:7607179] 🔵 Common click count: 2
2023-03-05 08:48:13.104265-0500 KermitSampleIOS[58575:7607179] 🟡 Common click count: 3
2023-03-05 08:48:13.568351-0500 KermitSampleIOS[58575:7607179] 🔴 Common click count: 4

OSLogWriter

This is the parent class of XcodeSeverityWriter. There is no emoji added for severity, and Throwable is sent as a string to oslog. This may trim exceptions. You can implement a custom version that writes each line of a stack trace to oslog, or whatever else you'd like to do. Override logThrowable.

NSLogWriter

Legacy implementation using NSLog.

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/TESTING/index.html b/docs/TESTING/index.html index f41dbdbe..9dd7ebbe 100644 --- a/docs/TESTING/index.html +++ b/docs/TESTING/index.html @@ -7,7 +7,7 @@ - + @@ -21,8 +21,8 @@ (global) static Logger as it will make testing easier.

Suppose you have a test

@OptIn(ExperimentalKermitApi::class)
class MyExampleTest {
private val testLogWriter = TestLogWriter(
loggable = Severity.Verbose // accept everything
)
private val kermit = Logger(
TestConfig(
minSeverity = Severity.Debug,
logWriterList = listOf(testLogWriter)
)
)

// ...
}

You can either interact with the latest log entry that was produced -

@Test
fun somethingInterestingHappened() {
// ...

testLogWriter.assertCount(1)

// calls assertTrue() on the result of the lambda
testLogWriter.assertLast {
message == "the message" && severity == Severity.Info && tag == "my-tag" && throwable == null
}
}

or you can interact with the list of log entries directly

@Test
fun somethingElseInterestingHappened() {
// ...

testLogWriter.assertCount(10)

with(testLogWriter.logs[3]) {
assertEquals("the message", message)
assertEquals(Severity.Info, severity)
assertEquals("my-tag", tag)
assertNull(throwable)
}
}

Logging on Android

The default setup of Kermit aims to make production logging as simple as possible. This means that the platform logger for Android defaults to passing the log through to Android's logcat Log() method. Be sure to configure your tests accordingly, as this wont function when running -unit tests on your local machine!

Touchlab KMP Insiders Newsletter

Subscribe
- +unit tests on your local machine!

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/category/technical-details/index.html b/docs/category/technical-details/index.html index 1945c7a4..52f00d81 100644 --- a/docs/category/technical-details/index.html +++ b/docs/category/technical-details/index.html @@ -7,13 +7,13 @@ - + - + + \ No newline at end of file diff --git a/docs/configuration/LOGGER_SETUP/index.html b/docs/configuration/LOGGER_SETUP/index.html index 7c1f2816..af5491e4 100644 --- a/docs/configuration/LOGGER_SETUP/index.html +++ b/docs/configuration/LOGGER_SETUP/index.html @@ -7,13 +7,13 @@ - +
-

Logger Setup

A Logger is just a class with a LoggerConfig instance and a default tag.

You can create your own instance of Logger, or configure and call the global Logger instance.

// Local
val log = Logger(
loggerConfigInit(platformLogWriter(NoTagLogFormatter)),
"MyTag"
)
log.i { "Hello Kotlin" }

// Global
Logger.setLogWriters(platformLogWriter(NoTagLogFormatter))
Logger.setTag("MyTag")
Logger.i { "Hello Kotlin" }

Which method you choose is up to you, but obviously a local log instance will need to be made available for you code to call, while global is available everywhere. For example, our pattern has been to inject loggers into components, with the tag applied at that point, rather than specify the tag in each call.

single { 
BreedCallbackViewModel(
get(),
getWith("BreedCallbackViewModel") // Convenience function to get a Logger with a tag set
)
}

LoggerConfig

LoggerConfig defines the minSeverity, below which log statements will be ignored, and logWriterList, the collection of LogWriter instances that will be written to.

interface LoggerConfig {
val minSeverity: Severity
val logWriterList: List<LogWriter>
}

When creating our own Logger instances above, we call loggerConfigInit. That is a convenience function to create a StaticConfig instance.

fun loggerConfigInit(vararg logWriters: LogWriter, minSeverity: Severity = DEFAULT_MIN_SEVERITY): LoggerConfig =
StaticConfig(logWriterList = logWriters.toList(), minSeverity = minSeverity)

Where to do config?

platformLogWriter() is an expect/actual factory function. You can call it in common code, and it will create a LogWriter designed for the platform the code is running on.

For more complex configuration, you'll either need platform-specific entry points, or possibly your own expect/actual factory function(s).

StaticConfig vs MutableLoggerConfig

For most use cases, once your logger is set up, you won't need to change the config. StaticConfig has values that can't be changed once initializd. That is what you want when creating a local Logger instance.

The global Logger uses MutableLoggerConfig, because values need to be changed after that instance has been initialized. It is also possible that you have a use case where the config of your local Logger instance needs to be changed after the instance is created. In that case, you can use MutableLoggerConfig instead of StaticConfig.

Why have StaticConfig at all?

Logger instances are thread-safe, so MutableLoggerConfig needs to be thread-safe. That means config fields are volatile on the JVM and Atomic on native platforms. While the performance impact is likely negligable, if you want to maximize performance, static is better.

If you really like global access, but want static config, you can just create your own global logger.

object MyLogger : Logger(
config = loggerConfigInit(
platformLogWriter(NoTagLogFormatter),
minSeverity = Severity.Info
),
tag = "MyAppTag"
)

fun hello(){
MyLogger.i { "Hello" }
}

Touchlab KMP Insiders Newsletter

Subscribe
- +

Logger Setup

A Logger is just a class with a LoggerConfig instance and a default tag.

You can create your own instance of Logger, or configure and call the global Logger instance.

// Local
val log = Logger(
loggerConfigInit(platformLogWriter(NoTagLogFormatter)),
"MyTag"
)
log.i { "Hello Kotlin" }

// Global
Logger.setLogWriters(platformLogWriter(NoTagLogFormatter))
Logger.setTag("MyTag")
Logger.i { "Hello Kotlin" }

Which method you choose is up to you, but obviously a local log instance will need to be made available for you code to call, while global is available everywhere. For example, our pattern has been to inject loggers into components, with the tag applied at that point, rather than specify the tag in each call.

single { 
BreedCallbackViewModel(
get(),
getWith("BreedCallbackViewModel") // Convenience function to get a Logger with a tag set
)
}

LoggerConfig

LoggerConfig defines the minSeverity, below which log statements will be ignored, and logWriterList, the collection of LogWriter instances that will be written to.

interface LoggerConfig {
val minSeverity: Severity
val logWriterList: List<LogWriter>
}

When creating our own Logger instances above, we call loggerConfigInit. That is a convenience function to create a StaticConfig instance.

fun loggerConfigInit(vararg logWriters: LogWriter, minSeverity: Severity = DEFAULT_MIN_SEVERITY): LoggerConfig =
StaticConfig(logWriterList = logWriters.toList(), minSeverity = minSeverity)

Where to do config?

platformLogWriter() is an expect/actual factory function. You can call it in common code, and it will create a LogWriter designed for the platform the code is running on.

For more complex configuration, you'll either need platform-specific entry points, or possibly your own expect/actual factory function(s).

StaticConfig vs MutableLoggerConfig

For most use cases, once your logger is set up, you won't need to change the config. StaticConfig has values that can't be changed once initializd. That is what you want when creating a local Logger instance.

The global Logger uses MutableLoggerConfig, because values need to be changed after that instance has been initialized. It is also possible that you have a use case where the config of your local Logger instance needs to be changed after the instance is created. In that case, you can use MutableLoggerConfig instead of StaticConfig.

Why have StaticConfig at all?

Logger instances are thread-safe, so MutableLoggerConfig needs to be thread-safe. That means config fields are volatile on the JVM and Atomic on native platforms. While the performance impact is likely negligable, if you want to maximize performance, static is better.

If you really like global access, but want static config, you can just create your own global logger.

object MyLogger : Logger(
config = loggerConfigInit(
platformLogWriter(NoTagLogFormatter),
minSeverity = Severity.Info
),
tag = "MyAppTag"
)

fun hello(){
MyLogger.i { "Hello" }
}

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/configuration/MESSAGE_FORMATTING/index.html b/docs/configuration/MESSAGE_FORMATTING/index.html index d93cafb6..58f5c184 100644 --- a/docs/configuration/MESSAGE_FORMATTING/index.html +++ b/docs/configuration/MESSAGE_FORMATTING/index.html @@ -7,13 +7,13 @@ - +
-

Message Formatting

To make message formatting more uniform and flexible, many of the LogWriter instances can take a MessageStringFormatter parameter. This allows you to control how log messages are presented and apply common formatting.

TL;DR

If you don't want tags to be printed in your iOS or JS log statements, give your LogWriter instances NoTagFormatter. This will suppress printing tag in log message strings. Tag will still be sent to Android log messages.

For the global Logger and the platform LogWriter, config would look like the following:

Logger.setLogWriters(platformLogWriter(NoTagFormatter))

For most use cases, this is all you need to know about formatters. The rest of this doc explains them in more detail.

Log Message Components

There are 3 parts to a message: Severity, Tag, and the Message itself. All loggers accept a log message string, but support for severity and tag vary between systems. Here is a breakdown of support for a few commonly used logging systems.

SystemSeverityTag
Android
OSLog (iOS)
JS-Console
SystemWriter (jvm)
Common (println)

The main purpose of MessageStringFormatter is to manage situations where the logging system does not support either Severity or Tag. The LogWriter instance will pass null's to the MessageStringFormatter in cases where the LogWriter natively supports Severity or Tag.

For example, the DefaultLogFormatter will result in the following message strings depending on platform:

// Log call
Logger.w(tag = "ATag") { "A Log Message" }

// Android
// 'A Log Message'

// OSLog
// '(ATag) A Log Message'

// Common
// 'Warn: (ATag) A Log Message'
info

You can use MessageStringFormatter to implement custom message strings. Maybe, say, add a special date format to each line. However, Kermit uses them to manage Severity and Tag for systems that don't natively support those constructs. Note: the Android LogcatWriter does not currently use a MessageStringFormatter. You would need to create a custom implementation to support that.

Implementations

Kermit provides a few implementations out of the box.

DefaultLogFormatter

This is the standard format that all compatible LogWriter instances get by default. Messages are formatted as in the examples above.

NoTagFormatter

Tags are really an Android convention. Other platforms can feel cluttered with them. You can simply ignore them with NoTagFormatter. Logging will function the same for Android, and other platforms will ignore the Tag.

SimpleLogFormatter

This formatter skips tags and severity. It just prints the message.

Configuration

To simplify setting platform LogWriter instances, you can pass a MessageStringFormatter to platformLogWriter.

platformLogWriter(NoTagLogFormatter)

Touchlab KMP Insiders Newsletter

Subscribe
- +

Message Formatting

To make message formatting more uniform and flexible, many of the LogWriter instances can take a MessageStringFormatter parameter. This allows you to control how log messages are presented and apply common formatting.

TL;DR

If you don't want tags to be printed in your iOS or JS log statements, give your LogWriter instances NoTagFormatter. This will suppress printing tag in log message strings. Tag will still be sent to Android log messages.

For the global Logger and the platform LogWriter, config would look like the following:

Logger.setLogWriters(platformLogWriter(NoTagFormatter))

For most use cases, this is all you need to know about formatters. The rest of this doc explains them in more detail.

Log Message Components

There are 3 parts to a message: Severity, Tag, and the Message itself. All loggers accept a log message string, but support for severity and tag vary between systems. Here is a breakdown of support for a few commonly used logging systems.

SystemSeverityTag
Android
OSLog (iOS)
JS-Console
SystemWriter (jvm)
Common (println)

The main purpose of MessageStringFormatter is to manage situations where the logging system does not support either Severity or Tag. The LogWriter instance will pass null's to the MessageStringFormatter in cases where the LogWriter natively supports Severity or Tag.

For example, the DefaultLogFormatter will result in the following message strings depending on platform:

// Log call
Logger.w(tag = "ATag") { "A Log Message" }

// Android
// 'A Log Message'

// OSLog
// '(ATag) A Log Message'

// Common
// 'Warn: (ATag) A Log Message'
info

You can use MessageStringFormatter to implement custom message strings. Maybe, say, add a special date format to each line. However, Kermit uses them to manage Severity and Tag for systems that don't natively support those constructs. Note: the Android LogcatWriter does not currently use a MessageStringFormatter. You would need to create a custom implementation to support that.

Implementations

Kermit provides a few implementations out of the box.

DefaultLogFormatter

This is the standard format that all compatible LogWriter instances get by default. Messages are formatted as in the examples above.

NoTagFormatter

Tags are really an Android convention. Other platforms can feel cluttered with them. You can simply ignore them with NoTagFormatter. Logging will function the same for Android, and other platforms will ignore the Tag.

SimpleLogFormatter

This formatter skips tags and severity. It just prints the message.

Configuration

To simplify setting platform LogWriter instances, you can pass a MessageStringFormatter to platformLogWriter.

platformLogWriter(NoTagLogFormatter)

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/configuration/NON_KOTLIN/index.html b/docs/configuration/NON_KOTLIN/index.html index 12305349..7a46aa61 100644 --- a/docs/configuration/NON_KOTLIN/index.html +++ b/docs/configuration/NON_KOTLIN/index.html @@ -7,13 +7,13 @@ - +
-

Non-Kotlin Environments

You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose.

Earlier versions of Kermit were designed to be Swift-friendly, but that sacrificed the Kotlin-friendly API, and since the primary use-case is calling Kermit from Kotlin, that seemed like a bad compromise.

We've added a module called kermit-simple which adds explicit call signatures to the API, to provide for the cases where default parameters make more sense in a Kotlin context.

kotlin {
sourceSets {
val commonMain by getting {
dependencies {
// etc
implementation("co.touchlab:kermit:2.0.3")
}
}

val iosMain by getting {
dependencies {
// etc
api("co.touchlab:kermit-simple:2.0.3")
}
}
}

cocoapods {
framework {
export("co.touchlab:kermit-simple:2.0.3")
}
}
}

You will need to export kermit-simple, as in the example above.

From Swift, this will allow you to call methods without all of the parameters explicitly added.

let log = // Get a Logger instance
log.i(messageString: "Try a log")
log.w(messageString: "Throw", throwable: someException)

Touchlab KMP Insiders Newsletter

Subscribe
- +

Non-Kotlin Environments

You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose.

Earlier versions of Kermit were designed to be Swift-friendly, but that sacrificed the Kotlin-friendly API, and since the primary use-case is calling Kermit from Kotlin, that seemed like a bad compromise.

We've added a module called kermit-simple which adds explicit call signatures to the API, to provide for the cases where default parameters make more sense in a Kotlin context.

kotlin {
sourceSets {
val commonMain by getting {
dependencies {
// etc
implementation("co.touchlab:kermit:2.0.3")
}
}

val iosMain by getting {
dependencies {
// etc
api("co.touchlab:kermit-simple:2.0.3")
}
}
}

cocoapods {
framework {
export("co.touchlab:kermit-simple:2.0.3")
}
}
}

You will need to export kermit-simple, as in the example above.

From Swift, this will allow you to call methods without all of the parameters explicitly added.

let log = // Get a Logger instance
log.i(messageString: "Try a log")
log.w(messageString: "Throw", throwable: someException)

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/configuration/index.html b/docs/configuration/index.html index 068d9681..bf3b828e 100644 --- a/docs/configuration/index.html +++ b/docs/configuration/index.html @@ -7,13 +7,13 @@ - +
-

Configuration

Logger Setup

Logger setup includes various topics, including static vs mutable, and adding non-default LogWriter instances.

Message Formatting

LogWriter instances sometimes need to include tag or severity in the log message string. You may also want to add some custom info to the message strings. MessageStringFormatter allows for central formatting configuration.

Non-Kotlin Environments

Kermit's API is designed to be Kotlin-friendly. That includes methods with default parameters. To call Kermit from other environments, for example Swift, you'll probably want to add and export kermit-simple.

Touchlab KMP Insiders Newsletter

Subscribe
- +

Configuration

Logger Setup

Logger setup includes various topics, including static vs mutable, and adding non-default LogWriter instances.

Message Formatting

LogWriter instances sometimes need to include tag or severity in the log message string. You may also want to add some custom info to the message strings. MessageStringFormatter allows for central formatting configuration.

Non-Kotlin Environments

Kermit's API is designed to be Kotlin-friendly. That includes methods with default parameters. To call Kermit from other environments, for example Swift, you'll probably want to add and export kermit-simple.

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/crashreporting/BUGSNAG/index.html b/docs/crashreporting/BUGSNAG/index.html index 4f9253d7..4de0a33a 100644 --- a/docs/crashreporting/BUGSNAG/index.html +++ b/docs/crashreporting/BUGSNAG/index.html @@ -7,13 +7,13 @@ - +
-

Bugsnag

Setup

You first need to configure Bugsnag and CrashKiOS initialization. See the CrashKiOS Bugsnag Tutorial Doc.

Add the dependency

commonMain {
dependencies {
implementation("co.touchlab:kermit-bugsnag:2.0.3")
}
}

Add the log writer

Logger.setLogWriters(BugsnagLogWriter())

Custom Values

You can add custom values to Bugsnag, but not through Kermit. Call CrashKiOS directly.

BugsnagKotlin.setCustomValue("someKey", "someValue")

Touchlab KMP Insiders Newsletter

Subscribe
- +

Bugsnag

Setup

You first need to configure Bugsnag and CrashKiOS initialization. See the CrashKiOS Bugsnag Tutorial Doc.

Add the dependency

commonMain {
dependencies {
implementation("co.touchlab:kermit-bugsnag:2.0.3")
}
}

Add the log writer

Logger.setLogWriters(BugsnagLogWriter())

Custom Values

You can add custom values to Bugsnag, but not through Kermit. Call CrashKiOS directly.

BugsnagKotlin.setCustomValue("someKey", "someValue")

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/crashreporting/CRASHLYTICS/index.html b/docs/crashreporting/CRASHLYTICS/index.html index f35685c7..7825b2bd 100644 --- a/docs/crashreporting/CRASHLYTICS/index.html +++ b/docs/crashreporting/CRASHLYTICS/index.html @@ -7,13 +7,13 @@ - +
-

Crashlytics

Setup

You first need to configure Crashlytics and CrashKiOS initialization. See the CrashKiOS Crashlytics Tutorial Doc.

Add the dependency

commonMain {
dependencies {
implementation("co.touchlab:kermit-crashlytics:2.0.3")
}
}

Add the log writer

Logger.setLogWriters(CrashlyticsLogWriter())

Custom Values

You can add custom values to Crashlytics, but not through Kermit. Call CrashKiOS directly.

CrashlyticsKotlin.setCustomValue("someKey", "someValue")

Touchlab KMP Insiders Newsletter

Subscribe
- +

Crashlytics

Setup

You first need to configure Crashlytics and CrashKiOS initialization. See the CrashKiOS Crashlytics Tutorial Doc.

Add the dependency

commonMain {
dependencies {
implementation("co.touchlab:kermit-crashlytics:2.0.3")
}
}

Add the log writer

Logger.setLogWriters(CrashlyticsLogWriter())

Custom Values

You can add custom values to Crashlytics, but not through Kermit. Call CrashKiOS directly.

CrashlyticsKotlin.setCustomValue("someKey", "someValue")

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/crashreporting/index.html b/docs/crashreporting/index.html index 198e7d52..b49411d5 100644 --- a/docs/crashreporting/index.html +++ b/docs/crashreporting/index.html @@ -7,13 +7,13 @@ - +
-

Crash Reporting

Crash reporting is primarily handled with CrashKiOS. Kermit provides LogWriter instances to write breadcrumb/log statements to the crash reporting tools, and sending soft "handled" exceptions when Throwable instances are logged, based on configuration.

info

Earlier versions of Kermit implemented crash reporting directly, but logging and crash reporting are really different domains. Crash reporting support was moved back into CrashKiOS, and Kermit simply provides a logging interface into those tools.

Kermit and CrashKiOS currently support Firebase Crashlytics and Bugsnag.

Crashlytics

See Crashlytics Setup

Bugsnag

See Bugsnag Setup

Configuring crash log writers

Both crash LogWriter implementations take 3 parameters:

minSeverity: Severity

This is the minimum severity that will be logged to the crash reporter's breadcrumb cache. The default severity is Info. That means Debug and Verbose statements will be ignored.

minCrashSeverity: Severity?

All log statements can take a Throwable. If you send a Throwable to a crash LogWriter, if the log statement itself is equal to or above minCrashSeverity, the Throwable will be sent as a soft/handled exception.

The default value is Warn, so all log statements with a Throwable, with log severity of Warn or higher, will create an exception report.

To disable sending exception reports, pass null.

messageStringFormatter: MessageStringFormatter

See Message Formatting for details of how to format log message strings. DefaultFormatter is the default value.

Touchlab KMP Insiders Newsletter

Subscribe
- +

Crash Reporting

Crash reporting is primarily handled with CrashKiOS. Kermit provides LogWriter instances to write breadcrumb/log statements to the crash reporting tools, and sending soft "handled" exceptions when Throwable instances are logged, based on configuration.

info

Earlier versions of Kermit implemented crash reporting directly, but logging and crash reporting are really different domains. Crash reporting support was moved back into CrashKiOS, and Kermit simply provides a logging interface into those tools.

Kermit and CrashKiOS currently support Firebase Crashlytics and Bugsnag.

Crashlytics

See Crashlytics Setup

Bugsnag

See Bugsnag Setup

Configuring crash log writers

Both crash LogWriter implementations take 3 parameters:

minSeverity: Severity

This is the minimum severity that will be logged to the crash reporter's breadcrumb cache. The default severity is Info. That means Debug and Verbose statements will be ignored.

minCrashSeverity: Severity?

All log statements can take a Throwable. If you send a Throwable to a crash LogWriter, if the log statement itself is equal to or above minCrashSeverity, the Throwable will be sent as a soft/handled exception.

The default value is Warn, so all log statements with a Throwable, with log severity of Warn or higher, will create an exception report.

To disable sending exception reports, pass null.

messageStringFormatter: MessageStringFormatter

See Message Formatting for details of how to format log message strings. DefaultFormatter is the default value.

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/details/CUSTOM_API/index.html b/docs/details/CUSTOM_API/index.html index 393bbec5..9a9dda3b 100644 --- a/docs/details/CUSTOM_API/index.html +++ b/docs/details/CUSTOM_API/index.html @@ -7,13 +7,13 @@ - +
-

Custom Logger API

The main module most users will include is kermit. However, much of the configuration and other underlying functionality has been moved to kermit-core. The main kermit module is a relatively thin API layer that sits on top of kermit-core.

Over the past few years, we've had feedback about the API design choices made in Kermit. Some of that feedback makes sense and has been incorporated. Other feedback is really just personal preference, and would conflict with the existing design.

Rather than trying to make everybody happy, we've structured Kermit's modules so you can create your own API interface on top of the underlying kermit-core module. That will allow you to use compatible extensions like Crashlytics and Bugsnag, but interface with the underlying Kermit system with whatever API you prefer.

For example, if you wanted a very simple logger with only two methods, you would make kermit-core a dependency rather than kermit, and write your own implementation:

object MyLogger : BaseLogger(loggerConfigInit(platformLogWriter())) {
fun info(message: String){
log(Severity.Info, "MyLogger", null, message)
}

fun error(message: String, throwable: Throwable){
log(Severity.Error, "MyLogger", throwable, message)
}
}

For a more complex example, see the implementation of co.touchlab.kermit.Logger in kermit.

Touchlab KMP Insiders Newsletter

Subscribe
- +

Custom Logger API

The main module most users will include is kermit. However, much of the configuration and other underlying functionality has been moved to kermit-core. The main kermit module is a relatively thin API layer that sits on top of kermit-core.

Over the past few years, we've had feedback about the API design choices made in Kermit. Some of that feedback makes sense and has been incorporated. Other feedback is really just personal preference, and would conflict with the existing design.

Rather than trying to make everybody happy, we've structured Kermit's modules so you can create your own API interface on top of the underlying kermit-core module. That will allow you to use compatible extensions like Crashlytics and Bugsnag, but interface with the underlying Kermit system with whatever API you prefer.

For example, if you wanted a very simple logger with only two methods, you would make kermit-core a dependency rather than kermit, and write your own implementation:

object MyLogger : BaseLogger(loggerConfigInit(platformLogWriter())) {
fun info(message: String){
log(Severity.Info, "MyLogger", null, message)
}

fun error(message: String, throwable: Throwable){
log(Severity.Error, "MyLogger", throwable, message)
}
}

For a more complex example, see the implementation of co.touchlab.kermit.Logger in kermit.

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/details/LOG_WRITER/index.html b/docs/details/LOG_WRITER/index.html index 69b995d5..586ce3f8 100644 --- a/docs/details/LOG_WRITER/index.html +++ b/docs/details/LOG_WRITER/index.html @@ -7,13 +7,13 @@ - +
-

LogWriter

LogWriter takes care of deciding where to log the messages.

Prebuilt LogWriters

By default Kermit provides default LogWriter for each platform

  • CommonWriter - Uses println to send logs in Kotlin
  • LogcatWriter - Uses LogCat to send logs in Android
  • OSLogWriter - Uses os log to send logs in iOS
  • ConsoleWriter - Uses console to log in JS

These can be created and passed into the Logger object during initialization

Logger.setLogWriters(listOf(LogcatWriter(), CommonWriter()))

Selecting loggers for each platform can either be done with platform-specific entry points, or using an expect/actual factory function.

Kermit ships with a default factory function that provides a LogWriter suited to local development.

package co.touchlab.kermit

expect fun platformLogWriter(messageStringFormatter: MessageStringFormatter = DefaultFormatter): LogWriter

You can implement a factory function for your project similar to the one above.

Custom LogWriter

If you want to have a custom implementation to send logs to your own server, or a 3rd party tool or simply because default implementation doesn't fit your need, then you would need to extend the LogWriter class and provide your own instance.

For a simple LogWriter you only need to implement the log method, which handles all log messages.

Simple implementation would look like below,

class YourCustomWriter : LogWriter() {
override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
// Handle logging here
}
}

Custom loggers may also override isLoggable. Kermit will check this value before logging to this LogWriter.

open fun isLoggable(tag: String, severity: Severity): Boolean = true

If your custom logger should only send messages in production, the implementation could look like the following:

// LogWriter
class YourCustomWriter(private val isProduction:Boolean) : LogWriter() {
override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
// Do something custom
}

override fun isLoggable(tag: String, severity: Severity): Boolean = isProduction
}

// Usage
val logWriter = YourCustomWriter(someProdFlag)
val logger = Logger(loggerConfigInit(logWriter))

Touchlab KMP Insiders Newsletter

Subscribe
- +

LogWriter

LogWriter takes care of deciding where to log the messages.

Prebuilt LogWriters

By default Kermit provides default LogWriter for each platform

  • CommonWriter - Uses println to send logs in Kotlin
  • LogcatWriter - Uses LogCat to send logs in Android
  • OSLogWriter - Uses os log to send logs in iOS
  • ConsoleWriter - Uses console to log in JS

These can be created and passed into the Logger object during initialization

Logger.setLogWriters(listOf(LogcatWriter(), CommonWriter()))

Selecting loggers for each platform can either be done with platform-specific entry points, or using an expect/actual factory function.

Kermit ships with a default factory function that provides a LogWriter suited to local development.

package co.touchlab.kermit

expect fun platformLogWriter(messageStringFormatter: MessageStringFormatter = DefaultFormatter): LogWriter

You can implement a factory function for your project similar to the one above.

Custom LogWriter

If you want to have a custom implementation to send logs to your own server, or a 3rd party tool or simply because default implementation doesn't fit your need, then you would need to extend the LogWriter class and provide your own instance.

For a simple LogWriter you only need to implement the log method, which handles all log messages.

Simple implementation would look like below,

class YourCustomWriter : LogWriter() {
override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
// Handle logging here
}
}

Custom loggers may also override isLoggable. Kermit will check this value before logging to this LogWriter.

open fun isLoggable(tag: String, severity: Severity): Boolean = true

If your custom logger should only send messages in production, the implementation could look like the following:

// LogWriter
class YourCustomWriter(private val isProduction:Boolean) : LogWriter() {
override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
// Do something custom
}

override fun isLoggable(tag: String, severity: Severity): Boolean = isProduction
}

// Usage
val logWriter = YourCustomWriter(someProdFlag)
val logger = Logger(loggerConfigInit(logWriter))

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/extensions/KOIN/index.html b/docs/extensions/KOIN/index.html index 93eb4c33..7bdf4d4c 100644 --- a/docs/extensions/KOIN/index.html +++ b/docs/extensions/KOIN/index.html @@ -7,7 +7,7 @@ - + @@ -20,8 +20,8 @@ unit tests!

Dependency Injection Helpers

The kermitLoggerModule() method returns a Koin module that declares a factory for logger instances. If you don't want to make use of the Koin factory, there's a getLoggerWithTag() extension method you can call directly.

We prefer injecting logger instances rather than using the global Logger instance, especially when -we know we'll be unit testing a section of code.

Touchlab KMP Insiders Newsletter

Subscribe
- +we know we'll be unit testing a section of code.

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/extensions/index.html b/docs/extensions/index.html index da58bda4..202c90b8 100644 --- a/docs/extensions/index.html +++ b/docs/extensions/index.html @@ -7,13 +7,13 @@ - +
-

Extensions

Crashlytics

Crashlytics log statement writing.

Bugsnag

Bugsnag breadcrumb writing.

Koin

Integration with Koin, for easy logger injection.

Touchlab KMP Insiders Newsletter

Subscribe
- +

Extensions

Crashlytics

Crashlytics log statement writing.

Bugsnag

Bugsnag breadcrumb writing.

Koin

Integration with Koin, for easy logger injection.

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 7f955ec9..4a9df3e8 100644 --- a/docs/index.html +++ b/docs/index.html @@ -7,15 +7,15 @@ - +

Kermit the log

Kermit is a Kotlin Multiplatform logging library.

It's primary purpose is to allow log statements from Kotlin code to be written to composable log outputs. Out of the box, the library defaults to platform-specific loggers such as Logcat and OSLog, but is easy to extend and configure.

tip

Check out KaMP Kit to get started developing for Kotlin Multiplatform

Getting Started

Configuration for different environments can get more complex, but the default config out of the box is fairly simple.

1. Add Dependency

The Kermit dependency should be added to your commonMain source set in your Kotlin Multiplatform module.

commonMain {
dependencies {
...
implementation("co.touchlab:kermit:2.0.3") //Add latest version
}
}

2. Log

Logger.i { "Hello World" }

Default LogWriter

By default, Kermit includes a LogWriter instance for each platform that is configured for development.

On Android it writes to Logcat, on iOS it writes to OSLog, and for JS it writes to console.

Basic Concepts

The basic components you'll need to be aware of are Logger, LogWriter, and Severity.

Logger

The Logger takes log calls from your code and dispatches them to LogWriter instances. There are different methods on Logger corresponding to different log Severity levels. In order of least to most severe: v(), d(), i(), w(), e(), and a().

You configure the Logger, then call log methods on it. That's the basic interaction with Kermit.

Logger.i { "Hello World" }

try {
somethingRisky()
}
catch(t: Throwable){
Logger.w(t) { "That could've gone better" }
}

LogWriter

A LogWriter actually sends log messages to different log outputs. You add LogWriter instances to a Logger.

Kermit includes a CommonWriter and various platform-specific LogWriter instances. Through other modules, Kermit also allows logging crash info to Crashlytics and Bugsnag.

For more info on included LogWriter types, and to create your own, see LOG_WRITER

Severity

Severity levels follow common logging library patterns and should be generally familiar. You can control what will and won't get logged based on severity. So, say you only want to log Warn and up, you can tell the logger. We'll cover that more in Configuration

Usage

The primary logging artifact is Logger. It defines the severity-level logging methods. It has a Kotlin-aware api relying on default parameters and lambda syntax.

info

To log from non-Kotlin clients, that don't support calling Kotlin's default parameters, see NON_KOTLIN. A common use case would be calling Kermit from Swift or JS.

For each severity, there are two methods. One takes a String log message directly, the other takes a function parameter that returns a string. The function is only evaluated if the log will be written. Which you use is personal preference. They both will log to the same places, but the function parameter version may avoid unecessary String creation and evaluation.

Here are what the w method definitions look like:

// Trailing function parameter
fun w(throwable: Throwable? = null, tag: String = this.tag, message: () -> String)

// String message parameter
fun w(messageString: String, throwable: Throwable? = null, tag: String = this.tag)
info

The function parameter is at the end of the function to support Kotlin's trailing lambda syntax.

In its most basic form, logging looks like this:

Logger.i { "Hello World" }

Some other examples with tags and Throwable params.

Logger.w("MyTag") { "Hello World $someData" }
// etc
Logger.e(ex) { "Something failed" }
// or
Logger.e("Something failed", ex)

A Note About Tags

Tags are much more common on Android, as Logcat has tag arguments, and it is the default logger on Android. It would be difficult to have a Kotlin Multiplatform library without them, but they don't really fit into other platforms as easily.

Kermit's default tag is an empty string. You can supply a tag param to each log call, change the base default tag, or create a Logger instance with it's own tag. For example, create a field in a ViewModel with the tag set to the class name (a common Android pattern):

class MyViewModel:ViewModel {
private val log = Logger.withTag("MyViewModel")
}

Platform-specific loggers can be configured to ignore tags on output, or you can customize their display easily. We'll discuss these options more in Configuration.

Deprecated Gradle properties

Per the official Kotlin documentation we took the opportunity -with the Kermit 2.0 release to remove deprecated gradle.properties values. We encourage you to do the same!

Touchlab KMP Insiders Newsletter

Subscribe
- +with the Kermit 2.0 release to remove deprecated gradle.properties values. We encourage you to do the same!

Touchlab KMP Insiders Newsletter

Subscribe
+ \ No newline at end of file diff --git a/index.html b/index.html index 46dc0b17..22f05a24 100644 --- a/index.html +++ b/index.html @@ -7,13 +7,13 @@ - +
About

Kermit - Kotlin Multiplatform Logging

Kermit The Log

Shared-code logging with platform-specific log writers

Log once, write anywhere

Dev Logging

Smart defaults log locally for development

Production-Ready

Disable local logging for production, or even strip log statements altogether with a compiler plugin

Crash Reporting

Integrate logging with popular crash reporting libraries

- + \ No newline at end of file diff --git a/search-index.json b/search-index.json index 2be6aeeb..1f9e4614 100644 --- a/search-index.json +++ b/search-index.json @@ -1 +1 @@ -[{"documents":[{"i":1,"t":"Kermit the log","u":"/docs/","b":["Docs"]},{"i":25,"t":"Configuration","u":"/docs/configuration/","b":["Docs","Configuration"]},{"i":32,"t":"Logger Setup","u":"/docs/configuration/LOGGER_SETUP","b":["Docs","Configuration"]},{"i":40,"t":"Message Formatting","u":"/docs/configuration/MESSAGE_FORMATTING","b":["Docs","Configuration"]},{"i":54,"t":"Non-Kotlin Environments","u":"/docs/configuration/NON_KOTLIN","b":["Docs","Configuration"]},{"i":56,"t":"Crash Reporting","u":"/docs/crashreporting/","b":["Docs","Crash Reporting"]},{"i":70,"t":"Bugsnag","u":"/docs/crashreporting/BUGSNAG","b":["Docs","Crash Reporting"]},{"i":79,"t":"Crashlytics","u":"/docs/crashreporting/CRASHLYTICS","b":["Docs","Crash Reporting"]},{"i":88,"t":"Custom Logger API","u":"/docs/details/CUSTOM_API","b":["Docs","Technical Details"]},{"i":90,"t":"Extensions","u":"/docs/extensions/","b":["Docs","Extensions"]},{"i":97,"t":"LogWriter","u":"/docs/details/LOG_WRITER","b":["Docs","Technical Details"]},{"i":103,"t":"iOS Logging","u":"/docs/IOS_LOGGING","b":["Docs"]},{"i":111,"t":"Koin Integration","u":"/docs/extensions/KOIN","b":["Docs","Extensions"]},{"i":120,"t":"Testing","u":"/docs/TESTING","b":["Docs"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[0,2.156,1,1.677]],["t/25",[2,2.776]],["t/32",[3,1.677,4,2.156]],["t/40",[5,2.156,6,2.156]],["t/54",[7,1.762,8,1.762,9,1.762]],["t/56",[10,2.156,11,2.156]],["t/70",[12,2.776]],["t/79",[13,2.776]],["t/88",[3,1.371,14,1.762,15,1.762]],["t/90",[16,2.776]],["t/97",[17,2.776]],["t/103",[1,1.677,18,2.156]],["t/111",[19,2.156,20,2.156]],["t/120",[21,2.776]]],"invertedIndex":[["api",{"_index":15,"t":{"88":{"position":[[14,3]]}}}],["bugsnag",{"_index":12,"t":{"70":{"position":[[0,7]]}}}],["configur",{"_index":2,"t":{"25":{"position":[[0,13]]}}}],["crash",{"_index":10,"t":{"56":{"position":[[0,5]]}}}],["crashlyt",{"_index":13,"t":{"79":{"position":[[0,11]]}}}],["custom",{"_index":14,"t":{"88":{"position":[[0,6]]}}}],["environ",{"_index":9,"t":{"54":{"position":[[11,12]]}}}],["extens",{"_index":16,"t":{"90":{"position":[[0,10]]}}}],["format",{"_index":6,"t":{"40":{"position":[[8,10]]}}}],["integr",{"_index":20,"t":{"111":{"position":[[5,11]]}}}],["io",{"_index":18,"t":{"103":{"position":[[0,3]]}}}],["kermit",{"_index":0,"t":{"1":{"position":[[0,6]]}}}],["koin",{"_index":19,"t":{"111":{"position":[[0,4]]}}}],["kotlin",{"_index":8,"t":{"54":{"position":[[4,6]]}}}],["log",{"_index":1,"t":{"1":{"position":[[11,3]]},"103":{"position":[[4,7]]}}}],["logger",{"_index":3,"t":{"32":{"position":[[0,6]]},"88":{"position":[[7,6]]}}}],["logwrit",{"_index":17,"t":{"97":{"position":[[0,9]]}}}],["messag",{"_index":5,"t":{"40":{"position":[[0,7]]}}}],["non",{"_index":7,"t":{"54":{"position":[[0,3]]}}}],["report",{"_index":11,"t":{"56":{"position":[[6,9]]}}}],["setup",{"_index":4,"t":{"32":{"position":[[7,5]]}}}],["test",{"_index":21,"t":{"120":{"position":[[0,7]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":3,"t":"Getting Started","u":"/docs/","h":"#getting-started","p":1},{"i":5,"t":"1. Add Dependency","u":"/docs/","h":"#1-add-dependency","p":1},{"i":7,"t":"2. Log","u":"/docs/","h":"#2-log","p":1},{"i":9,"t":"Default LogWriter","u":"/docs/","h":"#default-logwriter","p":1},{"i":11,"t":"Basic Concepts","u":"/docs/","h":"#basic-concepts","p":1},{"i":13,"t":"Logger","u":"/docs/","h":"#logger","p":1},{"i":15,"t":"LogWriter","u":"/docs/","h":"#logwriter","p":1},{"i":17,"t":"Severity","u":"/docs/","h":"#severity","p":1},{"i":19,"t":"Usage","u":"/docs/","h":"#usage","p":1},{"i":21,"t":"A Note About Tags","u":"/docs/","h":"#a-note-about-tags","p":1},{"i":23,"t":"Deprecated Gradle properties","u":"/docs/","h":"#deprecated-gradle-properties","p":1},{"i":26,"t":"Logger Setup","u":"/docs/configuration/","h":"#logger-setup","p":25},{"i":28,"t":"Message Formatting","u":"/docs/configuration/","h":"#message-formatting","p":25},{"i":30,"t":"Non-Kotlin Environments","u":"/docs/configuration/","h":"#non-kotlin-environments","p":25},{"i":34,"t":"LoggerConfig","u":"/docs/configuration/LOGGER_SETUP","h":"#loggerconfig","p":32},{"i":36,"t":"Where to do config?","u":"/docs/configuration/LOGGER_SETUP","h":"#where-to-do-config","p":32},{"i":38,"t":"StaticConfig vs MutableLoggerConfig","u":"/docs/configuration/LOGGER_SETUP","h":"#staticconfig-vs-mutableloggerconfig","p":32},{"i":42,"t":"Log Message Components","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#log-message-components","p":40},{"i":44,"t":"Implementations","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#implementations","p":40},{"i":46,"t":"DefaultLogFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#defaultlogformatter","p":40},{"i":48,"t":"NoTagFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#notagformatter","p":40},{"i":50,"t":"SimpleLogFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#simplelogformatter","p":40},{"i":52,"t":"Configuration","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#configuration","p":40},{"i":58,"t":"Crashlytics","u":"/docs/crashreporting/","h":"#crashlytics","p":56},{"i":60,"t":"Bugsnag","u":"/docs/crashreporting/","h":"#bugsnag","p":56},{"i":62,"t":"Configuring crash log writers","u":"/docs/crashreporting/","h":"#configuring-crash-log-writers","p":56},{"i":64,"t":"minSeverity: Severity","u":"/docs/crashreporting/","h":"#minseverity-severity","p":56},{"i":66,"t":"minCrashSeverity: Severity?","u":"/docs/crashreporting/","h":"#mincrashseverity-severity","p":56},{"i":68,"t":"messageStringFormatter: MessageStringFormatter","u":"/docs/crashreporting/","h":"#messagestringformatter-messagestringformatter","p":56},{"i":71,"t":"Setup","u":"/docs/crashreporting/BUGSNAG","h":"#setup","p":70},{"i":73,"t":"Add the dependency","u":"/docs/crashreporting/BUGSNAG","h":"#add-the-dependency","p":70},{"i":75,"t":"Add the log writer","u":"/docs/crashreporting/BUGSNAG","h":"#add-the-log-writer","p":70},{"i":77,"t":"Custom Values","u":"/docs/crashreporting/BUGSNAG","h":"#custom-values","p":70},{"i":80,"t":"Setup","u":"/docs/crashreporting/CRASHLYTICS","h":"#setup","p":79},{"i":82,"t":"Add the dependency","u":"/docs/crashreporting/CRASHLYTICS","h":"#add-the-dependency","p":79},{"i":84,"t":"Add the log writer","u":"/docs/crashreporting/CRASHLYTICS","h":"#add-the-log-writer","p":79},{"i":86,"t":"Custom Values","u":"/docs/crashreporting/CRASHLYTICS","h":"#custom-values","p":79},{"i":91,"t":"Crashlytics","u":"/docs/extensions/","h":"#crashlytics","p":90},{"i":93,"t":"Bugsnag","u":"/docs/extensions/","h":"#bugsnag","p":90},{"i":95,"t":"Koin","u":"/docs/extensions/","h":"#koin","p":90},{"i":99,"t":"Prebuilt LogWriters","u":"/docs/details/LOG_WRITER","h":"#prebuilt-logwriters","p":97},{"i":101,"t":"Custom LogWriter","u":"/docs/details/LOG_WRITER","h":"#custom-logwriter","p":97},{"i":105,"t":"XcodeSeverityWriter","u":"/docs/IOS_LOGGING","h":"#xcodeseveritywriter","p":103},{"i":107,"t":"OSLogWriter","u":"/docs/IOS_LOGGING","h":"#oslogwriter","p":103},{"i":109,"t":"NSLogWriter","u":"/docs/IOS_LOGGING","h":"#nslogwriter","p":103},{"i":113,"t":"Setup","u":"/docs/extensions/KOIN","h":"#setup","p":111},{"i":114,"t":"Add the dependency","u":"/docs/extensions/KOIN","h":"#add-the-dependency","p":111},{"i":116,"t":"Register the logger with Koin","u":"/docs/extensions/KOIN","h":"#register-the-logger-with-koin","p":111},{"i":118,"t":"Dependency Injection Helpers","u":"/docs/extensions/KOIN","h":"#dependency-injection-helpers","p":111},{"i":122,"t":"Add to your dependencies","u":"/docs/TESTING","h":"#add-to-your-dependencies","p":120},{"i":124,"t":"Use in your tests","u":"/docs/TESTING","h":"#use-in-your-tests","p":120},{"i":126,"t":"Logging on Android","u":"/docs/TESTING","h":"#logging-on-android","p":120}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/3",[0,3.4,1,3.4]],["t/5",[2,2.791,3,1.531,4,1.643]],["t/7",[5,3.4,6,2.002]],["t/9",[7,3.4,8,2.352]],["t/11",[9,3.4,10,3.4]],["t/13",[11,3.315]],["t/15",[8,3.009]],["t/17",[12,3.315]],["t/19",[13,4.349]],["t/21",[14,3.4,15,3.4]],["t/23",[16,2.791,17,2.791,18,2.791]],["t/26",[11,2.592,19,2.352]],["t/28",[20,2.913,21,3.4]],["t/30",[22,2.791,23,2.791,24,2.791]],["t/34",[25,4.349]],["t/36",[26,4.349]],["t/38",[27,2.791,28,2.791,29,2.791]],["t/42",[6,1.643,20,2.391,30,2.791]],["t/44",[31,4.349]],["t/46",[32,4.349]],["t/48",[33,4.349]],["t/50",[34,4.349]],["t/52",[35,3.726]],["t/58",[36,3.726]],["t/60",[37,3.726]],["t/62",[6,1.394,35,2.028,38,2.367,39,1.805]],["t/64",[12,2.592,40,3.4]],["t/66",[12,2.592,41,3.4]],["t/68",[42,4.744]],["t/71",[19,3.009]],["t/73",[3,1.865,4,2.002]],["t/75",[3,1.531,6,1.643,39,2.128]],["t/77",[43,2.592,44,2.913]],["t/80",[19,3.009]],["t/82",[3,1.865,4,2.002]],["t/84",[3,1.531,6,1.643,39,2.128]],["t/86",[43,2.592,44,2.913]],["t/91",[36,3.726]],["t/93",[37,3.726]],["t/95",[45,3.726]],["t/99",[8,2.352,46,3.4]],["t/101",[8,2.352,43,2.592]],["t/105",[47,4.349]],["t/107",[48,4.349]],["t/109",[49,4.349]],["t/113",[19,3.009]],["t/114",[3,1.865,4,2.002]],["t/116",[11,2.128,45,2.391,50,2.791]],["t/118",[4,1.643,51,2.791,52,2.791]],["t/122",[3,1.865,4,2.002]],["t/124",[53,3.4,54,3.4]],["t/126",[6,2.002,55,3.4]]],"invertedIndex":[["1",{"_index":2,"t":{"5":{"position":[[0,2]]}}}],["2",{"_index":5,"t":{"7":{"position":[[0,2]]}}}],["add",{"_index":3,"t":{"5":{"position":[[3,3]]},"73":{"position":[[0,3]]},"75":{"position":[[0,3]]},"82":{"position":[[0,3]]},"84":{"position":[[0,3]]},"114":{"position":[[0,3]]},"122":{"position":[[0,3]]}}}],["android",{"_index":55,"t":{"126":{"position":[[11,7]]}}}],["basic",{"_index":9,"t":{"11":{"position":[[0,5]]}}}],["bugsnag",{"_index":37,"t":{"60":{"position":[[0,7]]},"93":{"position":[[0,7]]}}}],["compon",{"_index":30,"t":{"42":{"position":[[12,10]]}}}],["concept",{"_index":10,"t":{"11":{"position":[[6,8]]}}}],["config",{"_index":26,"t":{"36":{"position":[[12,7]]}}}],["configur",{"_index":35,"t":{"52":{"position":[[0,13]]},"62":{"position":[[0,11]]}}}],["crash",{"_index":38,"t":{"62":{"position":[[12,5]]}}}],["crashlyt",{"_index":36,"t":{"58":{"position":[[0,11]]},"91":{"position":[[0,11]]}}}],["custom",{"_index":43,"t":{"77":{"position":[[0,6]]},"86":{"position":[[0,6]]},"101":{"position":[[0,6]]}}}],["default",{"_index":7,"t":{"9":{"position":[[0,7]]}}}],["defaultlogformatt",{"_index":32,"t":{"46":{"position":[[0,19]]}}}],["depend",{"_index":4,"t":{"5":{"position":[[7,10]]},"73":{"position":[[8,10]]},"82":{"position":[[8,10]]},"114":{"position":[[8,10]]},"118":{"position":[[0,10]]},"122":{"position":[[12,12]]}}}],["deprec",{"_index":16,"t":{"23":{"position":[[0,10]]}}}],["environ",{"_index":24,"t":{"30":{"position":[[11,12]]}}}],["format",{"_index":21,"t":{"28":{"position":[[8,10]]}}}],["get",{"_index":0,"t":{"3":{"position":[[0,7]]}}}],["gradl",{"_index":17,"t":{"23":{"position":[[11,6]]}}}],["helper",{"_index":52,"t":{"118":{"position":[[21,7]]}}}],["implement",{"_index":31,"t":{"44":{"position":[[0,15]]}}}],["inject",{"_index":51,"t":{"118":{"position":[[11,9]]}}}],["koin",{"_index":45,"t":{"95":{"position":[[0,4]]},"116":{"position":[[25,4]]}}}],["kotlin",{"_index":23,"t":{"30":{"position":[[4,6]]}}}],["log",{"_index":6,"t":{"7":{"position":[[3,3]]},"42":{"position":[[0,3]]},"62":{"position":[[18,3]]},"75":{"position":[[8,3]]},"84":{"position":[[8,3]]},"126":{"position":[[0,7]]}}}],["logger",{"_index":11,"t":{"13":{"position":[[0,6]]},"26":{"position":[[0,6]]},"116":{"position":[[13,6]]}}}],["loggerconfig",{"_index":25,"t":{"34":{"position":[[0,12]]}}}],["logwrit",{"_index":8,"t":{"9":{"position":[[8,9]]},"15":{"position":[[0,9]]},"99":{"position":[[9,10]]},"101":{"position":[[7,9]]}}}],["messag",{"_index":20,"t":{"28":{"position":[[0,7]]},"42":{"position":[[4,7]]}}}],["messagestringformatt",{"_index":42,"t":{"68":{"position":[[0,23],[24,22]]}}}],["mincrashsever",{"_index":41,"t":{"66":{"position":[[0,17]]}}}],["minsever",{"_index":40,"t":{"64":{"position":[[0,12]]}}}],["mutableloggerconfig",{"_index":29,"t":{"38":{"position":[[16,19]]}}}],["non",{"_index":22,"t":{"30":{"position":[[0,3]]}}}],["notagformatt",{"_index":33,"t":{"48":{"position":[[0,14]]}}}],["note",{"_index":14,"t":{"21":{"position":[[2,4]]}}}],["nslogwrit",{"_index":49,"t":{"109":{"position":[[0,11]]}}}],["oslogwrit",{"_index":48,"t":{"107":{"position":[[0,11]]}}}],["prebuilt",{"_index":46,"t":{"99":{"position":[[0,8]]}}}],["properti",{"_index":18,"t":{"23":{"position":[[18,10]]}}}],["regist",{"_index":50,"t":{"116":{"position":[[0,8]]}}}],["setup",{"_index":19,"t":{"26":{"position":[[7,5]]},"71":{"position":[[0,5]]},"80":{"position":[[0,5]]},"113":{"position":[[0,5]]}}}],["sever",{"_index":12,"t":{"17":{"position":[[0,8]]},"64":{"position":[[13,8]]},"66":{"position":[[18,9]]}}}],["simplelogformatt",{"_index":34,"t":{"50":{"position":[[0,18]]}}}],["start",{"_index":1,"t":{"3":{"position":[[8,7]]}}}],["staticconfig",{"_index":27,"t":{"38":{"position":[[0,12]]}}}],["tag",{"_index":15,"t":{"21":{"position":[[13,4]]}}}],["test",{"_index":54,"t":{"124":{"position":[[12,5]]}}}],["us",{"_index":53,"t":{"124":{"position":[[0,3]]}}}],["usag",{"_index":13,"t":{"19":{"position":[[0,5]]}}}],["valu",{"_index":44,"t":{"77":{"position":[[7,6]]},"86":{"position":[[7,6]]}}}],["vs",{"_index":28,"t":{"38":{"position":[[13,2]]}}}],["writer",{"_index":39,"t":{"62":{"position":[[22,7]]},"75":{"position":[[12,6]]},"84":{"position":[[12,6]]}}}],["xcodeseveritywrit",{"_index":47,"t":{"105":{"position":[[0,19]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":2,"t":"Kermit is a Kotlin Multiplatform logging library. It's primary purpose is to allow log statements from Kotlin code to be written to composable log outputs. Out of the box, the library defaults to platform-specific loggers such as Logcat and OSLog, but is easy to extend and configure. tip Check out KaMP Kit to get started developing for Kotlin Multiplatform","s":"Kermit the log","u":"/docs/","h":"","p":1},{"i":4,"t":"Configuration for different environments can get more complex, but the default config out of the box is fairly simple.","s":"Getting Started","u":"/docs/","h":"#getting-started","p":1},{"i":6,"t":"The Kermit dependency should be added to your commonMain source set in your Kotlin Multiplatform module. commonMain { dependencies { ... implementation(\"co.touchlab:kermit:2.0.3\") //Add latest version } }","s":"1. Add Dependency","u":"/docs/","h":"#1-add-dependency","p":1},{"i":8,"t":"Logger.i { \"Hello World\" }","s":"2. Log","u":"/docs/","h":"#2-log","p":1},{"i":10,"t":"By default, Kermit includes a LogWriter instance for each platform that is configured for development. On Android it writes to Logcat, on iOS it writes to OSLog, and for JS it writes to console.","s":"Default LogWriter","u":"/docs/","h":"#default-logwriter","p":1},{"i":12,"t":"The basic components you'll need to be aware of are Logger, LogWriter, and Severity.","s":"Basic Concepts","u":"/docs/","h":"#basic-concepts","p":1},{"i":14,"t":"The Logger takes log calls from your code and dispatches them to LogWriter instances. There are different methods on Logger corresponding to different log Severity levels. In order of least to most severe: v(), d(), i(), w(), e(), and a(). You configure the Logger, then call log methods on it. That's the basic interaction with Kermit. Logger.i { \"Hello World\" } try { somethingRisky() } catch(t: Throwable){ Logger.w(t) { \"That could've gone better\" } }","s":"Logger","u":"/docs/","h":"#logger","p":1},{"i":16,"t":"A LogWriter actually sends log messages to different log outputs. You add LogWriter instances to a Logger. Kermit includes a CommonWriter and various platform-specific LogWriter instances. Through other modules, Kermit also allows logging crash info to Crashlytics and Bugsnag. For more info on included LogWriter types, and to create your own, see LOG_WRITER","s":"LogWriter","u":"/docs/","h":"#logwriter","p":1},{"i":18,"t":"Severity levels follow common logging library patterns and should be generally familiar. You can control what will and won't get logged based on severity. So, say you only want to log Warn and up, you can tell the logger. We'll cover that more in Configuration","s":"Severity","u":"/docs/","h":"#severity","p":1},{"i":20,"t":"The primary logging artifact is Logger. It defines the severity-level logging methods. It has a Kotlin-aware api relying on default parameters and lambda syntax. info To log from non-Kotlin clients, that don't support calling Kotlin's default parameters, see NON_KOTLIN. A common use case would be calling Kermit from Swift or JS. For each severity, there are two methods. One takes a String log message directly, the other takes a function parameter that returns a string. The function is only evaluated if the log will be written. Which you use is personal preference. They both will log to the same places, but the function parameter version may avoid unecessary String creation and evaluation. Here are what the w method definitions look like: // Trailing function parameter fun w(throwable: Throwable? = null, tag: String = this.tag, message: () -> String) // String message parameter fun w(messageString: String, throwable: Throwable? = null, tag: String = this.tag) info The function parameter is at the end of the function to support Kotlin's trailing lambda syntax. In its most basic form, logging looks like this: Logger.i { \"Hello World\" } Some other examples with tags and Throwable params. Logger.w(\"MyTag\") { \"Hello World $someData\" } // etc Logger.e(ex) { \"Something failed\" } // or Logger.e(\"Something failed\", ex)","s":"Usage","u":"/docs/","h":"#usage","p":1},{"i":22,"t":"Tags are much more common on Android, as Logcat has tag arguments, and it is the default logger on Android. It would be difficult to have a Kotlin Multiplatform library without them, but they don't really fit into other platforms as easily. Kermit's default tag is an empty string. You can supply a tag param to each log call, change the base default tag, or create a Logger instance with it's own tag. For example, create a field in a ViewModel with the tag set to the class name (a common Android pattern): class MyViewModel:ViewModel { private val log = Logger.withTag(\"MyViewModel\") } Platform-specific loggers can be configured to ignore tags on output, or you can customize their display easily. We'll discuss these options more in Configuration.","s":"A Note About Tags","u":"/docs/","h":"#a-note-about-tags","p":1},{"i":24,"t":"Per the official Kotlin documentation we took the opportunity with the Kermit 2.0 release to remove deprecated gradle.properties values. We encourage you to do the same!","s":"Deprecated Gradle properties","u":"/docs/","h":"#deprecated-gradle-properties","p":1},{"i":27,"t":"Logger setup includes various topics, including static vs mutable, and adding non-default LogWriter instances.","s":"Logger Setup","u":"/docs/configuration/","h":"#logger-setup","p":25},{"i":29,"t":"LogWriter instances sometimes need to include tag or severity in the log message string. You may also want to add some custom info to the message strings. MessageStringFormatter allows for central formatting configuration.","s":"Message Formatting","u":"/docs/configuration/","h":"#message-formatting","p":25},{"i":31,"t":"Kermit's API is designed to be Kotlin-friendly. That includes methods with default parameters. To call Kermit from other environments, for example Swift, you'll probably want to add and export kermit-simple.","s":"Non-Kotlin Environments","u":"/docs/configuration/","h":"#non-kotlin-environments","p":25},{"i":33,"t":"A Logger is just a class with a LoggerConfig instance and a default tag. You can create your own instance of Logger, or configure and call the global Logger instance. // Local val log = Logger( loggerConfigInit(platformLogWriter(NoTagLogFormatter)), \"MyTag\" ) log.i { \"Hello Kotlin\" } // Global Logger.setLogWriters(platformLogWriter(NoTagLogFormatter)) Logger.setTag(\"MyTag\") Logger.i { \"Hello Kotlin\" } Which method you choose is up to you, but obviously a local log instance will need to be made available for you code to call, while global is available everywhere. For example, our pattern has been to inject loggers into components, with the tag applied at that point, rather than specify the tag in each call. single { BreedCallbackViewModel( get(), getWith(\"BreedCallbackViewModel\") // Convenience function to get a Logger with a tag set ) }","s":"Logger Setup","u":"/docs/configuration/LOGGER_SETUP","h":"","p":32},{"i":35,"t":"LoggerConfig defines the minSeverity, below which log statements will be ignored, and logWriterList, the collection of LogWriter instances that will be written to. interface LoggerConfig { val minSeverity: Severity val logWriterList: List } When creating our own Logger instances above, we call loggerConfigInit. That is a convenience function to create a StaticConfig instance. fun loggerConfigInit(vararg logWriters: LogWriter, minSeverity: Severity = DEFAULT_MIN_SEVERITY): LoggerConfig = StaticConfig(logWriterList = logWriters.toList(), minSeverity = minSeverity)","s":"LoggerConfig","u":"/docs/configuration/LOGGER_SETUP","h":"#loggerconfig","p":32},{"i":37,"t":"platformLogWriter() is an expect/actual factory function. You can call it in common code, and it will create a LogWriter designed for the platform the code is running on. For more complex configuration, you'll either need platform-specific entry points, or possibly your own expect/actual factory function(s).","s":"Where to do config?","u":"/docs/configuration/LOGGER_SETUP","h":"#where-to-do-config","p":32},{"i":39,"t":"For most use cases, once your logger is set up, you won't need to change the config. StaticConfig has values that can't be changed once initializd. That is what you want when creating a local Logger instance. The global Logger uses MutableLoggerConfig, because values need to be changed after that instance has been initialized. It is also possible that you have a use case where the config of your local Logger instance needs to be changed after the instance is created. In that case, you can use MutableLoggerConfig instead of StaticConfig. Why have StaticConfig at all? Logger instances are thread-safe, so MutableLoggerConfig needs to be thread-safe. That means config fields are volatile on the JVM and Atomic on native platforms. While the performance impact is likely negligable, if you want to maximize performance, static is better. If you really like global access, but want static config, you can just create your own global logger. object MyLogger : Logger( config = loggerConfigInit( platformLogWriter(NoTagLogFormatter), minSeverity = Severity.Info ), tag = \"MyAppTag\" ) fun hello(){ MyLogger.i { \"Hello\" } }","s":"StaticConfig vs MutableLoggerConfig","u":"/docs/configuration/LOGGER_SETUP","h":"#staticconfig-vs-mutableloggerconfig","p":32},{"i":41,"t":"To make message formatting more uniform and flexible, many of the LogWriter instances can take a MessageStringFormatter parameter. This allows you to control how log messages are presented and apply common formatting. TL;DR If you don't want tags to be printed in your iOS or JS log statements, give your LogWriter instances NoTagFormatter. This will suppress printing tag in log message strings. Tag will still be sent to Android log messages. For the global Logger and the platform LogWriter, config would look like the following: Logger.setLogWriters(platformLogWriter(NoTagFormatter)) For most use cases, this is all you need to know about formatters. The rest of this doc explains them in more detail.","s":"Message Formatting","u":"/docs/configuration/MESSAGE_FORMATTING","h":"","p":40},{"i":43,"t":"There are 3 parts to a message: Severity, Tag, and the Message itself. All loggers accept a log message string, but support for severity and tag vary between systems. Here is a breakdown of support for a few commonly used logging systems. System Severity Tag Android ✅ ✅ OSLog (iOS) ✅ ❌ JS-Console ✅ ❌ SystemWriter (jvm) ❌ ❌ Common (println) ❌ ❌ The main purpose of MessageStringFormatter is to manage situations where the logging system does not support either Severity or Tag. The LogWriter instance will pass null's to the MessageStringFormatter in cases where the LogWriter natively supports Severity or Tag. For example, the DefaultLogFormatter will result in the following message strings depending on platform: // Log call Logger.w(tag = \"ATag\") { \"A Log Message\" } // Android // 'A Log Message' // OSLog // '(ATag) A Log Message' // Common // 'Warn: (ATag) A Log Message' info You can use MessageStringFormatter to implement custom message strings. Maybe, say, add a special date format to each line. However, Kermit uses them to manage Severity and Tag for systems that don't natively support those constructs. Note: the Android LogcatWriter does not currently use a MessageStringFormatter. You would need to create a custom implementation to support that.","s":"Log Message Components","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#log-message-components","p":40},{"i":45,"t":"Kermit provides a few implementations out of the box.","s":"Implementations","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#implementations","p":40},{"i":47,"t":"This is the standard format that all compatible LogWriter instances get by default. Messages are formatted as in the examples above.","s":"DefaultLogFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#defaultlogformatter","p":40},{"i":49,"t":"Tags are really an Android convention. Other platforms can feel cluttered with them. You can simply ignore them with NoTagFormatter. Logging will function the same for Android, and other platforms will ignore the Tag.","s":"NoTagFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#notagformatter","p":40},{"i":51,"t":"This formatter skips tags and severity. It just prints the message.","s":"SimpleLogFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#simplelogformatter","p":40},{"i":53,"t":"To simplify setting platform LogWriter instances, you can pass a MessageStringFormatter to platformLogWriter. platformLogWriter(NoTagLogFormatter)","s":"Configuration","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#configuration","p":40},{"i":55,"t":"You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose. Earlier versions of Kermit were designed to be Swift-friendly, but that sacrificed the Kotlin-friendly API, and since the primary use-case is calling Kermit from Kotlin, that seemed like a bad compromise. We've added a module called kermit-simple which adds explicit call signatures to the API, to provide for the cases where default parameters make more sense in a Kotlin context. kotlin { sourceSets { val commonMain by getting { dependencies { // etc implementation(\"co.touchlab:kermit:2.0.3\") } } val iosMain by getting { dependencies { // etc api(\"co.touchlab:kermit-simple:2.0.3\") } } } cocoapods { framework { export(\"co.touchlab:kermit-simple:2.0.3\") } } } You will need to export kermit-simple, as in the example above. From Swift, this will allow you to call methods without all of the parameters explicitly added. let log = // Get a Logger instance log.i(messageString: \"Try a log\") log.w(messageString: \"Throw\", throwable: someException)","s":"Non-Kotlin Environments","u":"/docs/configuration/NON_KOTLIN","h":"","p":54},{"i":57,"t":"Crash reporting is primarily handled with CrashKiOS. Kermit provides LogWriter instances to write breadcrumb/log statements to the crash reporting tools, and sending soft \"handled\" exceptions when Throwable instances are logged, based on configuration. info Earlier versions of Kermit implemented crash reporting directly, but logging and crash reporting are really different domains. Crash reporting support was moved back into CrashKiOS, and Kermit simply provides a logging interface into those tools. Kermit and CrashKiOS currently support Firebase Crashlytics and Bugsnag.","s":"Crash Reporting","u":"/docs/crashreporting/","h":"","p":56},{"i":59,"t":"See Crashlytics Setup","s":"Crashlytics","u":"/docs/crashreporting/","h":"#crashlytics","p":56},{"i":61,"t":"See Bugsnag Setup","s":"Bugsnag","u":"/docs/crashreporting/","h":"#bugsnag","p":56},{"i":63,"t":"Both crash LogWriter implementations take 3 parameters:","s":"Configuring crash log writers","u":"/docs/crashreporting/","h":"#configuring-crash-log-writers","p":56},{"i":65,"t":"This is the minimum severity that will be logged to the crash reporter's breadcrumb cache. The default severity is Info. That means Debug and Verbose statements will be ignored.","s":"minSeverity: Severity","u":"/docs/crashreporting/","h":"#minseverity-severity","p":56},{"i":67,"t":"All log statements can take a Throwable. If you send a Throwable to a crash LogWriter, if the log statement itself is equal to or above minCrashSeverity, the Throwable will be sent as a soft/handled exception. The default value is Warn, so all log statements with a Throwable, with log severity of Warn or higher, will create an exception report. To disable sending exception reports, pass null.","s":"minCrashSeverity: Severity?","u":"/docs/crashreporting/","h":"#mincrashseverity-severity","p":56},{"i":69,"t":"See Message Formatting for details of how to format log message strings. DefaultFormatter is the default value.","s":"messageStringFormatter: MessageStringFormatter","u":"/docs/crashreporting/","h":"#messagestringformatter-messagestringformatter","p":56},{"i":72,"t":"You first need to configure Bugsnag and CrashKiOS initialization. See the CrashKiOS Bugsnag Tutorial Doc.","s":"Setup","u":"/docs/crashreporting/BUGSNAG","h":"#setup","p":70},{"i":74,"t":"commonMain { dependencies { implementation(\"co.touchlab:kermit-bugsnag:2.0.3\") } }","s":"Add the dependency","u":"/docs/crashreporting/BUGSNAG","h":"#add-the-dependency","p":70},{"i":76,"t":"Logger.setLogWriters(BugsnagLogWriter())","s":"Add the log writer","u":"/docs/crashreporting/BUGSNAG","h":"#add-the-log-writer","p":70},{"i":78,"t":"You can add custom values to Bugsnag, but not through Kermit. Call CrashKiOS directly. BugsnagKotlin.setCustomValue(\"someKey\", \"someValue\")","s":"Custom Values","u":"/docs/crashreporting/BUGSNAG","h":"#custom-values","p":70},{"i":81,"t":"You first need to configure Crashlytics and CrashKiOS initialization. See the CrashKiOS Crashlytics Tutorial Doc.","s":"Setup","u":"/docs/crashreporting/CRASHLYTICS","h":"#setup","p":79},{"i":83,"t":"commonMain { dependencies { implementation(\"co.touchlab:kermit-crashlytics:2.0.3\") } }","s":"Add the dependency","u":"/docs/crashreporting/CRASHLYTICS","h":"#add-the-dependency","p":79},{"i":85,"t":"Logger.setLogWriters(CrashlyticsLogWriter())","s":"Add the log writer","u":"/docs/crashreporting/CRASHLYTICS","h":"#add-the-log-writer","p":79},{"i":87,"t":"You can add custom values to Crashlytics, but not through Kermit. Call CrashKiOS directly. CrashlyticsKotlin.setCustomValue(\"someKey\", \"someValue\")","s":"Custom Values","u":"/docs/crashreporting/CRASHLYTICS","h":"#custom-values","p":79},{"i":89,"t":"The main module most users will include is kermit. However, much of the configuration and other underlying functionality has been moved to kermit-core. The main kermit module is a relatively thin API layer that sits on top of kermit-core. Over the past few years, we've had feedback about the API design choices made in Kermit. Some of that feedback makes sense and has been incorporated. Other feedback is really just personal preference, and would conflict with the existing design. Rather than trying to make everybody happy, we've structured Kermit's modules so you can create your own API interface on top of the underlying kermit-core module. That will allow you to use compatible extensions like Crashlytics and Bugsnag, but interface with the underlying Kermit system with whatever API you prefer. For example, if you wanted a very simple logger with only two methods, you would make kermit-core a dependency rather than kermit, and write your own implementation: object MyLogger : BaseLogger(loggerConfigInit(platformLogWriter())) { fun info(message: String){ log(Severity.Info, \"MyLogger\", null, message) } fun error(message: String, throwable: Throwable){ log(Severity.Error, \"MyLogger\", throwable, message) } } For a more complex example, see the implementation of co.touchlab.kermit.Logger in kermit.","s":"Custom Logger API","u":"/docs/details/CUSTOM_API","h":"","p":88},{"i":92,"t":"Crashlytics log statement writing.","s":"Crashlytics","u":"/docs/extensions/","h":"#crashlytics","p":90},{"i":94,"t":"Bugsnag breadcrumb writing.","s":"Bugsnag","u":"/docs/extensions/","h":"#bugsnag","p":90},{"i":96,"t":"Integration with Koin, for easy logger injection.","s":"Koin","u":"/docs/extensions/","h":"#koin","p":90},{"i":98,"t":"LogWriter takes care of deciding where to log the messages.","s":"LogWriter","u":"/docs/details/LOG_WRITER","h":"","p":97},{"i":100,"t":"By default Kermit provides default LogWriter for each platform CommonWriter - Uses println to send logs in Kotlin LogcatWriter - Uses LogCat to send logs in Android OSLogWriter - Uses os log to send logs in iOS ConsoleWriter - Uses console to log in JS These can be created and passed into the Logger object during initialization Logger.setLogWriters(listOf(LogcatWriter(), CommonWriter())) Selecting loggers for each platform can either be done with platform-specific entry points, or using an expect/actual factory function. Kermit ships with a default factory function that provides a LogWriter suited to local development. package co.touchlab.kermit expect fun platformLogWriter(messageStringFormatter: MessageStringFormatter = DefaultFormatter): LogWriter You can implement a factory function for your project similar to the one above.","s":"Prebuilt LogWriters","u":"/docs/details/LOG_WRITER","h":"#prebuilt-logwriters","p":97},{"i":102,"t":"If you want to have a custom implementation to send logs to your own server, or a 3rd party tool or simply because default implementation doesn't fit your need, then you would need to extend the LogWriter class and provide your own instance. For a simple LogWriter you only need to implement the log method, which handles all log messages. Simple implementation would look like below, class YourCustomWriter : LogWriter() { override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) { // Handle logging here } } Custom loggers may also override isLoggable. Kermit will check this value before logging to this LogWriter. open fun isLoggable(tag: String, severity: Severity): Boolean = true If your custom logger should only send messages in production, the implementation could look like the following: // LogWriter class YourCustomWriter(private val isProduction:Boolean) : LogWriter() { override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) { // Do something custom } override fun isLoggable(tag: String, severity: Severity): Boolean = isProduction } // Usage val logWriter = YourCustomWriter(someProdFlag) val logger = Logger(loggerConfigInit(logWriter))","s":"Custom LogWriter","u":"/docs/details/LOG_WRITER","h":"#custom-logwriter","p":97},{"i":104,"t":"There are three LogWriter implementations for iOS.","s":"iOS Logging","u":"/docs/IOS_LOGGING","h":"","p":103},{"i":106,"t":"This is the default LogWriter. It is designed for local development. Each severity is represented with an emoji. Throwable instances sent to this writer will be written with println rather than oslog because oslog trims long strings. 2023-03-05 08:48:03.864138-0500 KermitSampleIOS[58575:7607179] 🟢 Try a log 2023-03-05 08:48:04.622452-0500 KermitSampleIOS[58575:7607442] [Bugsnag] [INFO] Sent session 7D3188F7-2B37-4189-9F92-63BC7172D01B 2023-03-05 08:48:09.999884-0500 KermitSampleIOS[58575:7607179] 🟢 Common click count: 1 2023-03-05 08:48:11.333941-0500 KermitSampleIOS[58575:7607179] 🔵 Common click count: 2 2023-03-05 08:48:13.104265-0500 KermitSampleIOS[58575:7607179] 🟡 Common click count: 3 2023-03-05 08:48:13.568351-0500 KermitSampleIOS[58575:7607179] 🔴 Common click count: 4","s":"XcodeSeverityWriter","u":"/docs/IOS_LOGGING","h":"#xcodeseveritywriter","p":103},{"i":108,"t":"This is the parent class of XcodeSeverityWriter. There is no emoji added for severity, and Throwable is sent as a string to oslog. This may trim exceptions. You can implement a custom version that writes each line of a stack trace to oslog, or whatever else you'd like to do. Override logThrowable.","s":"OSLogWriter","u":"/docs/IOS_LOGGING","h":"#oslogwriter","p":103},{"i":110,"t":"Legacy implementation using NSLog.","s":"NSLogWriter","u":"/docs/IOS_LOGGING","h":"#nslogwriter","p":103},{"i":112,"t":"Kermit's Koin integation comes in two parts - a logger implementation that writes Koin logger output to Kermit, and dependency injection helpers.","s":"Koin Integration","u":"/docs/extensions/KOIN","h":"","p":111},{"i":115,"t":"commonMain { dependencies { implementation(\"co.touchlab:kermit-koin:2.0.3\") } }","s":"Add the dependency","u":"/docs/extensions/KOIN","h":"#add-the-dependency","p":111},{"i":117,"t":"val koinApplication = startKoin { logger( KermitKoinLogger(Logger.withTag(\"koin\")) ) modules(/* modulesList */) } Obviously you will want to have initialized Kermit before registering a logger with Koin, and the tag you pass is optional. That said, it's useful to tag the Koin output to be able to filter and see what is going on. Once you have registered the logger, all of the normal Koin logging will be piped through to Kermit. This is especially helpful when checking your module dependencies from unit tests!","s":"Register the logger with Koin","u":"/docs/extensions/KOIN","h":"#register-the-logger-with-koin","p":111},{"i":119,"t":"The kermitLoggerModule() method returns a Koin module that declares a factory for logger instances. If you don't want to make use of the Koin factory, there's a getLoggerWithTag() extension method you can call directly. We prefer injecting logger instances rather than using the global Logger instance, especially when we know we'll be unit testing a section of code.","s":"Dependency Injection Helpers","u":"/docs/extensions/KOIN","h":"#dependency-injection-helpers","p":111},{"i":121,"t":"Kermit includes a test dependency, intended for use when testing application code that interacts with Kermit APIs but doesn't want to write to actual logs. This includes a TestLogWriter which holds the string outputs of log statements, and has APIs for asserting on what logs are present. note The test APIs are not yet stable, and require opting into the @ExperimentalKermitApi annotation. The current API is based on what we use to test Kermit internally. It may change dramatically before we stabilize it as we consider more real-world use-cases.","s":"Testing","u":"/docs/TESTING","h":"","p":120},{"i":123,"t":"Typically you would depend on this from your test sources. sourceSets { commonTest { dependencies { implementation(\"co.touchlab:kermit-test:2.0.3\") //Add latest version } } }","s":"Add to your dependencies","u":"/docs/TESTING","h":"#add-to-your-dependencies","p":120},{"i":125,"t":"info We strongly recommend you inject logger instances into your classes rather than simply calling the (global) static Logger as it will make testing easier. Suppose you have a test @OptIn(ExperimentalKermitApi::class) class MyExampleTest { private val testLogWriter = TestLogWriter( loggable = Severity.Verbose // accept everything ) private val kermit = Logger( TestConfig( minSeverity = Severity.Debug, logWriterList = listOf(testLogWriter) ) ) // ... } You can either interact with the latest log entry that was produced - @Test fun somethingInterestingHappened() { // ... testLogWriter.assertCount(1) // calls assertTrue() on the result of the lambda testLogWriter.assertLast { message == \"the message\" && severity == Severity.Info && tag == \"my-tag\" && throwable == null } } or you can interact with the list of log entries directly @Test fun somethingElseInterestingHappened() { // ... testLogWriter.assertCount(10) with(testLogWriter.logs[3]) { assertEquals(\"the message\", message) assertEquals(Severity.Info, severity) assertEquals(\"my-tag\", tag) assertNull(throwable) } }","s":"Use in your tests","u":"/docs/TESTING","h":"#use-in-your-tests","p":120},{"i":127,"t":"The default setup of Kermit aims to make production logging as simple as possible. This means that the platform logger for Android defaults to passing the log through to Android's logcat Log() method. Be sure to configure your tests accordingly, as this wont function when running unit tests on your local machine!","s":"Logging on Android","u":"/docs/TESTING","h":"#logging-on-android","p":120}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/2",[0,0.964,1,2.871,2,3.818,3,1.301,4,3.818,5,2.734,6,2.734,7,3.054,8,2.145,9,1.89,10,2.009,11,2.495,12,3.54,13,2.145,14,3.818,15,2.734,16,1.203,17,1.523,18,2.304,19,0.923,20,3.54,21,2.304,22,2.304,23,3.054,24,3.054,25,1.382,26,3.54,27,2.734,28,3.54,29,3.54,30,3.54,31,2.495]],["t/4",[14,3.988,15,3.988,16,1.755,25,2.016,32,3.639,33,3.988,34,2.603,35,3.988,36,3.988,37,4.455,38,3.129]],["t/6",[0,1.226,1,2.268,2,3.476,39,2.629,40,3.172,41,3.78,42,3.883,43,2.929,44,2.727,45,2.092,46,3.883,47,2.268,48,3.476,49,2.727]],["t/8",[45,2.004,50,4.036,51,3.727,52,4.036]],["t/10",[0,1.262,16,1.574,17,1.993,21,3.015,22,3.015,25,1.809,31,3.265,53,2.629,54,1.378,55,1.44,56,2.473,57,2.629,58,3.481,59,3.015,60,3.015,61,3.578]],["t/12",[19,1.416,54,1.615,62,4.194,63,4.685,64,4.194,65,2.458,66,4.685,67,2.12]],["t/14",[0,0.867,3,1.227,10,1.806,19,1.4,25,1.243,32,3.231,45,1.988,50,2.243,51,2.072,52,2.243,54,0.946,55,0.989,62,2.458,67,1.79,68,1.929,69,1.878,70,3.183,71,2.31,72,3.183,73,2.458,74,3.183,75,3.183,76,3.183,77,2.746,78,3.183,79,3.183,80,2.458,81,2.243,82,3.183,83,3.183,84,1.519,85,3.183,86,3.183,87,3.183,88,2.746]],["t/16",[0,1.368,3,1.317,8,2.195,13,2.195,17,1.558,18,2.357,19,0.944,32,2.552,34,1.825,44,2.195,47,1.825,53,2.85,54,1.851,55,1.561,89,3.124,90,2.357,91,1.558,92,3.124,93,3.124,94,2.357,95,2.357,96,2.681,97,2.055,98,1.934,99,3.621,100,1.728,101,1.825,102,3.621]],["t/18",[3,1.43,4,3.288,19,1.11,25,1.662,34,2.146,67,2.187,73,3.288,103,3,104,2.416,105,3.288,106,4.257,107,4.257,108,3.673,109,3.288,110,3,111,2.031,112,3.288,113,3.288,114,4.257,115,3.288,116,4.257]],["t/20",[0,0.434,1,1.343,3,1.175,6,1.229,11,1.122,16,0.906,19,0.415,45,1.934,49,0.965,50,1.122,51,1.735,52,1.879,56,0.85,60,1.036,62,1.229,66,1.373,67,1.041,68,1.615,69,1.092,71,1.733,73,1.229,77,1.373,84,1.919,91,1.48,96,1.423,101,0.802,104,0.903,117,1.592,118,1.373,119,1.036,120,1.592,121,3.348,122,2.3,123,2.665,124,1.229,125,1.592,126,1.036,127,2.059,128,2.665,129,1.592,130,1.207,131,0.965,132,1.229,133,1.229,134,1.373,135,2.442,136,0.965,137,2.586,138,1.373,139,2.665,140,1.373,141,1.229,142,1.373,143,1.229,144,1.592,145,1.592,146,1.592,147,1.592,148,1.229,149,1.592,150,2.059,151,2.665,152,1.513,153,1.592,154,1.879,155,1.48,156,2.665,157,1.592,158,1.592,159,1.592,160,0.85,161,1.373,162,1.592,163,1.592,164,1.373,165,1.592,166,1.373,167,2.665,168,1.592,169,1.592]],["t/22",[1,1.261,2,1.932,3,0.875,4,1.932,5,1.932,13,1.516,16,1.583,17,1.649,18,1.628,19,1.214,21,1.628,25,1.496,34,1.931,43,1.628,45,1.385,55,0.777,56,1.335,57,2.643,69,1.024,100,1.828,104,2.175,105,1.932,110,1.763,115,1.932,126,1.628,135,1.132,155,2.743,160,1.335,161,2.158,170,2.158,171,2.501,172,2.501,173,2.158,174,1.628,175,2.158,176,3.832,177,1.763,178,2.501,179,2.501,180,1.932,181,2.158,182,2.501,183,2.494,184,2.501,185,2.501,186,2.158,187,1.419,188,2.501,189,1.763,190,1.419,191,2.501,192,2.501,193,2.158]],["t/24",[0,1.32,1,2.443,143,3.743,194,4.846,195,4.846,196,4.846,197,4.846,198,4.846,199,4.846,200,4.846,201,4.846,202,4.846,203,4.846,204,2.75,205,4.846]],["t/27",[16,1.673,19,1.283,40,3.469,53,3.489,54,1.464,55,1.53,93,4.246,124,3.801,206,3.469,207,4.922,208,3.801,209,4.922,210,4.922]],["t/29",[3,1.013,8,2.689,25,1.732,47,2.236,53,2.518,54,1.319,55,1.379,65,2.009,67,1.732,91,2.476,96,2.369,111,2.117,135,2.605,155,1.909,190,2.518,211,4.437,212,2.888,213,4.437,214,2.888]],["t/31",[0,1.567,1,2.236,16,1.508,33,3.427,38,2.689,47,2.236,53,2.518,64,3.427,69,1.817,71,2.236,111,2.117,119,2.888,121,2.888,132,3.427,160,2.369,177,3.127,215,2.888,216,3.828,217,4.437,218,3.828]],["t/33",[1,1.931,3,0.875,10,1.419,16,0.85,19,1.548,25,0.976,43,1.628,45,2.047,50,1.763,51,2.494,55,1.623,56,1.335,63,2.158,65,1.132,69,1.908,71,1.261,100,1.193,105,1.932,113,1.932,137,1.335,155,2.246,160,1.335,183,1.628,187,1.419,219,2.158,220,3.032,221,2.494,222,2.501,223,2.501,224,2.501,225,2.501,226,2.501,227,2.501,228,2.158,229,2.158,230,3.832,231,2.501,232,1.628,233,2.158,234,1.932,235,2.501,236,2.501,237,2.501,238,2.501,239,2.158]],["t/35",[3,0.727,9,1.699,11,2.243,19,0.83,45,1.929,54,1.597,55,1.67,67,1.79,69,1.304,100,2.187,118,2.746,137,1.699,152,1.806,187,2.601,189,2.243,219,4.635,239,2.746,240,4.811,241,2.746,242,3.955,243,3.183,244,2.458,245,3.183,246,2.072,247,2.746,248,2.746,249,3.183,250,3.183,251,3.183,252,3.183]],["t/37",[10,3.124,17,2.368,18,2.698,25,1.618,34,2.089,35,3.201,54,1.233,64,3.201,65,1.877,69,1.698,100,1.978,104,2.353,137,2.213,215,2.698,234,3.201,253,3.576,254,4.748,255,4.251,256,3.576,257,3.201,258,3.201,259,4.145]],["t/39",[17,0.886,19,1.498,36,3.965,43,1.341,45,1.83,51,2.142,55,1.595,65,2.126,88,1.777,100,1.962,109,1.591,111,1.962,113,1.591,130,2.126,131,2.491,152,1.169,155,0.886,174,1.341,180,3.627,181,1.777,204,1.868,208,2.542,220,2.676,221,2.142,240,1.591,247,1.777,248,3.547,258,1.591,260,2.84,261,2.06,262,2.06,263,4.111,264,1.341,265,2.06,266,3.292,267,3.292,268,1.591,269,2.06,270,1.777,271,2.06,272,1.777,273,3.292,274,2.06,275,2.06,276,2.06,277,2.06,278,1.591,279,1.777,280,1.777,281,1.777,282,2.06,283,2.06]],["t/41",[3,1.26,8,1.69,9,1.489,17,1.2,19,0.727,34,2.097,36,2.154,54,1.48,55,1.293,57,1.583,59,1.815,60,1.815,65,1.262,68,1.69,91,2.374,103,1.965,104,1.583,108,2.406,111,1.331,121,1.815,126,1.815,130,1.262,131,1.69,135,1.262,150,2.154,155,2.141,212,1.815,214,2.708,220,1.815,233,2.406,284,1.69,285,2.789,286,2.789,287,2.789,288,2.406,289,2.789,290,3.589,291,2.789,292,2.406,293,2.789,294,2.789,295,1.965,296,2.789,297,2.406,298,2.406,299,2.789,300,2.154,301,2.789,302,2.406]],["t/43",[0,0.449,3,1.251,7,1.424,17,0.71,19,0.43,22,1.788,39,0.747,45,2.032,47,0.832,54,0.817,55,0.513,56,0.881,57,2.002,59,1.074,60,1.074,61,1.274,65,0.747,67,1.925,69,0.676,91,2.446,96,0.881,100,0.787,103,1.163,104,1.559,112,1.274,126,1.074,127,3.809,130,1.862,131,1,135,1.597,148,1.274,155,2.122,160,0.881,190,1.559,212,2.677,214,1.074,270,1.424,272,2.37,303,1.274,304,1.424,305,1.424,306,1.424,307,1.65,308,1.65,309,3.941,310,1.65,311,1.274,312,1.65,313,1.65,314,1.274,315,1.424,316,2.747,317,1.65,318,1,319,1.65,320,1.65,321,1.424,322,1.65,323,3.528,324,1.243,325,1.65,326,1.65,327,1.65,328,1.424,329,1.274,330,1.65,331,1.424,332,1.424,333,1.274]],["t/45",[0,1.532,14,4.344,15,4.344,311,4.344,324,2.546,334,3.661]],["t/47",[16,1.784,54,1.561,55,1.632,91,2.259,160,2.803,214,4.164,246,3.417,335,5.25,336,4.529]],["t/49",[3,1.074,17,2.57,57,3.39,137,2.51,143,3.631,155,2.57,174,3.06,189,4.21,292,4.056,337,4.702,338,4.702,339,4.702,340,3.314]],["t/51",[67,2.196,91,2.42,155,2.42,290,4.852,298,4.852,341,5.624]],["t/53",[17,2.297,43,3.475,54,1.587,55,1.659,212,3.475,253,4.606,280,4.606,318,3.235,342,5.338]],["t/55",[0,1.317,1,2.615,3,0.684,6,1.415,8,1.11,10,1.04,16,1.018,19,0.478,33,1.415,34,0.924,37,1.581,38,1.815,39,1.356,40,2.111,41,1.193,44,1.11,45,2.075,46,1.581,47,0.924,49,1.11,55,0.57,65,0.83,69,2.243,71,0.924,81,1.291,84,0.874,109,1.415,119,1.949,121,2.472,124,1.415,130,1.356,131,1.815,132,2.313,160,0.978,164,2.584,173,1.581,187,1.7,215,1.193,216,2.584,218,1.581,246,1.193,284,1.815,329,1.415,334,1.193,343,1.832,344,1.832,345,1.832,346,1.581,347,1.581,348,1.832,349,1.832,350,1.832,351,1.832,352,1.581,353,1.832,354,1.832,355,1.581,356,1.832,357,1.581,358,2.995,359,1.832,360,1.832,361,2.995,362,1.832,363,1.832,364,1.832,365,1.832,366,1.832,367,1.832,368,1.832,369,1.832]],["t/57",[0,1.536,3,1.167,9,1.558,25,1.139,32,2.056,49,1.768,54,0.868,55,1.337,58,1.558,84,1.392,90,1.899,95,3.915,96,1.558,97,1.656,98,1.558,110,2.056,127,3.323,136,1.768,174,1.899,244,2.253,324,1.321,329,2.253,333,2.253,334,2.8,340,2.056,347,2.517,370,5.189,371,2.918,372,3.712,373,3.326,374,2.918,375,3.712,376,2.918,377,2.253,378,2.918,379,2.517,380,2.918,381,2.918]],["t/59",[97,3.372,101,2.995,206,4.188]],["t/61",[98,3.173,101,2.995,206,4.188]],["t/63",[54,1.643,68,3.348,95,3.596,121,3.596,142,4.767,303,4.268,324,2.501]],["t/65",[3,1.107,9,2.587,16,1.647,67,2.377,95,3.154,96,2.587,189,3.416,268,3.743,346,4.181,382,4.846,383,4.846,384,4.181,385,4.846,386,4.846]],["t/67",[3,1.422,9,3.078,16,1.231,54,1.077,67,1.414,68,2.195,84,2.97,90,3.269,95,2.357,100,1.728,112,3.878,154,2.552,204,2.055,246,2.357,295,2.552,305,3.124,318,2.195,370,4.332,377,4.452,387,3.621,388,3.621,389,3.621,390,3.621,391,3.621]],["t/69",[3,1.179,16,1.755,91,2.725,101,2.603,135,2.338,204,2.931,214,4.122,302,4.455,392,4.455]],["t/72",[25,2.016,65,2.338,98,3.381,101,2.603,264,3.361,300,3.988,373,4.122,393,4.455,394,4.455]],["t/74",[39,2.458,41,3.535,45,2.161,395,3.827,396,5.43]],["t/76",[397,6.175]],["t/78",[0,1.406,47,2.603,69,2.115,94,3.361,98,2.757,136,3.129,190,2.931,204,2.931,373,3.361,398,5.164,399,4.455]],["t/81",[25,2.016,65,2.338,97,3.594,101,2.603,264,3.361,300,3.988,373,4.122,393,4.455,394,4.455]],["t/83",[39,2.458,41,3.535,45,2.161,395,3.827,400,5.43]],["t/85",[401,6.175]],["t/87",[0,1.406,47,2.603,69,2.115,94,3.361,97,2.931,136,3.129,190,2.931,204,2.931,373,3.361,399,4.455,402,5.164]],["t/89",[0,1.665,8,1.13,19,0.486,25,0.728,34,0.94,35,1.44,38,1.13,39,0.844,44,2.686,45,1.451,53,1.058,58,0.996,71,0.94,81,1.314,84,1.834,91,1.307,97,1.058,98,0.996,100,0.89,101,0.94,111,0.89,119,2.884,130,0.844,133,1.44,135,1.375,137,0.996,140,1.609,141,2.346,152,1.724,154,1.314,160,1.622,170,1.609,174,1.214,177,1.314,215,1.977,229,1.609,244,2.346,278,1.44,279,3.316,284,2.329,309,1.609,311,1.44,315,2.621,324,1.375,336,1.609,352,2.621,355,1.609,379,1.609,403,1.865,404,3.844,405,4.432,406,1.865,407,1.865,408,1.865,409,1.865,410,3.038,411,1.865,412,1.865,413,1.865,414,3.844,415,1.865,416,1.865,417,1.865,418,1.865,419,1.865,420,1.865,421,1.865,422,1.609,423,1.609,424,1.865,425,1.865,426,1.865,427,1.865,428,1.865,429,1.865,430,1.865]],["t/92",[3,1.332,9,3.114,58,3.114,97,3.31]],["t/94",[58,3.173,98,3.173,384,5.127]],["t/96",[19,1.493,23,4.94,232,3.727,431,5.726,432,4.036]],["t/98",[3,1.284,54,1.672,68,3.408,91,2.42,433,5.624,434,5.624]],["t/100",[0,1.031,1,1.241,3,1.276,16,1.568,17,1.985,18,1.602,19,0.987,21,1.602,31,1.735,45,0.732,54,1.372,56,2.021,57,1.397,59,1.602,60,1.602,61,1.901,90,3.002,92,3.266,100,1.175,130,2.53,134,2.124,137,2.463,152,1.397,212,1.602,221,1.602,234,1.901,246,1.602,254,2.124,255,3.562,257,1.901,264,1.602,278,1.901,314,1.901,318,1.492,324,1.115,332,2.124,334,2.464,392,2.124,435,2.462,436,2.462,437,2.462,438,2.462,439,2.462,440,2.462,441,2.462,442,2.462,443,2.462,444,2.462,445,2.462,446,2.462,447,2.462,448,2.462,449,2.462]],["t/102",[0,0.485,3,1.087,16,0.605,19,0.97,24,1.536,27,1.375,38,1.773,45,2.029,54,1.608,55,0.553,65,1.685,67,1.998,71,0.898,84,2.057,90,1.904,91,1.855,103,1.255,111,0.85,135,2.317,148,1.375,150,2.259,152,2.446,155,1.259,166,1.536,175,1.536,183,2.423,187,2.113,190,2.446,204,1.011,241,1.536,324,2.155,334,1.159,340,1.255,372,2.524,375,1.536,450,1.781,451,1.781,452,1.781,453,1.536,454,1.781,455,3.719,456,2.925,457,1.781,458,1.375,459,1.781,460,2.925,461,2.925,462,1.781,463,1.536,464,1.781,465,1.781,466,1.781,467,1.781,468,1.781,469,1.781]],["t/104",[54,1.734,59,3.796,324,2.64,470,5.832]],["t/106",[3,0.522,11,1.61,16,0.776,22,2.324,31,1.61,45,1.605,54,0.679,55,0.71,56,1.219,67,0.892,81,1.61,84,1.09,96,1.219,98,1.219,104,2.823,135,1.034,215,1.486,221,1.486,295,2.517,303,1.764,314,1.764,471,2.284,472,1.97,473,2.284,474,1.97,475,2.284,476,5.722,477,5.722,478,5.722,479,2.284,480,5.722,481,5.397,482,2.284,483,2.284,484,2.284,485,2.284,486,2.284,487,2.284,488,2.284,489,2.284,490,2.284,491,4.973,492,4.973,493,2.284,494,2.284,495,2.284,496,2.284,497,2.284,498,2.284]],["t/108",[22,3.614,40,2.96,49,2.545,56,2.243,58,2.243,67,1.64,84,2.004,135,1.902,183,2.734,190,2.384,295,2.96,324,1.902,328,3.624,377,3.244,423,3.624,455,3.624,472,3.624,474,3.624,499,4.2,500,4.2,501,4.2,502,4.2,503,4.2,504,4.2]],["t/110",[130,2.64,324,2.64,505,5.832,506,5.832]],["t/112",[0,1.3,13,2.892,19,1.572,39,2.161,58,2.548,133,3.686,177,3.364,232,3.107,304,4.118,324,2.161,432,4.25,507,4.773,508,4.773,509,4.773]],["t/115",[39,2.458,41,3.535,45,2.161,395,3.827,510,5.43]],["t/117",[0,1.267,3,0.742,5,2.509,13,1.968,19,1.416,27,2.509,39,1.471,44,2.819,45,1.867,94,2.114,101,1.637,111,1.55,130,1.471,155,2.001,187,1.844,193,2.802,228,2.802,260,2.802,264,2.114,318,1.968,432,3.83,458,2.509,511,3.248,512,3.248,513,3.248,514,3.248,515,4.651,516,3.248,517,3.248,518,3.248,519,3.248,520,2.802,521,3.248,522,2.509,523,1.968]],["t/119",[10,2.079,19,1.512,44,2.22,55,1.803,69,1.501,71,2.551,111,1.748,115,2.829,126,2.385,130,2.292,136,2.22,138,3.161,141,2.829,220,2.385,232,2.385,255,3.91,284,2.22,297,3.161,422,3.161,432,3.568,520,3.161,522,2.829,523,2.22,524,3.664,525,3.664,526,3.664,527,3.664,528,3.664]],["t/121",[0,1.431,3,1.2,9,1.633,10,1.736,13,1.854,34,1.542,39,1.385,52,2.156,53,2.528,58,1.633,80,2.363,89,2.639,110,2.156,111,1.46,119,3.755,130,2.378,131,1.854,135,1.385,180,2.363,288,2.639,331,2.639,333,2.363,453,2.639,458,2.363,523,3.496,529,3.059,530,3.059,531,2.639,532,3.059,533,3.059,534,3.059,535,3.059,536,3.059,537,3.059,538,3.059,539,3.059,540,3.059,541,3.059,542,3.059,543,3.059]],["t/123",[39,2.679,42,3.997,45,2.159,47,2.335,48,3.578,49,2.807,357,3.997,395,3.265,523,2.807,544,4.632,545,4.632,546,4.632]],["t/125",[0,0.533,3,0.722,19,1.036,45,2.221,48,1.512,55,0.608,67,1.234,69,1.294,80,2.44,84,0.934,91,1.962,96,1.045,122,1.689,136,1.186,152,1.793,154,1.38,155,1.962,183,2.057,186,2.726,187,1.793,208,1.512,220,1.274,232,1.274,240,1.512,242,1.689,257,2.44,281,1.689,284,1.186,306,1.689,321,1.689,340,1.38,523,2.763,531,2.726,547,1.958,548,1.958,549,1.958,550,1.958,551,1.958,552,1.958,553,1.958,554,1.958,555,1.958,556,1.958,557,1.958,558,1.958,559,1.958,560,1.958,561,1.958,562,1.958,563,1.958,564,1.958,565,1.958,566,1.958,567,1.958,568,1.958,569,1.958,570,1.958,571,1.958]],["t/127",[0,1.046,3,1.358,16,1.778,17,1.653,19,1.002,21,2.501,25,1.5,38,2.328,57,2.181,71,1.937,94,2.501,137,2.051,206,2.708,221,2.501,256,3.315,258,2.967,268,2.967,284,2.328,318,2.328,463,3.315,522,2.967,523,3.169,572,3.842,573,3.842,574,3.842,575,3.842,576,3.842,577,3.842]]],"invertedIndex":[["",{"_index":45,"t":{"6":{"position":[[116,1],[131,1],[133,3],[201,1],[203,1]]},"8":{"position":[[9,1],[25,1]]},"14":{"position":[[346,1],[362,1],[368,1],[387,1],[422,1],[452,1],[454,1]]},"20":{"position":[[748,2],[807,1],[827,1],[848,2],[852,1],[862,2],[941,1],[961,1],[1133,1],[1149,1],[1221,1],[1247,1],[1249,2],[1269,1],[1290,1],[1292,2]]},"22":{"position":[[537,1],[555,1],[587,1]]},"33":{"position":[[167,2],[184,1],[258,1],[266,1],[283,1],[285,2],[386,1],[403,1],[723,1],[790,2],[845,1],[847,1]]},"35":{"position":[[187,1],[250,1],[463,1],[501,1],[530,1],[565,1]]},"39":{"position":[[960,1],[977,1],[1047,1],[1063,2],[1070,1],[1083,1],[1109,1],[1119,1],[1121,1]]},"43":{"position":[[267,1],[269,1],[283,1],[285,1],[298,1],[300,1],[321,1],[323,1],[342,1],[344,1],[718,2],[743,1],[753,1],[771,1],[773,2],[784,2],[803,2],[812,2],[838,2],[848,2]]},"55":{"position":[[585,1],[598,1],[626,1],[641,1],[643,2],[693,1],[695,1],[720,1],[735,1],[737,2],[783,1],[785,1],[787,1],[799,1],[811,1],[855,1],[857,1],[859,1],[1029,1],[1031,2]]},"74":{"position":[[11,1],[26,1],[79,1],[81,1]]},"83":{"position":[[11,1],[26,1],[83,1],[85,1]]},"89":{"position":[[988,1],[1040,1],[1115,1],[1219,1],[1221,1]]},"100":{"position":[[730,1]]},"102":{"position":[[408,1],[422,1],[514,1],[516,2],[539,1],[541,1],[713,1],[833,2],[903,1],[917,1],[1009,1],[1011,2],[1034,1],[1102,1],[1117,1],[1119,2],[1142,1],[1186,1]]},"106":{"position":[[297,2],[503,2],[591,2],[679,2],[767,2]]},"115":{"position":[[11,1],[26,1],[76,1],[78,1]]},"117":{"position":[[20,1],[32,1],[83,1],[108,3],[112,1]]},"123":{"position":[[70,1],[83,1],[98,1],[169,1],[171,1],[173,1]]},"125":{"position":[[240,1],[268,1],[294,1],[313,2],[334,1],[355,1],[389,1],[421,1],[445,1],[447,1],[449,2],[452,3],[456,1],[569,1],[571,2],[574,3],[607,2],[682,1],[692,2],[709,2],[721,2],[738,2],[745,2],[757,2],[770,2],[778,1],[780,1],[885,1],[887,2],[890,3],[952,1],[1079,1],[1081,1]]}}}],["03",{"_index":477,"t":{"106":{"position":[[239,2],[315,2],[445,2],[533,2],[621,2],[709,2]]}}}],["05",{"_index":478,"t":{"106":{"position":[[242,2],[318,2],[448,2],[536,2],[624,2],[712,2]]}}}],["0500",{"_index":480,"t":{"106":{"position":[[261,4],[337,4],[467,4],[555,4],[643,4],[731,4]]}}}],["08:48:03.864138",{"_index":479,"t":{"106":{"position":[[245,15]]}}}],["08:48:04.622452",{"_index":482,"t":{"106":{"position":[[321,15]]}}}],["08:48:09.999884",{"_index":490,"t":{"106":{"position":[[451,15]]}}}],["08:48:11.333941",{"_index":494,"t":{"106":{"position":[[539,15]]}}}],["08:48:13.104265",{"_index":496,"t":{"106":{"position":[[627,15]]}}}],["08:48:13.568351",{"_index":497,"t":{"106":{"position":[[715,15]]}}}],["1",{"_index":493,"t":{"106":{"position":[[526,1]]}}}],["2",{"_index":495,"t":{"106":{"position":[[614,1]]}}}],["2.0",{"_index":199,"t":{"24":{"position":[[78,3]]}}}],["2023",{"_index":476,"t":{"106":{"position":[[234,4],[310,4],[440,4],[528,4],[616,4],[704,4]]}}}],["2b37",{"_index":486,"t":{"106":{"position":[[412,4]]}}}],["3",{"_index":303,"t":{"43":{"position":[[10,1]]},"63":{"position":[[42,1]]},"106":{"position":[[702,1]]}}}],["3rd",{"_index":451,"t":{"102":{"position":[[82,3]]}}}],["4",{"_index":498,"t":{"106":{"position":[[790,1]]}}}],["4189",{"_index":487,"t":{"106":{"position":[[417,4]]}}}],["63bc7172d01b",{"_index":489,"t":{"106":{"position":[[427,12]]}}}],["7d3188f7",{"_index":485,"t":{"106":{"position":[[403,8]]}}}],["9f92",{"_index":488,"t":{"106":{"position":[[422,4]]}}}],["abov",{"_index":246,"t":{"35":{"position":[[291,6]]},"47":{"position":[[126,6]]},"55":{"position":[[918,6]]},"67":{"position":[[130,5]]},"100":{"position":[[834,6]]}}}],["accept",{"_index":306,"t":{"43":{"position":[[83,6]]},"125":{"position":[[316,6]]}}}],["access",{"_index":277,"t":{"39":{"position":[[868,7]]}}}],["accordingli",{"_index":575,"t":{"127":{"position":[[233,12]]}}}],["actual",{"_index":89,"t":{"16":{"position":[[12,8]]},"121":{"position":[[143,6]]}}}],["ad",{"_index":40,"t":{"6":{"position":[[32,5]]},"27":{"position":[[71,6]]},"55":{"position":[[407,5],[1014,6]]},"108":{"position":[[67,5]]}}}],["add",{"_index":47,"t":{"6":{"position":[[180,5]]},"16":{"position":[[70,3]]},"29":{"position":[[110,3]]},"31":{"position":[[178,3]]},"43":{"position":[[969,3]]},"55":{"position":[[449,4]]},"78":{"position":[[8,3]]},"87":{"position":[[8,3]]},"123":{"position":[[148,5]]}}}],["aim",{"_index":572,"t":{"127":{"position":[[28,4]]}}}],["allow",{"_index":8,"t":{"2":{"position":[[77,5]]},"16":{"position":[[224,6]]},"29":{"position":[[178,6]]},"41":{"position":[[136,6]]},"55":{"position":[[947,5]]},"89":{"position":[[659,5]]}}}],["android",{"_index":57,"t":{"10":{"position":[[106,7]]},"22":{"position":[[29,8],[99,8],[491,7]]},"41":{"position":[[423,7]]},"43":{"position":[[259,7],[776,7],[1130,7]]},"49":{"position":[[19,7],[168,8]]},"100":{"position":[[157,7]]},"127":{"position":[[123,7]]}}}],["android'",{"_index":573,"t":{"127":{"position":[[170,9]]}}}],["annot",{"_index":538,"t":{"121":{"position":[[379,11]]}}}],["api",{"_index":119,"t":{"20":{"position":[[109,3]]},"31":{"position":[[9,3]]},"55":{"position":[[299,4],[486,4]]},"89":{"position":[[196,3],[293,3],[590,3],[790,3]]},"121":{"position":[[109,4],[244,4],[303,4],[403,3]]}}}],["api(\"co.touchlab:kermit",{"_index":360,"t":{"55":{"position":[[744,23]]}}}],["appli",{"_index":233,"t":{"33":{"position":[[651,7]]},"41":{"position":[[193,5]]}}}],["applic",{"_index":530,"t":{"121":{"position":[[65,11]]}}}],["argument",{"_index":171,"t":{"22":{"position":[[56,10]]}}}],["artifact",{"_index":117,"t":{"20":{"position":[[20,8]]}}}],["assert",{"_index":533,"t":{"121":{"position":[[253,9]]}}}],["assertequals(\"mi",{"_index":570,"t":{"125":{"position":[[1029,16]]}}}],["assertequals(\"th",{"_index":568,"t":{"125":{"position":[[954,17]]}}}],["assertequals(severity.info",{"_index":569,"t":{"125":{"position":[[991,27]]}}}],["assertnull(throw",{"_index":571,"t":{"125":{"position":[[1057,21]]}}}],["asserttru",{"_index":562,"t":{"125":{"position":[[616,12]]}}}],["atag",{"_index":323,"t":{"43":{"position":[[745,7],[815,7],[858,6]]}}}],["atom",{"_index":271,"t":{"39":{"position":[[708,6]]}}}],["avail",{"_index":230,"t":{"33":{"position":[[499,9],[547,9]]}}}],["avoid",{"_index":145,"t":{"20":{"position":[[649,5]]}}}],["awar",{"_index":66,"t":{"12":{"position":[[39,5]]},"20":{"position":[[103,5]]}}}],["back",{"_index":380,"t":{"57":{"position":[[419,4]]}}}],["bad",{"_index":350,"t":{"55":{"position":[[385,3]]}}}],["base",{"_index":110,"t":{"18":{"position":[[136,5]]},"22":{"position":[[338,4]]},"57":{"position":[[229,5]]},"121":{"position":[[410,5]]}}}],["baselogger(loggerconfiginit(platformlogwrit",{"_index":425,"t":{"89":{"position":[[990,49]]}}}],["basic",{"_index":62,"t":{"12":{"position":[[4,5]]},"14":{"position":[[306,5]]},"20":{"position":[[1087,5]]}}}],["befor",{"_index":458,"t":{"102":{"position":[[617,6]]},"117":{"position":[[165,6]]},"121":{"position":[[485,6]]}}}],["below",{"_index":241,"t":{"35":{"position":[[38,5]]},"102":{"position":[[378,6]]}}}],["better",{"_index":88,"t":{"14":{"position":[[444,7]]},"39":{"position":[[834,7]]}}}],["between",{"_index":308,"t":{"43":{"position":[[150,7]]}}}],["boolean",{"_index":461,"t":{"102":{"position":[[705,7],[1094,7]]}}}],["both",{"_index":142,"t":{"20":{"position":[[576,4]]},"63":{"position":[[0,4]]}}}],["box",{"_index":15,"t":{"2":{"position":[[167,4]]},"4":{"position":[[97,3]]},"45":{"position":[[49,4]]}}}],["breadcrumb",{"_index":384,"t":{"65":{"position":[[73,10]]},"94":{"position":[[8,10]]}}}],["breadcrumb/log",{"_index":374,"t":{"57":{"position":[[98,14]]}}}],["breakdown",{"_index":310,"t":{"43":{"position":[[177,9]]}}}],["breedcallbackviewmodel",{"_index":237,"t":{"33":{"position":[[725,23]]}}}],["bugsnag",{"_index":98,"t":{"16":{"position":[[269,8]]},"57":{"position":[[569,8]]},"61":{"position":[[4,7]]},"72":{"position":[[28,7],[84,7]]},"78":{"position":[[29,8]]},"89":{"position":[[719,8]]},"94":{"position":[[0,7]]},"106":{"position":[[373,9]]}}}],["bugsnag:2.0.3",{"_index":396,"t":{"74":{"position":[[63,15]]}}}],["bugsnagkotlin.setcustomvalue(\"somekey",{"_index":398,"t":{"78":{"position":[[87,39]]}}}],["cach",{"_index":385,"t":{"65":{"position":[[84,6]]}}}],["call",{"_index":69,"t":{"14":{"position":[[21,5],[271,4]]},"20":{"position":[[218,7],[298,7]]},"22":{"position":[[321,5]]},"31":{"position":[[98,4]]},"33":{"position":[[134,4],[525,5],[710,5]]},"35":{"position":[[301,4]]},"37":{"position":[[66,4]]},"43":{"position":[[725,4]]},"55":{"position":[[8,4],[80,7],[165,7],[338,7],[422,6],[463,4],[960,4]]},"78":{"position":[[62,4]]},"87":{"position":[[66,4]]},"119":{"position":[[205,4]]},"125":{"position":[[92,7],[610,5]]}}}],["can't",{"_index":261,"t":{"39":{"position":[[114,5]]}}}],["care",{"_index":433,"t":{"98":{"position":[[16,4]]}}}],["case",{"_index":131,"t":{"20":{"position":[[284,4]]},"39":{"position":[[13,6],[369,4],[480,5]]},"41":{"position":[[602,6]]},"43":{"position":[[552,5]]},"55":{"position":[[330,4],[510,5]]},"121":{"position":[[543,6]]}}}],["catch(t",{"_index":83,"t":{"14":{"position":[[389,8]]}}}],["central",{"_index":213,"t":{"29":{"position":[[189,7]]}}}],["chang",{"_index":180,"t":{"22":{"position":[[327,6]]},"39":{"position":[[66,6],[123,7],[279,7],[433,7]]},"121":{"position":[[465,6]]}}}],["check",{"_index":27,"t":{"2":{"position":[[289,5]]},"102":{"position":[[600,5]]},"117":{"position":[[464,8]]}}}],["choic",{"_index":415,"t":{"89":{"position":[[304,7]]}}}],["choos",{"_index":227,"t":{"33":{"position":[[422,6]]}}}],["class",{"_index":183,"t":{"22":{"position":[[470,5],[509,5]]},"33":{"position":[[19,5]]},"102":{"position":[[205,5],[385,5],[846,5]]},"108":{"position":[[19,5]]},"125":{"position":[[65,7],[220,5]]}}}],["click",{"_index":491,"t":{"106":{"position":[[513,5],[601,5],[689,5],[777,5]]}}}],["client",{"_index":125,"t":{"20":{"position":[[190,8]]}}}],["clutter",{"_index":339,"t":{"49":{"position":[[64,9]]}}}],["co.touchlab.kermit",{"_index":445,"t":{"100":{"position":[[635,18]]}}}],["co.touchlab.kermit.logg",{"_index":430,"t":{"89":{"position":[[1277,25]]}}}],["cocoapod",{"_index":362,"t":{"55":{"position":[[789,9]]}}}],["code",{"_index":10,"t":{"2":{"position":[[110,4]]},"14":{"position":[[37,4]]},"33":{"position":[[517,4]]},"37":{"position":[[84,5],[151,4]]},"55":{"position":[[36,5]]},"119":{"position":[[362,5]]},"121":{"position":[[77,4]]}}}],["collect",{"_index":243,"t":{"35":{"position":[[105,10]]}}}],["come",{"_index":508,"t":{"112":{"position":[[25,5]]}}}],["common",{"_index":104,"t":{"18":{"position":[[23,6]]},"20":{"position":[[273,6]]},"22":{"position":[[19,6],[484,6]]},"37":{"position":[[77,6]]},"41":{"position":[[199,6]]},"43":{"position":[[325,6],[841,6]]},"106":{"position":[[506,6],[594,6],[682,6],[770,6]]}}}],["commonli",{"_index":312,"t":{"43":{"position":[[208,8]]}}}],["commonmain",{"_index":41,"t":{"6":{"position":[[46,10],[105,10]]},"55":{"position":[[604,10]]},"74":{"position":[[0,10]]},"83":{"position":[[0,10]]},"115":{"position":[[0,10]]}}}],["commontest",{"_index":545,"t":{"123":{"position":[[72,10]]}}}],["commonwrit",{"_index":92,"t":{"16":{"position":[[125,12]]},"100":{"position":[[63,12],[374,16]]}}}],["compat",{"_index":336,"t":{"47":{"position":[[37,10]]},"89":{"position":[[676,10]]}}}],["complex",{"_index":35,"t":{"4":{"position":[[54,8]]},"37":{"position":[[180,7]]},"89":{"position":[[1234,7]]}}}],["compon",{"_index":63,"t":{"12":{"position":[[10,10]]},"33":{"position":[[626,11]]}}}],["compos",{"_index":12,"t":{"2":{"position":[[132,10]]}}}],["compromis",{"_index":351,"t":{"55":{"position":[[389,11]]}}}],["config",{"_index":36,"t":{"4":{"position":[[79,6]]},"39":{"position":[[77,7],[384,6],[666,6],[892,7],[970,6]]},"41":{"position":[[495,6]]}}}],["configur",{"_index":25,"t":{"2":{"position":[[274,10]]},"4":{"position":[[0,13]]},"10":{"position":[[75,10]]},"14":{"position":[[244,9]]},"18":{"position":[[247,13]]},"22":{"position":[[622,10],[738,14]]},"29":{"position":[[208,14]]},"33":{"position":[[120,9]]},"37":{"position":[[188,14]]},"57":{"position":[[238,14]]},"72":{"position":[[18,9]]},"81":{"position":[[18,9]]},"89":{"position":[[72,13]]},"127":{"position":[[212,9]]}}}],["conflict",{"_index":417,"t":{"89":{"position":[[450,8]]}}}],["consid",{"_index":542,"t":{"121":{"position":[[514,8]]}}}],["consol",{"_index":61,"t":{"10":{"position":[[186,8]]},"43":{"position":[[290,7]]},"100":{"position":[[232,7]]}}}],["consolewrit",{"_index":437,"t":{"100":{"position":[[211,13]]}}}],["construct",{"_index":330,"t":{"43":{"position":[[1108,11]]}}}],["context",{"_index":356,"t":{"55":{"position":[[569,8]]}}}],["control",{"_index":108,"t":{"18":{"position":[[97,7]]},"41":{"position":[[150,7]]}}}],["conveni",{"_index":239,"t":{"33":{"position":[[793,11]]},"35":{"position":[[334,11]]}}}],["convent",{"_index":337,"t":{"49":{"position":[[27,11]]}}}],["core",{"_index":405,"t":{"89":{"position":[[146,5],[233,5],[636,4],[899,4]]}}}],["correspond",{"_index":72,"t":{"14":{"position":[[124,13]]}}}],["could'v",{"_index":86,"t":{"14":{"position":[[430,8]]}}}],["count",{"_index":492,"t":{"106":{"position":[[519,6],[607,6],[695,6],[783,6]]}}}],["cover",{"_index":116,"t":{"18":{"position":[[228,5]]}}}],["crash",{"_index":95,"t":{"16":{"position":[[239,5]]},"57":{"position":[[0,5],[131,5],[297,5],[339,5],[385,5]]},"63":{"position":[[5,5]]},"65":{"position":[[56,5]]},"67":{"position":[[70,5]]}}}],["crashkio",{"_index":373,"t":{"57":{"position":[[42,10],[429,10],[516,9]]},"72":{"position":[[40,9],[74,9]]},"78":{"position":[[67,9]]},"81":{"position":[[44,9],[78,9]]},"87":{"position":[[71,9]]}}}],["crashlyt",{"_index":97,"t":{"16":{"position":[[253,11]]},"57":{"position":[[553,11]]},"59":{"position":[[4,11]]},"81":{"position":[[28,11],[88,11]]},"87":{"position":[[29,12]]},"89":{"position":[[703,11]]},"92":{"position":[[0,11]]}}}],["crashlytics:2.0.3",{"_index":400,"t":{"83":{"position":[[63,19]]}}}],["crashlyticskotlin.setcustomvalue(\"somekey",{"_index":402,"t":{"87":{"position":[[91,43]]}}}],["creat",{"_index":100,"t":{"16":{"position":[[328,6]]},"22":{"position":[[359,6],[416,6]]},"33":{"position":[[81,6]]},"35":{"position":[[257,8],[358,6]]},"37":{"position":[[102,6]]},"39":{"position":[[175,8],[463,8],[913,6]]},"43":{"position":[[1218,6]]},"67":{"position":[[319,6]]},"89":{"position":[[574,6]]},"100":{"position":[[266,7]]}}}],["creation",{"_index":147,"t":{"20":{"position":[[673,8]]}}}],["current",{"_index":333,"t":{"43":{"position":[[1160,9]]},"57":{"position":[[526,9]]},"121":{"position":[[395,7]]}}}],["custom",{"_index":190,"t":{"22":{"position":[[670,9]]},"29":{"position":[[119,6]]},"43":{"position":[[933,6],[1227,6]]},"78":{"position":[[12,6]]},"87":{"position":[[12,6]]},"102":{"position":[[22,6],[543,6],[728,6],[1027,6]]},"108":{"position":[[177,6]]}}}],["d",{"_index":76,"t":{"14":{"position":[[211,4]]}}}],["date",{"_index":327,"t":{"43":{"position":[[983,4]]}}}],["debug",{"_index":386,"t":{"65":{"position":[[132,5]]}}}],["decid",{"_index":434,"t":{"98":{"position":[[24,8]]}}}],["declar",{"_index":525,"t":{"119":{"position":[[59,8]]}}}],["default",{"_index":16,"t":{"2":{"position":[[184,8]]},"4":{"position":[[71,7]]},"10":{"position":[[3,8]]},"20":{"position":[[124,7],[235,7]]},"22":{"position":[[81,7],[250,7],[343,7]]},"27":{"position":[[82,7]]},"31":{"position":[[75,7]]},"33":{"position":[[60,7]]},"47":{"position":[[75,8]]},"55":{"position":[[130,7],[522,7]]},"65":{"position":[[95,7]]},"67":{"position":[[214,7]]},"69":{"position":[[97,7]]},"100":{"position":[[3,7],[27,7],[547,7]]},"102":{"position":[[115,7]]},"106":{"position":[[12,7]]},"127":{"position":[[4,7],[131,8]]}}}],["default_min_sever",{"_index":250,"t":{"35":{"position":[[465,22]]}}}],["defaultformatt",{"_index":392,"t":{"69":{"position":[[73,16]]},"100":{"position":[[732,18]]}}}],["defaultlogformatt",{"_index":320,"t":{"43":{"position":[[630,19]]}}}],["defin",{"_index":118,"t":{"20":{"position":[[43,7]]},"35":{"position":[[13,7]]}}}],["definit",{"_index":149,"t":{"20":{"position":[[725,11]]}}}],["depend",{"_index":39,"t":{"6":{"position":[[11,10],[118,12]]},"43":{"position":[[695,9]]},"55":{"position":[[628,12],[722,12]]},"74":{"position":[[13,12]]},"83":{"position":[[13,12]]},"89":{"position":[[906,10]]},"112":{"position":[[116,10]]},"115":{"position":[[13,12]]},"117":{"position":[[485,12]]},"121":{"position":[[23,11]]},"123":{"position":[[20,6],[85,12]]}}}],["deprec",{"_index":202,"t":{"24":{"position":[[100,10]]}}}],["design",{"_index":215,"t":{"31":{"position":[[16,8]]},"37":{"position":[[121,8]]},"55":{"position":[[228,8]]},"89":{"position":[[297,6],[477,7]]},"106":{"position":[[37,8]]}}}],["detail",{"_index":302,"t":{"41":{"position":[[699,7]]},"69":{"position":[[27,7]]}}}],["develop",{"_index":31,"t":{"2":{"position":[[323,10]]},"10":{"position":[[90,12]]},"100":{"position":[[614,12]]},"106":{"position":[[56,12]]}}}],["differ",{"_index":32,"t":{"4":{"position":[[18,9]]},"14":{"position":[[96,9],[141,9]]},"16":{"position":[[43,9]]},"57":{"position":[[366,9]]}}}],["difficult",{"_index":172,"t":{"22":{"position":[[120,9]]}}}],["directli",{"_index":136,"t":{"20":{"position":[[404,9]]},"57":{"position":[[313,9]]},"78":{"position":[[77,9]]},"87":{"position":[[81,9]]},"119":{"position":[[210,9]]},"125":{"position":[[831,8]]}}}],["disabl",{"_index":391,"t":{"67":{"position":[[350,7]]}}}],["discuss",{"_index":192,"t":{"22":{"position":[[708,7]]}}}],["dispatch",{"_index":70,"t":{"14":{"position":[[46,10]]}}}],["display",{"_index":191,"t":{"22":{"position":[[686,7]]}}}],["doc",{"_index":300,"t":{"41":{"position":[[673,3]]},"72":{"position":[[101,4]]},"81":{"position":[[109,4]]}}}],["document",{"_index":196,"t":{"24":{"position":[[24,13]]}}}],["doesn't",{"_index":453,"t":{"102":{"position":[[138,7]]},"121":{"position":[[118,7]]}}}],["domain",{"_index":378,"t":{"57":{"position":[[376,8]]}}}],["don't",{"_index":126,"t":{"20":{"position":[[204,5]]},"22":{"position":[[192,5]]},"41":{"position":[[231,5]]},"43":{"position":[[1079,5]]},"119":{"position":[[107,5]]}}}],["done",{"_index":441,"t":{"100":{"position":[[441,4]]}}}],["dramat",{"_index":540,"t":{"121":{"position":[[472,12]]}}}],["dure",{"_index":438,"t":{"100":{"position":[[308,6]]}}}],["e",{"_index":78,"t":{"14":{"position":[[226,4]]}}}],["each",{"_index":56,"t":{"10":{"position":[[53,4]]},"20":{"position":[[335,4]]},"22":{"position":[[312,4]]},"33":{"position":[[705,4]]},"43":{"position":[[998,4]]},"100":{"position":[[49,4],[413,4]]},"106":{"position":[[69,4]]},"108":{"position":[[204,4]]}}}],["earlier",{"_index":347,"t":{"55":{"position":[[196,7]]},"57":{"position":[[258,7]]}}}],["easi",{"_index":23,"t":{"2":{"position":[[255,4]]},"96":{"position":[[27,4]]}}}],["easier",{"_index":549,"t":{"125":{"position":[[151,7]]}}}],["easili",{"_index":176,"t":{"22":{"position":[[233,7],[694,7]]}}}],["emoji",{"_index":472,"t":{"106":{"position":[[106,6]]},"108":{"position":[[61,5]]}}}],["empti",{"_index":178,"t":{"22":{"position":[[268,5]]}}}],["encourag",{"_index":205,"t":{"24":{"position":[[140,9]]}}}],["end",{"_index":158,"t":{"20":{"position":[[1011,3]]}}}],["entri",{"_index":257,"t":{"37":{"position":[[240,5]]},"100":{"position":[[469,5]]},"125":{"position":[[502,5],[823,7]]}}}],["environ",{"_index":33,"t":{"4":{"position":[[28,12]]},"31":{"position":[[121,13]]},"55":{"position":[[99,12]]}}}],["equal",{"_index":387,"t":{"67":{"position":[[118,5]]}}}],["error(messag",{"_index":428,"t":{"89":{"position":[[1121,14]]}}}],["especi",{"_index":520,"t":{"117":{"position":[[440,10]]},"119":{"position":[[303,10]]}}}],["etc",{"_index":164,"t":{"20":{"position":[[1252,3]]},"55":{"position":[[646,3],[740,3]]}}}],["evalu",{"_index":139,"t":{"20":{"position":[[495,9],[686,11]]}}}],["everybodi",{"_index":419,"t":{"89":{"position":[[512,9]]}}}],["everyth",{"_index":555,"t":{"125":{"position":[[323,10]]}}}],["everywher",{"_index":231,"t":{"33":{"position":[[557,11]]}}}],["ex",{"_index":169,"t":{"20":{"position":[[1327,3]]}}}],["exampl",{"_index":160,"t":{"20":{"position":[[1162,8]]},"22":{"position":[[407,8]]},"31":{"position":[[139,7]]},"33":{"position":[[573,8]]},"43":{"position":[[617,8]]},"47":{"position":[[117,8]]},"55":{"position":[[910,7]]},"89":{"position":[[810,8],[1242,8]]}}}],["except",{"_index":377,"t":{"57":{"position":[[181,10]]},"67":{"position":[[199,10],[329,9],[366,9]]},"108":{"position":[[145,11]]}}}],["exist",{"_index":418,"t":{"89":{"position":[[468,8]]}}}],["expect",{"_index":446,"t":{"100":{"position":[[654,6]]}}}],["expect/actu",{"_index":254,"t":{"37":{"position":[[26,13],[275,13]]},"100":{"position":[[495,13]]}}}],["experimentalkermitapi",{"_index":537,"t":{"121":{"position":[[356,22]]}}}],["explain",{"_index":301,"t":{"41":{"position":[[677,8]]}}}],["explicit",{"_index":353,"t":{"55":{"position":[[454,8]]}}}],["explicitli",{"_index":365,"t":{"55":{"position":[[1003,10]]}}}],["export",{"_index":218,"t":{"31":{"position":[[186,6]]},"55":{"position":[[878,6]]}}}],["export(\"co.touchlab:kermit",{"_index":364,"t":{"55":{"position":[[813,26]]}}}],["extend",{"_index":24,"t":{"2":{"position":[[263,6]]},"102":{"position":[[184,6]]}}}],["extens",{"_index":422,"t":{"89":{"position":[[687,10]]},"119":{"position":[[180,9]]}}}],["factori",{"_index":255,"t":{"37":{"position":[[40,7],[289,7]]},"100":{"position":[[509,7],[555,7],[781,7]]},"119":{"position":[[70,7],[142,8]]}}}],["fail",{"_index":167,"t":{"20":{"position":[[1282,7],[1318,8]]}}}],["fairli",{"_index":37,"t":{"4":{"position":[[104,6]]},"55":{"position":[[180,6]]}}}],["familiar",{"_index":107,"t":{"18":{"position":[[79,9]]}}}],["feedback",{"_index":414,"t":{"89":{"position":[[274,8],[341,8],[395,8]]}}}],["feel",{"_index":338,"t":{"49":{"position":[[59,4]]}}}],["few",{"_index":311,"t":{"43":{"position":[[204,3]]},"45":{"position":[[18,3]]},"89":{"position":[[253,3]]}}}],["field",{"_index":181,"t":{"22":{"position":[[425,5]]},"39":{"position":[[673,6]]}}}],["filter",{"_index":516,"t":{"117":{"position":[[298,6]]}}}],["firebas",{"_index":381,"t":{"57":{"position":[[544,8]]}}}],["first",{"_index":393,"t":{"72":{"position":[[4,5]]},"81":{"position":[[4,5]]}}}],["fit",{"_index":175,"t":{"22":{"position":[[205,3]]},"102":{"position":[[146,3]]}}}],["flexibl",{"_index":286,"t":{"41":{"position":[[44,9]]}}}],["follow",{"_index":103,"t":{"18":{"position":[[16,6]]},"41":{"position":[[522,10]]},"43":{"position":[[669,9]]},"102":{"position":[[822,10]]}}}],["form",{"_index":159,"t":{"20":{"position":[[1093,5]]}}}],["format",{"_index":214,"t":{"29":{"position":[[197,10]]},"41":{"position":[[16,10],[206,11]]},"43":{"position":[[988,6]]},"47":{"position":[[21,6],[97,9]]},"69":{"position":[[12,10],[45,6]]}}}],["formatt",{"_index":298,"t":{"41":{"position":[[644,11]]},"51":{"position":[[5,9]]}}}],["framework",{"_index":363,"t":{"55":{"position":[[801,9]]}}}],["friendli",{"_index":216,"t":{"31":{"position":[[38,9]]},"55":{"position":[[249,9],[290,8]]}}}],["fun",{"_index":152,"t":{"20":{"position":[[779,3],[890,3]]},"35":{"position":[[390,3]]},"39":{"position":[[1085,3]]},"89":{"position":[[1042,3],[1117,3]]},"100":{"position":[[661,3]]},"102":{"position":[[433,3],[656,3],[928,3],[1045,3]]},"125":{"position":[[534,3],[846,3]]}}}],["function",{"_index":137,"t":{"20":{"position":[[432,8],[478,8],[618,8],[760,8],[982,8],[1022,8]]},"33":{"position":[[805,8]]},"35":{"position":[[346,8]]},"37":{"position":[[48,9]]},"49":{"position":[[146,8]]},"89":{"position":[[107,13]]},"100":{"position":[[517,9],[563,8],[789,8]]},"127":{"position":[[259,8]]}}}],["function(",{"_index":259,"t":{"37":{"position":[[297,12]]}}}],["gener",{"_index":106,"t":{"18":{"position":[[69,9]]}}}],["get",{"_index":358,"t":{"55":{"position":[[618,7],[712,7]]}}}],["getloggerwithtag",{"_index":527,"t":{"119":{"position":[[161,18]]}}}],["getwith(\"breedcallbackviewmodel",{"_index":238,"t":{"33":{"position":[[756,33]]}}}],["give",{"_index":291,"t":{"41":{"position":[[295,4]]}}}],["global",{"_index":220,"t":{"33":{"position":[[143,6],[288,6],[537,6]]},"39":{"position":[[213,6],[861,6],[929,6]]},"41":{"position":[[453,6]]},"119":{"position":[[279,6]]},"125":{"position":[[104,8]]}}}],["go",{"_index":517,"t":{"117":{"position":[[321,5]]}}}],["gone",{"_index":87,"t":{"14":{"position":[[439,4]]}}}],["gradle.properti",{"_index":203,"t":{"24":{"position":[[111,17]]}}}],["handl",{"_index":372,"t":{"57":{"position":[[29,7],[171,9]]},"102":{"position":[[314,7],[519,6]]}}}],["happi",{"_index":420,"t":{"89":{"position":[[522,6]]}}}],["hello",{"_index":51,"t":{"8":{"position":[[11,6]]},"14":{"position":[[348,6]]},"20":{"position":[[1135,6],[1223,6]]},"33":{"position":[[268,6],[388,6]]},"39":{"position":[[1089,8],[1111,7]]}}}],["help",{"_index":521,"t":{"117":{"position":[[451,7]]}}}],["helper",{"_index":509,"t":{"112":{"position":[[137,8]]}}}],["here",{"_index":148,"t":{"20":{"position":[[698,4]]},"43":{"position":[[167,4]]},"102":{"position":[[534,4]]}}}],["higher",{"_index":390,"t":{"67":{"position":[[306,7]]}}}],["hold",{"_index":532,"t":{"121":{"position":[[192,5]]}}}],["ignor",{"_index":189,"t":{"22":{"position":[[636,6]]},"35":{"position":[[73,8]]},"49":{"position":[[100,6],[202,6]]},"65":{"position":[[169,8]]}}}],["impact",{"_index":274,"t":{"39":{"position":[[758,6]]}}}],["implement",{"_index":324,"t":{"43":{"position":[[923,9],[1234,14]]},"45":{"position":[[22,15]]},"57":{"position":[[285,11]]},"63":{"position":[[21,15]]},"89":{"position":[[956,15],[1259,14]]},"100":{"position":[[769,9]]},"102":{"position":[[29,14],[123,14],[282,9],[347,14],[787,14]]},"104":{"position":[[26,15]]},"108":{"position":[[165,9]]},"110":{"position":[[7,14]]},"112":{"position":[[55,14]]}}}],["implementation(\"co.touchlab:kermit",{"_index":395,"t":{"74":{"position":[[28,34]]},"83":{"position":[[28,34]]},"115":{"position":[[28,34]]},"123":{"position":[[100,34]]}}}],["implementation(\"co.touchlab:kermit:2.0.3",{"_index":46,"t":{"6":{"position":[[137,42]]},"55":{"position":[[650,42]]}}}],["includ",{"_index":53,"t":{"10":{"position":[[19,8]]},"16":{"position":[[114,8],[295,8]]},"27":{"position":[[13,8],[38,9]]},"29":{"position":[[38,7]]},"31":{"position":[[53,8]]},"89":{"position":[[32,7]]},"121":{"position":[[7,8],[161,8]]}}}],["incorpor",{"_index":416,"t":{"89":{"position":[[375,13]]}}}],["info",{"_index":96,"t":{"16":{"position":[[245,4],[287,4]]},"20":{"position":[[162,4],[973,4]]},"29":{"position":[[126,4]]},"43":{"position":[[880,4]]},"57":{"position":[[253,4]]},"65":{"position":[[115,5]]},"106":{"position":[[383,6]]},"125":{"position":[[0,4]]}}}],["info(messag",{"_index":426,"t":{"89":{"position":[[1046,13]]}}}],["initi",{"_index":264,"t":{"39":{"position":[[316,12]]},"72":{"position":[[50,15]]},"81":{"position":[[54,15]]},"100":{"position":[[315,14]]},"117":{"position":[[146,11]]}}}],["initializd",{"_index":262,"t":{"39":{"position":[[136,11]]}}}],["inject",{"_index":232,"t":{"33":{"position":[[606,6]]},"96":{"position":[[39,10]]},"112":{"position":[[127,9]]},"119":{"position":[[230,9]]},"125":{"position":[[31,6]]}}}],["instanc",{"_index":55,"t":{"10":{"position":[[40,8]]},"14":{"position":[[75,10]]},"16":{"position":[[84,9],[178,10]]},"22":{"position":[[375,8]]},"27":{"position":[[100,10]]},"29":{"position":[[10,9]]},"33":{"position":[[45,8],[97,8],[157,9],[469,8]]},"35":{"position":[[129,9],[281,9],[380,9]]},"39":{"position":[[199,9],[298,8],[412,8],[451,8],[580,9]]},"41":{"position":[[76,9],[315,9]]},"43":{"position":[[493,8]]},"47":{"position":[[58,9]]},"53":{"position":[[39,10]]},"55":{"position":[[1047,8]]},"57":{"position":[[79,9],[207,9]]},"102":{"position":[[232,9]]},"106":{"position":[[123,9]]},"119":{"position":[[89,10],[247,9],[293,9]]},"125":{"position":[[45,9]]}}}],["instead",{"_index":265,"t":{"39":{"position":[[518,7]]}}}],["integ",{"_index":507,"t":{"112":{"position":[[14,10]]}}}],["integr",{"_index":431,"t":{"96":{"position":[[0,11]]}}}],["intend",{"_index":529,"t":{"121":{"position":[[35,8]]}}}],["interact",{"_index":80,"t":{"14":{"position":[[312,11]]},"121":{"position":[[87,9]]},"125":{"position":[[473,8],[793,8]]}}}],["interfac",{"_index":244,"t":{"35":{"position":[[164,9]]},"57":{"position":[[477,9]]},"89":{"position":[[594,9],[732,9]]}}}],["intern",{"_index":539,"t":{"121":{"position":[[446,11]]}}}],["interop",{"_index":344,"t":{"55":{"position":[[65,7]]}}}],["io",{"_index":59,"t":{"10":{"position":[[138,3]]},"41":{"position":[[269,3]]},"43":{"position":[[277,5]]},"100":{"position":[[207,3]]},"104":{"position":[[46,4]]}}}],["iosmain",{"_index":359,"t":{"55":{"position":[[701,7]]}}}],["islogg",{"_index":457,"t":{"102":{"position":[[576,11]]}}}],["isloggable(tag",{"_index":460,"t":{"102":{"position":[[660,15],[1049,15]]}}}],["isproduct",{"_index":466,"t":{"102":{"position":[[1104,12]]}}}],["isproduction:boolean",{"_index":465,"t":{"102":{"position":[[881,21]]}}}],["it'",{"_index":5,"t":{"2":{"position":[[50,4]]},"22":{"position":[[389,4]]},"117":{"position":[[249,4]]}}}],["itself",{"_index":305,"t":{"43":{"position":[[63,7]]},"67":{"position":[[108,6]]}}}],["js",{"_index":60,"t":{"10":{"position":[[170,2]]},"20":{"position":[[327,3]]},"41":{"position":[[276,2]]},"43":{"position":[[287,2]]},"100":{"position":[[250,2]]}}}],["jvm",{"_index":270,"t":{"39":{"position":[[700,3]]},"43":{"position":[[315,5]]}}}],["kamp",{"_index":28,"t":{"2":{"position":[[299,4]]}}}],["kermit",{"_index":0,"t":{"2":{"position":[[0,6]]},"6":{"position":[[4,6]]},"10":{"position":[[12,6]]},"14":{"position":[[329,7]]},"16":{"position":[[107,6],[212,6]]},"20":{"position":[[306,6]]},"24":{"position":[[71,6]]},"31":{"position":[[103,6],[193,6]]},"43":{"position":[[1018,6]]},"45":{"position":[[0,6]]},"55":{"position":[[13,6],[216,6],[346,6],[429,6],[885,6]]},"57":{"position":[[53,6],[278,6],[444,6],[505,6]]},"78":{"position":[[54,7]]},"87":{"position":[[58,7]]},"89":{"position":[[43,7],[139,6],[161,6],[226,6],[320,7],[629,6],[762,6],[892,6],[929,7],[1306,7]]},"100":{"position":[[11,6],[527,6]]},"102":{"position":[[588,6]]},"112":{"position":[[104,7]]},"117":{"position":[[158,6],[424,7]]},"121":{"position":[[0,6],[102,6],[439,6]]},"125":{"position":[[348,6]]},"127":{"position":[[21,6]]}}}],["kermit'",{"_index":177,"t":{"22":{"position":[[241,8]]},"31":{"position":[[0,8]]},"89":{"position":[[546,8]]},"112":{"position":[[0,8]]}}}],["kermitkoinlogger(logger.withtag(\"koin",{"_index":513,"t":{"117":{"position":[[42,40]]}}}],["kermitloggermodul",{"_index":524,"t":{"119":{"position":[[4,20]]}}}],["kermitsampleios[58575:7607179",{"_index":481,"t":{"106":{"position":[[266,30],[472,30],[560,30],[648,30],[736,30]]}}}],["kermitsampleios[58575:7607442",{"_index":483,"t":{"106":{"position":[[342,30]]}}}],["kit",{"_index":29,"t":{"2":{"position":[[304,3]]}}}],["know",{"_index":297,"t":{"41":{"position":[[633,4]]},"119":{"position":[[322,4]]}}}],["koin",{"_index":432,"t":{"96":{"position":[[17,5]]},"112":{"position":[[9,4],[82,4]]},"117":{"position":[[198,5],[272,4],[386,4]]},"119":{"position":[[42,4],[137,4]]}}}],["koin:2.0.3",{"_index":510,"t":{"115":{"position":[[63,12]]}}}],["koinappl",{"_index":511,"t":{"117":{"position":[[4,15]]}}}],["kotlin",{"_index":1,"t":{"2":{"position":[[12,6],[103,6],[338,6]]},"6":{"position":[[76,6]]},"20":{"position":[[96,6],[183,6]]},"22":{"position":[[140,6]]},"24":{"position":[[17,6]]},"31":{"position":[[31,6]]},"33":{"position":[[275,7],[395,7]]},"55":{"position":[[29,6],[173,6],[283,6],[358,7],[562,6],[578,6]]},"100":{"position":[[107,6]]}}}],["kotlin'",{"_index":128,"t":{"20":{"position":[[226,8],[1042,8]]}}}],["lambda",{"_index":122,"t":{"20":{"position":[[147,6],[1060,6]]},"125":{"position":[[650,6]]}}}],["latest",{"_index":48,"t":{"6":{"position":[[186,6]]},"123":{"position":[[154,6]]},"125":{"position":[[491,6]]}}}],["layer",{"_index":408,"t":{"89":{"position":[[200,5]]}}}],["legaci",{"_index":505,"t":{"110":{"position":[[0,6]]}}}],["level",{"_index":73,"t":{"14":{"position":[[164,7]]},"18":{"position":[[9,6]]},"20":{"position":[[64,5]]}}}],["librari",{"_index":4,"t":{"2":{"position":[[41,8],[176,7]]},"18":{"position":[[38,7]]},"22":{"position":[[161,7]]}}}],["line",{"_index":328,"t":{"43":{"position":[[1003,5]]},"108":{"position":[[209,4]]}}}],["list",{"_index":564,"t":{"125":{"position":[[811,4]]}}}],["list String) // String message parameter fun w(messageString: String, throwable: Throwable? = null, tag: String = this.tag) info The function parameter is at the end of the function to support Kotlin's trailing lambda syntax. In its most basic form, logging looks like this: Logger.i { \"Hello World\" } Some other examples with tags and Throwable params. Logger.w(\"MyTag\") { \"Hello World $someData\" } // etc Logger.e(ex) { \"Something failed\" } // or Logger.e(\"Something failed\", ex)","s":"Usage","u":"/docs/","h":"#usage","p":1},{"i":22,"t":"Tags are much more common on Android, as Logcat has tag arguments, and it is the default logger on Android. It would be difficult to have a Kotlin Multiplatform library without them, but they don't really fit into other platforms as easily. Kermit's default tag is an empty string. You can supply a tag param to each log call, change the base default tag, or create a Logger instance with it's own tag. For example, create a field in a ViewModel with the tag set to the class name (a common Android pattern): class MyViewModel:ViewModel { private val log = Logger.withTag(\"MyViewModel\") } Platform-specific loggers can be configured to ignore tags on output, or you can customize their display easily. We'll discuss these options more in Configuration.","s":"A Note About Tags","u":"/docs/","h":"#a-note-about-tags","p":1},{"i":24,"t":"Per the official Kotlin documentation we took the opportunity with the Kermit 2.0 release to remove deprecated gradle.properties values. We encourage you to do the same!","s":"Deprecated Gradle properties","u":"/docs/","h":"#deprecated-gradle-properties","p":1},{"i":27,"t":"Logger setup includes various topics, including static vs mutable, and adding non-default LogWriter instances.","s":"Logger Setup","u":"/docs/configuration/","h":"#logger-setup","p":25},{"i":29,"t":"LogWriter instances sometimes need to include tag or severity in the log message string. You may also want to add some custom info to the message strings. MessageStringFormatter allows for central formatting configuration.","s":"Message Formatting","u":"/docs/configuration/","h":"#message-formatting","p":25},{"i":31,"t":"Kermit's API is designed to be Kotlin-friendly. That includes methods with default parameters. To call Kermit from other environments, for example Swift, you'll probably want to add and export kermit-simple.","s":"Non-Kotlin Environments","u":"/docs/configuration/","h":"#non-kotlin-environments","p":25},{"i":33,"t":"A Logger is just a class with a LoggerConfig instance and a default tag. You can create your own instance of Logger, or configure and call the global Logger instance. // Local val log = Logger( loggerConfigInit(platformLogWriter(NoTagLogFormatter)), \"MyTag\" ) log.i { \"Hello Kotlin\" } // Global Logger.setLogWriters(platformLogWriter(NoTagLogFormatter)) Logger.setTag(\"MyTag\") Logger.i { \"Hello Kotlin\" } Which method you choose is up to you, but obviously a local log instance will need to be made available for you code to call, while global is available everywhere. For example, our pattern has been to inject loggers into components, with the tag applied at that point, rather than specify the tag in each call. single { BreedCallbackViewModel( get(), getWith(\"BreedCallbackViewModel\") // Convenience function to get a Logger with a tag set ) }","s":"Logger Setup","u":"/docs/configuration/LOGGER_SETUP","h":"","p":32},{"i":35,"t":"LoggerConfig defines the minSeverity, below which log statements will be ignored, and logWriterList, the collection of LogWriter instances that will be written to. interface LoggerConfig { val minSeverity: Severity val logWriterList: List } When creating our own Logger instances above, we call loggerConfigInit. That is a convenience function to create a StaticConfig instance. fun loggerConfigInit(vararg logWriters: LogWriter, minSeverity: Severity = DEFAULT_MIN_SEVERITY): LoggerConfig = StaticConfig(logWriterList = logWriters.toList(), minSeverity = minSeverity)","s":"LoggerConfig","u":"/docs/configuration/LOGGER_SETUP","h":"#loggerconfig","p":32},{"i":37,"t":"platformLogWriter() is an expect/actual factory function. You can call it in common code, and it will create a LogWriter designed for the platform the code is running on. For more complex configuration, you'll either need platform-specific entry points, or possibly your own expect/actual factory function(s).","s":"Where to do config?","u":"/docs/configuration/LOGGER_SETUP","h":"#where-to-do-config","p":32},{"i":39,"t":"For most use cases, once your logger is set up, you won't need to change the config. StaticConfig has values that can't be changed once initializd. That is what you want when creating a local Logger instance. The global Logger uses MutableLoggerConfig, because values need to be changed after that instance has been initialized. It is also possible that you have a use case where the config of your local Logger instance needs to be changed after the instance is created. In that case, you can use MutableLoggerConfig instead of StaticConfig. Why have StaticConfig at all? Logger instances are thread-safe, so MutableLoggerConfig needs to be thread-safe. That means config fields are volatile on the JVM and Atomic on native platforms. While the performance impact is likely negligable, if you want to maximize performance, static is better. If you really like global access, but want static config, you can just create your own global logger. object MyLogger : Logger( config = loggerConfigInit( platformLogWriter(NoTagLogFormatter), minSeverity = Severity.Info ), tag = \"MyAppTag\" ) fun hello(){ MyLogger.i { \"Hello\" } }","s":"StaticConfig vs MutableLoggerConfig","u":"/docs/configuration/LOGGER_SETUP","h":"#staticconfig-vs-mutableloggerconfig","p":32},{"i":41,"t":"To make message formatting more uniform and flexible, many of the LogWriter instances can take a MessageStringFormatter parameter. This allows you to control how log messages are presented and apply common formatting. TL;DR If you don't want tags to be printed in your iOS or JS log statements, give your LogWriter instances NoTagFormatter. This will suppress printing tag in log message strings. Tag will still be sent to Android log messages. For the global Logger and the platform LogWriter, config would look like the following: Logger.setLogWriters(platformLogWriter(NoTagFormatter)) For most use cases, this is all you need to know about formatters. The rest of this doc explains them in more detail.","s":"Message Formatting","u":"/docs/configuration/MESSAGE_FORMATTING","h":"","p":40},{"i":43,"t":"There are 3 parts to a message: Severity, Tag, and the Message itself. All loggers accept a log message string, but support for severity and tag vary between systems. Here is a breakdown of support for a few commonly used logging systems. System Severity Tag Android ✅ ✅ OSLog (iOS) ✅ ❌ JS-Console ✅ ❌ SystemWriter (jvm) ❌ ❌ Common (println) ❌ ❌ The main purpose of MessageStringFormatter is to manage situations where the logging system does not support either Severity or Tag. The LogWriter instance will pass null's to the MessageStringFormatter in cases where the LogWriter natively supports Severity or Tag. For example, the DefaultLogFormatter will result in the following message strings depending on platform: // Log call Logger.w(tag = \"ATag\") { \"A Log Message\" } // Android // 'A Log Message' // OSLog // '(ATag) A Log Message' // Common // 'Warn: (ATag) A Log Message' info You can use MessageStringFormatter to implement custom message strings. Maybe, say, add a special date format to each line. However, Kermit uses them to manage Severity and Tag for systems that don't natively support those constructs. Note: the Android LogcatWriter does not currently use a MessageStringFormatter. You would need to create a custom implementation to support that.","s":"Log Message Components","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#log-message-components","p":40},{"i":45,"t":"Kermit provides a few implementations out of the box.","s":"Implementations","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#implementations","p":40},{"i":47,"t":"This is the standard format that all compatible LogWriter instances get by default. Messages are formatted as in the examples above.","s":"DefaultLogFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#defaultlogformatter","p":40},{"i":49,"t":"Tags are really an Android convention. Other platforms can feel cluttered with them. You can simply ignore them with NoTagFormatter. Logging will function the same for Android, and other platforms will ignore the Tag.","s":"NoTagFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#notagformatter","p":40},{"i":51,"t":"This formatter skips tags and severity. It just prints the message.","s":"SimpleLogFormatter","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#simplelogformatter","p":40},{"i":53,"t":"To simplify setting platform LogWriter instances, you can pass a MessageStringFormatter to platformLogWriter. platformLogWriter(NoTagLogFormatter)","s":"Configuration","u":"/docs/configuration/MESSAGE_FORMATTING","h":"#configuration","p":40},{"i":55,"t":"Crash reporting is primarily handled with CrashKiOS. Kermit provides LogWriter instances to write breadcrumb/log statements to the crash reporting tools, and sending soft \"handled\" exceptions when Throwable instances are logged, based on configuration. info Earlier versions of Kermit implemented crash reporting directly, but logging and crash reporting are really different domains. Crash reporting support was moved back into CrashKiOS, and Kermit simply provides a logging interface into those tools. Kermit and CrashKiOS currently support Firebase Crashlytics and Bugsnag.","s":"Crash Reporting","u":"/docs/crashreporting/","h":"","p":54},{"i":57,"t":"See Crashlytics Setup","s":"Crashlytics","u":"/docs/crashreporting/","h":"#crashlytics","p":54},{"i":59,"t":"See Bugsnag Setup","s":"Bugsnag","u":"/docs/crashreporting/","h":"#bugsnag","p":54},{"i":61,"t":"Both crash LogWriter implementations take 3 parameters:","s":"Configuring crash log writers","u":"/docs/crashreporting/","h":"#configuring-crash-log-writers","p":54},{"i":63,"t":"This is the minimum severity that will be logged to the crash reporter's breadcrumb cache. The default severity is Info. That means Debug and Verbose statements will be ignored.","s":"minSeverity: Severity","u":"/docs/crashreporting/","h":"#minseverity-severity","p":54},{"i":65,"t":"All log statements can take a Throwable. If you send a Throwable to a crash LogWriter, if the log statement itself is equal to or above minCrashSeverity, the Throwable will be sent as a soft/handled exception. The default value is Warn, so all log statements with a Throwable, with log severity of Warn or higher, will create an exception report. To disable sending exception reports, pass null.","s":"minCrashSeverity: Severity?","u":"/docs/crashreporting/","h":"#mincrashseverity-severity","p":54},{"i":67,"t":"See Message Formatting for details of how to format log message strings. DefaultFormatter is the default value.","s":"messageStringFormatter: MessageStringFormatter","u":"/docs/crashreporting/","h":"#messagestringformatter-messagestringformatter","p":54},{"i":69,"t":"You can call Kermit from non-Kotlin code, but because of the way interop works, calling from those environments won't let you use default parameters. That will make calling Kotlin fairly verbose. Earlier versions of Kermit were designed to be Swift-friendly, but that sacrificed the Kotlin-friendly API, and since the primary use-case is calling Kermit from Kotlin, that seemed like a bad compromise. We've added a module called kermit-simple which adds explicit call signatures to the API, to provide for the cases where default parameters make more sense in a Kotlin context. kotlin { sourceSets { val commonMain by getting { dependencies { // etc implementation(\"co.touchlab:kermit:2.0.3\") } } val iosMain by getting { dependencies { // etc api(\"co.touchlab:kermit-simple:2.0.3\") } } } cocoapods { framework { export(\"co.touchlab:kermit-simple:2.0.3\") } } } You will need to export kermit-simple, as in the example above. From Swift, this will allow you to call methods without all of the parameters explicitly added. let log = // Get a Logger instance log.i(messageString: \"Try a log\") log.w(messageString: \"Throw\", throwable: someException)","s":"Non-Kotlin Environments","u":"/docs/configuration/NON_KOTLIN","h":"","p":68},{"i":72,"t":"You first need to configure Bugsnag and CrashKiOS initialization. See the CrashKiOS Bugsnag Tutorial Doc.","s":"Setup","u":"/docs/crashreporting/BUGSNAG","h":"#setup","p":70},{"i":74,"t":"commonMain { dependencies { implementation(\"co.touchlab:kermit-bugsnag:2.0.3\") } }","s":"Add the dependency","u":"/docs/crashreporting/BUGSNAG","h":"#add-the-dependency","p":70},{"i":76,"t":"Logger.setLogWriters(BugsnagLogWriter())","s":"Add the log writer","u":"/docs/crashreporting/BUGSNAG","h":"#add-the-log-writer","p":70},{"i":78,"t":"You can add custom values to Bugsnag, but not through Kermit. Call CrashKiOS directly. BugsnagKotlin.setCustomValue(\"someKey\", \"someValue\")","s":"Custom Values","u":"/docs/crashreporting/BUGSNAG","h":"#custom-values","p":70},{"i":80,"t":"The main module most users will include is kermit. However, much of the configuration and other underlying functionality has been moved to kermit-core. The main kermit module is a relatively thin API layer that sits on top of kermit-core. Over the past few years, we've had feedback about the API design choices made in Kermit. Some of that feedback makes sense and has been incorporated. Other feedback is really just personal preference, and would conflict with the existing design. Rather than trying to make everybody happy, we've structured Kermit's modules so you can create your own API interface on top of the underlying kermit-core module. That will allow you to use compatible extensions like Crashlytics and Bugsnag, but interface with the underlying Kermit system with whatever API you prefer. For example, if you wanted a very simple logger with only two methods, you would make kermit-core a dependency rather than kermit, and write your own implementation: object MyLogger : BaseLogger(loggerConfigInit(platformLogWriter())) { fun info(message: String){ log(Severity.Info, \"MyLogger\", null, message) } fun error(message: String, throwable: Throwable){ log(Severity.Error, \"MyLogger\", throwable, message) } } For a more complex example, see the implementation of co.touchlab.kermit.Logger in kermit.","s":"Custom Logger API","u":"/docs/details/CUSTOM_API","h":"","p":79},{"i":83,"t":"You first need to configure Crashlytics and CrashKiOS initialization. See the CrashKiOS Crashlytics Tutorial Doc.","s":"Setup","u":"/docs/crashreporting/CRASHLYTICS","h":"#setup","p":81},{"i":85,"t":"commonMain { dependencies { implementation(\"co.touchlab:kermit-crashlytics:2.0.3\") } }","s":"Add the dependency","u":"/docs/crashreporting/CRASHLYTICS","h":"#add-the-dependency","p":81},{"i":87,"t":"Logger.setLogWriters(CrashlyticsLogWriter())","s":"Add the log writer","u":"/docs/crashreporting/CRASHLYTICS","h":"#add-the-log-writer","p":81},{"i":89,"t":"You can add custom values to Crashlytics, but not through Kermit. Call CrashKiOS directly. CrashlyticsKotlin.setCustomValue(\"someKey\", \"someValue\")","s":"Custom Values","u":"/docs/crashreporting/CRASHLYTICS","h":"#custom-values","p":81},{"i":91,"t":"LogWriter takes care of deciding where to log the messages.","s":"LogWriter","u":"/docs/details/LOG_WRITER","h":"","p":90},{"i":93,"t":"By default Kermit provides default LogWriter for each platform CommonWriter - Uses println to send logs in Kotlin LogcatWriter - Uses LogCat to send logs in Android OSLogWriter - Uses os log to send logs in iOS ConsoleWriter - Uses console to log in JS These can be created and passed into the Logger object during initialization Logger.setLogWriters(listOf(LogcatWriter(), CommonWriter())) Selecting loggers for each platform can either be done with platform-specific entry points, or using an expect/actual factory function. Kermit ships with a default factory function that provides a LogWriter suited to local development. package co.touchlab.kermit expect fun platformLogWriter(messageStringFormatter: MessageStringFormatter = DefaultFormatter): LogWriter You can implement a factory function for your project similar to the one above.","s":"Prebuilt LogWriters","u":"/docs/details/LOG_WRITER","h":"#prebuilt-logwriters","p":90},{"i":95,"t":"If you want to have a custom implementation to send logs to your own server, or a 3rd party tool or simply because default implementation doesn't fit your need, then you would need to extend the LogWriter class and provide your own instance. For a simple LogWriter you only need to implement the log method, which handles all log messages. Simple implementation would look like below, class YourCustomWriter : LogWriter() { override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) { // Handle logging here } } Custom loggers may also override isLoggable. Kermit will check this value before logging to this LogWriter. open fun isLoggable(tag: String, severity: Severity): Boolean = true If your custom logger should only send messages in production, the implementation could look like the following: // LogWriter class YourCustomWriter(private val isProduction:Boolean) : LogWriter() { override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) { // Do something custom } override fun isLoggable(tag: String, severity: Severity): Boolean = isProduction } // Usage val logWriter = YourCustomWriter(someProdFlag) val logger = Logger(loggerConfigInit(logWriter))","s":"Custom LogWriter","u":"/docs/details/LOG_WRITER","h":"#custom-logwriter","p":90},{"i":98,"t":"Crashlytics log statement writing.","s":"Crashlytics","u":"/docs/extensions/","h":"#crashlytics","p":96},{"i":100,"t":"Bugsnag breadcrumb writing.","s":"Bugsnag","u":"/docs/extensions/","h":"#bugsnag","p":96},{"i":102,"t":"Integration with Koin, for easy logger injection.","s":"Koin","u":"/docs/extensions/","h":"#koin","p":96},{"i":104,"t":"Kermit's Koin integation comes in two parts - a logger implementation that writes Koin logger output to Kermit, and dependency injection helpers.","s":"Koin Integration","u":"/docs/extensions/KOIN","h":"","p":103},{"i":107,"t":"commonMain { dependencies { implementation(\"co.touchlab:kermit-koin:2.0.3\") } }","s":"Add the dependency","u":"/docs/extensions/KOIN","h":"#add-the-dependency","p":103},{"i":109,"t":"val koinApplication = startKoin { logger( KermitKoinLogger(Logger.withTag(\"koin\")) ) modules(/* modulesList */) } Obviously you will want to have initialized Kermit before registering a logger with Koin, and the tag you pass is optional. That said, it's useful to tag the Koin output to be able to filter and see what is going on. Once you have registered the logger, all of the normal Koin logging will be piped through to Kermit. This is especially helpful when checking your module dependencies from unit tests!","s":"Register the logger with Koin","u":"/docs/extensions/KOIN","h":"#register-the-logger-with-koin","p":103},{"i":111,"t":"The kermitLoggerModule() method returns a Koin module that declares a factory for logger instances. If you don't want to make use of the Koin factory, there's a getLoggerWithTag() extension method you can call directly. We prefer injecting logger instances rather than using the global Logger instance, especially when we know we'll be unit testing a section of code.","s":"Dependency Injection Helpers","u":"/docs/extensions/KOIN","h":"#dependency-injection-helpers","p":103},{"i":113,"t":"There are three LogWriter implementations for iOS.","s":"iOS Logging","u":"/docs/IOS_LOGGING","h":"","p":112},{"i":115,"t":"This is the default LogWriter. It is designed for local development. Each severity is represented with an emoji. Throwable instances sent to this writer will be written with println rather than oslog because oslog trims long strings. 2023-03-05 08:48:03.864138-0500 KermitSampleIOS[58575:7607179] 🟢 Try a log 2023-03-05 08:48:04.622452-0500 KermitSampleIOS[58575:7607442] [Bugsnag] [INFO] Sent session 7D3188F7-2B37-4189-9F92-63BC7172D01B 2023-03-05 08:48:09.999884-0500 KermitSampleIOS[58575:7607179] 🟢 Common click count: 1 2023-03-05 08:48:11.333941-0500 KermitSampleIOS[58575:7607179] 🔵 Common click count: 2 2023-03-05 08:48:13.104265-0500 KermitSampleIOS[58575:7607179] 🟡 Common click count: 3 2023-03-05 08:48:13.568351-0500 KermitSampleIOS[58575:7607179] 🔴 Common click count: 4","s":"XcodeSeverityWriter","u":"/docs/IOS_LOGGING","h":"#xcodeseveritywriter","p":112},{"i":117,"t":"This is the parent class of XcodeSeverityWriter. There is no emoji added for severity, and Throwable is sent as a string to oslog. This may trim exceptions. You can implement a custom version that writes each line of a stack trace to oslog, or whatever else you'd like to do. Override logThrowable.","s":"OSLogWriter","u":"/docs/IOS_LOGGING","h":"#oslogwriter","p":112},{"i":119,"t":"Legacy implementation using NSLog.","s":"NSLogWriter","u":"/docs/IOS_LOGGING","h":"#nslogwriter","p":112},{"i":121,"t":"Kermit includes a test dependency, intended for use when testing application code that interacts with Kermit APIs but doesn't want to write to actual logs. This includes a TestLogWriter which holds the string outputs of log statements, and has APIs for asserting on what logs are present. note The test APIs are not yet stable, and require opting into the @ExperimentalKermitApi annotation. The current API is based on what we use to test Kermit internally. It may change dramatically before we stabilize it as we consider more real-world use-cases.","s":"Testing","u":"/docs/TESTING","h":"","p":120},{"i":123,"t":"Typically you would depend on this from your test sources. sourceSets { commonTest { dependencies { implementation(\"co.touchlab:kermit-test:2.0.3\") //Add latest version } } }","s":"Add to your dependencies","u":"/docs/TESTING","h":"#add-to-your-dependencies","p":120},{"i":125,"t":"info We strongly recommend you inject logger instances into your classes rather than simply calling the (global) static Logger as it will make testing easier. Suppose you have a test @OptIn(ExperimentalKermitApi::class) class MyExampleTest { private val testLogWriter = TestLogWriter( loggable = Severity.Verbose // accept everything ) private val kermit = Logger( TestConfig( minSeverity = Severity.Debug, logWriterList = listOf(testLogWriter) ) ) // ... } You can either interact with the latest log entry that was produced - @Test fun somethingInterestingHappened() { // ... testLogWriter.assertCount(1) // calls assertTrue() on the result of the lambda testLogWriter.assertLast { message == \"the message\" && severity == Severity.Info && tag == \"my-tag\" && throwable == null } } or you can interact with the list of log entries directly @Test fun somethingElseInterestingHappened() { // ... testLogWriter.assertCount(10) with(testLogWriter.logs[3]) { assertEquals(\"the message\", message) assertEquals(Severity.Info, severity) assertEquals(\"my-tag\", tag) assertNull(throwable) } }","s":"Use in your tests","u":"/docs/TESTING","h":"#use-in-your-tests","p":120},{"i":127,"t":"The default setup of Kermit aims to make production logging as simple as possible. This means that the platform logger for Android defaults to passing the log through to Android's logcat Log() method. Be sure to configure your tests accordingly, as this wont function when running unit tests on your local machine!","s":"Logging on Android","u":"/docs/TESTING","h":"#logging-on-android","p":120}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/2",[0,0.964,1,2.871,2,3.818,3,1.301,4,3.818,5,2.734,6,2.734,7,3.054,8,2.145,9,1.89,10,2.009,11,2.495,12,3.54,13,2.145,14,3.818,15,2.734,16,1.203,17,1.523,18,2.304,19,0.923,20,3.54,21,2.304,22,2.304,23,3.054,24,3.054,25,1.382,26,3.54,27,2.734,28,3.54,29,3.54,30,3.54,31,2.495]],["t/4",[14,3.988,15,3.988,16,1.755,25,2.016,32,3.639,33,3.988,34,2.603,35,3.988,36,3.988,37,4.455,38,3.129]],["t/6",[0,1.226,1,2.268,2,3.476,39,2.629,40,3.172,41,3.78,42,3.883,43,2.929,44,2.727,45,2.092,46,3.883,47,2.268,48,3.476,49,2.727]],["t/8",[45,2.004,50,4.036,51,3.727,52,4.036]],["t/10",[0,1.262,16,1.574,17,1.993,21,3.015,22,3.015,25,1.809,31,3.265,53,2.629,54,1.378,55,1.44,56,2.473,57,2.629,58,3.481,59,3.015,60,3.015,61,3.578]],["t/12",[19,1.416,54,1.615,62,4.194,63,4.685,64,4.194,65,2.458,66,4.685,67,2.12]],["t/14",[0,0.867,3,1.227,10,1.806,19,1.4,25,1.243,32,3.231,45,1.988,50,2.243,51,2.072,52,2.243,54,0.946,55,0.989,62,2.458,67,1.79,68,1.929,69,1.878,70,3.183,71,2.31,72,3.183,73,2.458,74,3.183,75,3.183,76,3.183,77,2.746,78,3.183,79,3.183,80,2.458,81,2.243,82,3.183,83,3.183,84,1.519,85,3.183,86,3.183,87,3.183,88,2.746]],["t/16",[0,1.368,3,1.317,8,2.195,13,2.195,17,1.558,18,2.357,19,0.944,32,2.552,34,1.825,44,2.195,47,1.825,53,2.85,54,1.851,55,1.561,89,3.124,90,2.357,91,1.558,92,3.124,93,3.124,94,2.357,95,2.357,96,2.681,97,2.055,98,1.934,99,3.621,100,1.728,101,1.825,102,3.621]],["t/18",[3,1.43,4,3.288,19,1.11,25,1.662,34,2.146,67,2.187,73,3.288,103,3,104,2.416,105,3.288,106,4.257,107,4.257,108,3.673,109,3.288,110,3,111,2.031,112,3.288,113,3.288,114,4.257,115,3.288,116,4.257]],["t/20",[0,0.434,1,1.343,3,1.175,6,1.229,11,1.122,16,0.906,19,0.415,45,1.934,49,0.965,50,1.122,51,1.735,52,1.879,56,0.85,60,1.036,62,1.229,66,1.373,67,1.041,68,1.615,69,1.092,71,1.733,73,1.229,77,1.373,84,1.919,91,1.48,96,1.423,101,0.802,104,0.903,117,1.592,118,1.373,119,1.036,120,1.592,121,3.348,122,2.3,123,2.665,124,1.229,125,1.592,126,1.036,127,2.059,128,2.665,129,1.592,130,1.207,131,0.965,132,1.229,133,1.229,134,1.373,135,2.442,136,0.965,137,2.586,138,1.373,139,2.665,140,1.373,141,1.229,142,1.373,143,1.229,144,1.592,145,1.592,146,1.592,147,1.592,148,1.229,149,1.592,150,2.059,151,2.665,152,1.513,153,1.592,154,1.879,155,1.48,156,2.665,157,1.592,158,1.592,159,1.592,160,0.85,161,1.373,162,1.592,163,1.592,164,1.373,165,1.592,166,1.373,167,2.665,168,1.592,169,1.592]],["t/22",[1,1.261,2,1.932,3,0.875,4,1.932,5,1.932,13,1.516,16,1.583,17,1.649,18,1.628,19,1.214,21,1.628,25,1.496,34,1.931,43,1.628,45,1.385,55,0.777,56,1.335,57,2.643,69,1.024,100,1.828,104,2.175,105,1.932,110,1.763,115,1.932,126,1.628,135,1.132,155,2.743,160,1.335,161,2.158,170,2.158,171,2.501,172,2.501,173,2.158,174,1.628,175,2.158,176,3.832,177,1.763,178,2.501,179,2.501,180,1.932,181,2.158,182,2.501,183,2.494,184,2.501,185,2.501,186,2.158,187,1.419,188,2.501,189,1.763,190,1.419,191,2.501,192,2.501,193,2.158]],["t/24",[0,1.32,1,2.443,143,3.743,194,4.846,195,4.846,196,4.846,197,4.846,198,4.846,199,4.846,200,4.846,201,4.846,202,4.846,203,4.846,204,2.75,205,4.846]],["t/27",[16,1.673,19,1.283,40,3.469,53,3.489,54,1.464,55,1.53,93,4.246,124,3.801,206,3.469,207,4.922,208,3.801,209,4.922,210,4.922]],["t/29",[3,1.013,8,2.689,25,1.732,47,2.236,53,2.518,54,1.319,55,1.379,65,2.009,67,1.732,91,2.476,96,2.369,111,2.117,135,2.605,155,1.909,190,2.518,211,4.437,212,2.888,213,4.437,214,2.888]],["t/31",[0,1.567,1,2.236,16,1.508,33,3.427,38,2.689,47,2.236,53,2.518,64,3.427,69,1.817,71,2.236,111,2.117,119,2.888,121,2.888,132,3.427,160,2.369,177,3.127,215,2.888,216,3.828,217,4.437,218,3.828]],["t/33",[1,1.931,3,0.875,10,1.419,16,0.85,19,1.548,25,0.976,43,1.628,45,2.047,50,1.763,51,2.494,55,1.623,56,1.335,63,2.158,65,1.132,69,1.908,71,1.261,100,1.193,105,1.932,113,1.932,137,1.335,155,2.246,160,1.335,183,1.628,187,1.419,219,2.158,220,3.032,221,2.494,222,2.501,223,2.501,224,2.501,225,2.501,226,2.501,227,2.501,228,2.158,229,2.158,230,3.832,231,2.501,232,1.628,233,2.158,234,1.932,235,2.501,236,2.501,237,2.501,238,2.501,239,2.158]],["t/35",[3,0.727,9,1.699,11,2.243,19,0.83,45,1.929,54,1.597,55,1.67,67,1.79,69,1.304,100,2.187,118,2.746,137,1.699,152,1.806,187,2.601,189,2.243,219,4.635,239,2.746,240,4.811,241,2.746,242,3.955,243,3.183,244,2.458,245,3.183,246,2.072,247,2.746,248,2.746,249,3.183,250,3.183,251,3.183,252,3.183]],["t/37",[10,3.124,17,2.368,18,2.698,25,1.618,34,2.089,35,3.201,54,1.233,64,3.201,65,1.877,69,1.698,100,1.978,104,2.353,137,2.213,215,2.698,234,3.201,253,3.576,254,4.748,255,4.251,256,3.576,257,3.201,258,3.201,259,4.145]],["t/39",[17,0.886,19,1.498,36,3.965,43,1.341,45,1.83,51,2.142,55,1.595,65,2.126,88,1.777,100,1.962,109,1.591,111,1.962,113,1.591,130,2.126,131,2.491,152,1.169,155,0.886,174,1.341,180,3.627,181,1.777,204,1.868,208,2.542,220,2.676,221,2.142,240,1.591,247,1.777,248,3.547,258,1.591,260,2.84,261,2.06,262,2.06,263,4.111,264,1.341,265,2.06,266,3.292,267,3.292,268,1.591,269,2.06,270,1.777,271,2.06,272,1.777,273,3.292,274,2.06,275,2.06,276,2.06,277,2.06,278,1.591,279,1.777,280,1.777,281,1.777,282,2.06,283,2.06]],["t/41",[3,1.26,8,1.69,9,1.489,17,1.2,19,0.727,34,2.097,36,2.154,54,1.48,55,1.293,57,1.583,59,1.815,60,1.815,65,1.262,68,1.69,91,2.374,103,1.965,104,1.583,108,2.406,111,1.331,121,1.815,126,1.815,130,1.262,131,1.69,135,1.262,150,2.154,155,2.141,212,1.815,214,2.708,220,1.815,233,2.406,284,1.69,285,2.789,286,2.789,287,2.789,288,2.406,289,2.789,290,3.589,291,2.789,292,2.406,293,2.789,294,2.789,295,1.965,296,2.789,297,2.406,298,2.406,299,2.789,300,2.154,301,2.789,302,2.406]],["t/43",[0,0.449,3,1.251,7,1.424,17,0.71,19,0.43,22,1.788,39,0.747,45,2.032,47,0.832,54,0.817,55,0.513,56,0.881,57,2.002,59,1.074,60,1.074,61,1.274,65,0.747,67,1.925,69,0.676,91,2.446,96,0.881,100,0.787,103,1.163,104,1.559,112,1.274,126,1.074,127,3.809,130,1.862,131,1,135,1.597,148,1.274,155,2.122,160,0.881,190,1.559,212,2.677,214,1.074,270,1.424,272,2.37,303,1.274,304,1.424,305,1.424,306,1.424,307,1.65,308,1.65,309,3.941,310,1.65,311,1.274,312,1.65,313,1.65,314,1.274,315,1.424,316,2.747,317,1.65,318,1,319,1.65,320,1.65,321,1.424,322,1.65,323,3.528,324,1.243,325,1.65,326,1.65,327,1.65,328,1.424,329,1.274,330,1.65,331,1.424,332,1.424,333,1.274]],["t/45",[0,1.532,14,4.344,15,4.344,311,4.344,324,2.546,334,3.661]],["t/47",[16,1.784,54,1.561,55,1.632,91,2.259,160,2.803,214,4.164,246,3.417,335,5.25,336,4.529]],["t/49",[3,1.074,17,2.57,57,3.39,137,2.51,143,3.631,155,2.57,174,3.06,189,4.21,292,4.056,337,4.702,338,4.702,339,4.702,340,3.314]],["t/51",[67,2.196,91,2.42,155,2.42,290,4.852,298,4.852,341,5.624]],["t/53",[17,2.297,43,3.475,54,1.587,55,1.659,212,3.475,253,4.606,280,4.606,318,3.235,342,5.338]],["t/55",[0,1.536,3,1.167,9,1.558,25,1.139,32,2.056,49,1.768,54,0.868,55,1.337,58,1.558,84,1.392,90,1.899,95,3.915,96,1.558,97,1.656,98,1.558,110,2.056,127,3.323,136,1.768,174,1.899,244,2.253,324,1.321,329,2.253,333,2.253,334,2.8,340,2.056,343,5.189,344,2.918,345,3.712,346,3.326,347,2.918,348,3.712,349,2.918,350,2.253,351,2.517,352,2.918,353,2.517,354,2.918,355,2.918]],["t/57",[97,3.372,101,2.995,206,4.188]],["t/59",[98,3.173,101,2.995,206,4.188]],["t/61",[54,1.643,68,3.348,95,3.596,121,3.596,142,4.767,303,4.268,324,2.501]],["t/63",[3,1.107,9,2.587,16,1.647,67,2.377,95,3.154,96,2.587,189,3.416,268,3.743,356,4.846,357,4.846,358,4.181,359,4.846,360,4.846,361,4.181]],["t/65",[3,1.422,9,3.078,16,1.231,54,1.077,67,1.414,68,2.195,84,2.97,90,3.269,95,2.357,100,1.728,112,3.878,154,2.552,204,2.055,246,2.357,295,2.552,305,3.124,318,2.195,343,4.332,350,4.452,362,3.621,363,3.621,364,3.621,365,3.621,366,3.621]],["t/67",[3,1.179,16,1.755,91,2.725,101,2.603,135,2.338,204,2.931,214,4.122,302,4.455,367,4.455]],["t/69",[0,1.317,1,2.615,3,0.684,6,1.415,8,1.11,10,1.04,16,1.018,19,0.478,33,1.415,34,0.924,37,1.581,38,1.815,39,1.356,40,2.111,41,1.193,44,1.11,45,2.075,46,1.581,47,0.924,49,1.11,55,0.57,65,0.83,69,2.243,71,0.924,81,1.291,84,0.874,109,1.415,119,1.949,121,2.472,124,1.415,130,1.356,131,1.815,132,2.313,160,0.978,164,2.584,173,1.581,187,1.7,215,1.193,216,2.584,218,1.581,246,1.193,284,1.815,329,1.415,334,1.193,351,1.581,361,1.581,368,1.832,369,1.832,370,1.832,371,1.832,372,1.832,373,1.832,374,1.832,375,1.581,376,1.832,377,1.832,378,1.581,379,1.832,380,1.581,381,2.995,382,1.832,383,1.832,384,2.995,385,1.832,386,1.832,387,1.832,388,1.832,389,1.832,390,1.832,391,1.832,392,1.832]],["t/72",[25,2.016,65,2.338,98,3.381,101,2.603,264,3.361,300,3.988,346,4.122,393,4.455,394,4.455]],["t/74",[39,2.458,41,3.535,45,2.161,395,3.827,396,5.43]],["t/76",[397,6.175]],["t/78",[0,1.406,47,2.603,69,2.115,94,3.361,98,2.757,136,3.129,190,2.931,204,2.931,346,3.361,398,5.164,399,4.455]],["t/80",[0,1.665,8,1.13,19,0.486,25,0.728,34,0.94,35,1.44,38,1.13,39,0.844,44,2.686,45,1.451,53,1.058,58,0.996,71,0.94,81,1.314,84,1.834,91,1.307,97,1.058,98,0.996,100,0.89,101,0.94,111,0.89,119,2.884,130,0.844,133,1.44,135,1.375,137,0.996,140,1.609,141,2.346,152,1.724,154,1.314,160,1.622,170,1.609,174,1.214,177,1.314,215,1.977,229,1.609,244,2.346,278,1.44,279,3.316,284,2.329,309,1.609,311,1.44,315,2.621,324,1.375,336,1.609,353,1.609,375,2.621,378,1.609,400,1.865,401,3.844,402,4.432,403,1.865,404,1.865,405,1.865,406,1.865,407,3.038,408,1.865,409,1.865,410,1.865,411,3.844,412,1.865,413,1.865,414,1.865,415,1.865,416,1.865,417,1.865,418,1.865,419,1.609,420,1.609,421,1.865,422,1.865,423,1.865,424,1.865,425,1.865,426,1.865,427,1.865]],["t/83",[25,2.016,65,2.338,97,3.594,101,2.603,264,3.361,300,3.988,346,4.122,393,4.455,394,4.455]],["t/85",[39,2.458,41,3.535,45,2.161,395,3.827,428,5.43]],["t/87",[429,6.175]],["t/89",[0,1.406,47,2.603,69,2.115,94,3.361,97,2.931,136,3.129,190,2.931,204,2.931,346,3.361,399,4.455,430,5.164]],["t/91",[3,1.284,54,1.672,68,3.408,91,2.42,431,5.624,432,5.624]],["t/93",[0,1.031,1,1.241,3,1.276,16,1.568,17,1.985,18,1.602,19,0.987,21,1.602,31,1.735,45,0.732,54,1.372,56,2.021,57,1.397,59,1.602,60,1.602,61,1.901,90,3.002,92,3.266,100,1.175,130,2.53,134,2.124,137,2.463,152,1.397,212,1.602,221,1.602,234,1.901,246,1.602,254,2.124,255,3.562,257,1.901,264,1.602,278,1.901,314,1.901,318,1.492,324,1.115,332,2.124,334,2.464,367,2.124,433,2.462,434,2.462,435,2.462,436,2.462,437,2.462,438,2.462,439,2.462,440,2.462,441,2.462,442,2.462,443,2.462,444,2.462,445,2.462,446,2.462,447,2.462]],["t/95",[0,0.485,3,1.087,16,0.605,19,0.97,24,1.536,27,1.375,38,1.773,45,2.029,54,1.608,55,0.553,65,1.685,67,1.998,71,0.898,84,2.057,90,1.904,91,1.855,103,1.255,111,0.85,135,2.317,148,1.375,150,2.259,152,2.446,155,1.259,166,1.536,175,1.536,183,2.423,187,2.113,190,2.446,204,1.011,241,1.536,324,2.155,334,1.159,340,1.255,345,2.524,348,1.536,448,1.781,449,1.781,450,1.781,451,1.536,452,1.781,453,3.719,454,2.925,455,1.781,456,1.375,457,1.781,458,2.925,459,2.925,460,1.781,461,1.536,462,1.781,463,1.781,464,1.781,465,1.781,466,1.781,467,1.781]],["t/98",[3,1.332,9,3.114,58,3.114,97,3.31]],["t/100",[58,3.173,98,3.173,358,5.127]],["t/102",[19,1.493,23,4.94,232,3.727,468,5.726,469,4.036]],["t/104",[0,1.3,13,2.892,19,1.572,39,2.161,58,2.548,133,3.686,177,3.364,232,3.107,304,4.118,324,2.161,469,4.25,470,4.773,471,4.773,472,4.773]],["t/107",[39,2.458,41,3.535,45,2.161,395,3.827,473,5.43]],["t/109",[0,1.267,3,0.742,5,2.509,13,1.968,19,1.416,27,2.509,39,1.471,44,2.819,45,1.867,94,2.114,101,1.637,111,1.55,130,1.471,155,2.001,187,1.844,193,2.802,228,2.802,260,2.802,264,2.114,318,1.968,456,2.509,469,3.83,474,3.248,475,3.248,476,3.248,477,3.248,478,4.651,479,3.248,480,3.248,481,3.248,482,3.248,483,2.802,484,3.248,485,2.509,486,1.968]],["t/111",[10,2.079,19,1.512,44,2.22,55,1.803,69,1.501,71,2.551,111,1.748,115,2.829,126,2.385,130,2.292,136,2.22,138,3.161,141,2.829,220,2.385,232,2.385,255,3.91,284,2.22,297,3.161,419,3.161,469,3.568,483,3.161,485,2.829,486,2.22,487,3.664,488,3.664,489,3.664,490,3.664,491,3.664]],["t/113",[54,1.734,59,3.796,324,2.64,492,5.832]],["t/115",[3,0.522,11,1.61,16,0.776,22,2.324,31,1.61,45,1.605,54,0.679,55,0.71,56,1.219,67,0.892,81,1.61,84,1.09,96,1.219,98,1.219,104,2.823,135,1.034,215,1.486,221,1.486,295,2.517,303,1.764,314,1.764,493,2.284,494,1.97,495,2.284,496,1.97,497,2.284,498,5.722,499,5.722,500,5.722,501,2.284,502,5.722,503,5.397,504,2.284,505,2.284,506,2.284,507,2.284,508,2.284,509,2.284,510,2.284,511,2.284,512,2.284,513,4.973,514,4.973,515,2.284,516,2.284,517,2.284,518,2.284,519,2.284,520,2.284]],["t/117",[22,3.614,40,2.96,49,2.545,56,2.243,58,2.243,67,1.64,84,2.004,135,1.902,183,2.734,190,2.384,295,2.96,324,1.902,328,3.624,350,3.244,420,3.624,453,3.624,494,3.624,496,3.624,521,4.2,522,4.2,523,4.2,524,4.2,525,4.2,526,4.2]],["t/119",[130,2.64,324,2.64,527,5.832,528,5.832]],["t/121",[0,1.431,3,1.2,9,1.633,10,1.736,13,1.854,34,1.542,39,1.385,52,2.156,53,2.528,58,1.633,80,2.363,89,2.639,110,2.156,111,1.46,119,3.755,130,2.378,131,1.854,135,1.385,180,2.363,288,2.639,331,2.639,333,2.363,451,2.639,456,2.363,486,3.496,529,3.059,530,3.059,531,2.639,532,3.059,533,3.059,534,3.059,535,3.059,536,3.059,537,3.059,538,3.059,539,3.059,540,3.059,541,3.059,542,3.059,543,3.059]],["t/123",[39,2.679,42,3.997,45,2.159,47,2.335,48,3.578,49,2.807,380,3.997,395,3.265,486,2.807,544,4.632,545,4.632,546,4.632]],["t/125",[0,0.533,3,0.722,19,1.036,45,2.221,48,1.512,55,0.608,67,1.234,69,1.294,80,2.44,84,0.934,91,1.962,96,1.045,122,1.689,136,1.186,152,1.793,154,1.38,155,1.962,183,2.057,186,2.726,187,1.793,208,1.512,220,1.274,232,1.274,240,1.512,242,1.689,257,2.44,281,1.689,284,1.186,306,1.689,321,1.689,340,1.38,486,2.763,531,2.726,547,1.958,548,1.958,549,1.958,550,1.958,551,1.958,552,1.958,553,1.958,554,1.958,555,1.958,556,1.958,557,1.958,558,1.958,559,1.958,560,1.958,561,1.958,562,1.958,563,1.958,564,1.958,565,1.958,566,1.958,567,1.958,568,1.958,569,1.958,570,1.958,571,1.958]],["t/127",[0,1.046,3,1.358,16,1.778,17,1.653,19,1.002,21,2.501,25,1.5,38,2.328,57,2.181,71,1.937,94,2.501,137,2.051,206,2.708,221,2.501,256,3.315,258,2.967,268,2.967,284,2.328,318,2.328,461,3.315,485,2.967,486,3.169,572,3.842,573,3.842,574,3.842,575,3.842,576,3.842,577,3.842]]],"invertedIndex":[["",{"_index":45,"t":{"6":{"position":[[116,1],[131,1],[133,3],[201,1],[203,1]]},"8":{"position":[[9,1],[25,1]]},"14":{"position":[[346,1],[362,1],[368,1],[387,1],[422,1],[452,1],[454,1]]},"20":{"position":[[748,2],[807,1],[827,1],[848,2],[852,1],[862,2],[941,1],[961,1],[1133,1],[1149,1],[1221,1],[1247,1],[1249,2],[1269,1],[1290,1],[1292,2]]},"22":{"position":[[537,1],[555,1],[587,1]]},"33":{"position":[[167,2],[184,1],[258,1],[266,1],[283,1],[285,2],[386,1],[403,1],[723,1],[790,2],[845,1],[847,1]]},"35":{"position":[[187,1],[250,1],[463,1],[501,1],[530,1],[565,1]]},"39":{"position":[[960,1],[977,1],[1047,1],[1063,2],[1070,1],[1083,1],[1109,1],[1119,1],[1121,1]]},"43":{"position":[[267,1],[269,1],[283,1],[285,1],[298,1],[300,1],[321,1],[323,1],[342,1],[344,1],[718,2],[743,1],[753,1],[771,1],[773,2],[784,2],[803,2],[812,2],[838,2],[848,2]]},"69":{"position":[[585,1],[598,1],[626,1],[641,1],[643,2],[693,1],[695,1],[720,1],[735,1],[737,2],[783,1],[785,1],[787,1],[799,1],[811,1],[855,1],[857,1],[859,1],[1029,1],[1031,2]]},"74":{"position":[[11,1],[26,1],[79,1],[81,1]]},"80":{"position":[[988,1],[1040,1],[1115,1],[1219,1],[1221,1]]},"85":{"position":[[11,1],[26,1],[83,1],[85,1]]},"93":{"position":[[730,1]]},"95":{"position":[[408,1],[422,1],[514,1],[516,2],[539,1],[541,1],[713,1],[833,2],[903,1],[917,1],[1009,1],[1011,2],[1034,1],[1102,1],[1117,1],[1119,2],[1142,1],[1186,1]]},"107":{"position":[[11,1],[26,1],[76,1],[78,1]]},"109":{"position":[[20,1],[32,1],[83,1],[108,3],[112,1]]},"115":{"position":[[297,2],[503,2],[591,2],[679,2],[767,2]]},"123":{"position":[[70,1],[83,1],[98,1],[169,1],[171,1],[173,1]]},"125":{"position":[[240,1],[268,1],[294,1],[313,2],[334,1],[355,1],[389,1],[421,1],[445,1],[447,1],[449,2],[452,3],[456,1],[569,1],[571,2],[574,3],[607,2],[682,1],[692,2],[709,2],[721,2],[738,2],[745,2],[757,2],[770,2],[778,1],[780,1],[885,1],[887,2],[890,3],[952,1],[1079,1],[1081,1]]}}}],["03",{"_index":499,"t":{"115":{"position":[[239,2],[315,2],[445,2],[533,2],[621,2],[709,2]]}}}],["05",{"_index":500,"t":{"115":{"position":[[242,2],[318,2],[448,2],[536,2],[624,2],[712,2]]}}}],["0500",{"_index":502,"t":{"115":{"position":[[261,4],[337,4],[467,4],[555,4],[643,4],[731,4]]}}}],["08:48:03.864138",{"_index":501,"t":{"115":{"position":[[245,15]]}}}],["08:48:04.622452",{"_index":504,"t":{"115":{"position":[[321,15]]}}}],["08:48:09.999884",{"_index":512,"t":{"115":{"position":[[451,15]]}}}],["08:48:11.333941",{"_index":516,"t":{"115":{"position":[[539,15]]}}}],["08:48:13.104265",{"_index":518,"t":{"115":{"position":[[627,15]]}}}],["08:48:13.568351",{"_index":519,"t":{"115":{"position":[[715,15]]}}}],["1",{"_index":515,"t":{"115":{"position":[[526,1]]}}}],["2",{"_index":517,"t":{"115":{"position":[[614,1]]}}}],["2.0",{"_index":199,"t":{"24":{"position":[[78,3]]}}}],["2023",{"_index":498,"t":{"115":{"position":[[234,4],[310,4],[440,4],[528,4],[616,4],[704,4]]}}}],["2b37",{"_index":508,"t":{"115":{"position":[[412,4]]}}}],["3",{"_index":303,"t":{"43":{"position":[[10,1]]},"61":{"position":[[42,1]]},"115":{"position":[[702,1]]}}}],["3rd",{"_index":449,"t":{"95":{"position":[[82,3]]}}}],["4",{"_index":520,"t":{"115":{"position":[[790,1]]}}}],["4189",{"_index":509,"t":{"115":{"position":[[417,4]]}}}],["63bc7172d01b",{"_index":511,"t":{"115":{"position":[[427,12]]}}}],["7d3188f7",{"_index":507,"t":{"115":{"position":[[403,8]]}}}],["9f92",{"_index":510,"t":{"115":{"position":[[422,4]]}}}],["abov",{"_index":246,"t":{"35":{"position":[[291,6]]},"47":{"position":[[126,6]]},"65":{"position":[[130,5]]},"69":{"position":[[918,6]]},"93":{"position":[[834,6]]}}}],["accept",{"_index":306,"t":{"43":{"position":[[83,6]]},"125":{"position":[[316,6]]}}}],["access",{"_index":277,"t":{"39":{"position":[[868,7]]}}}],["accordingli",{"_index":575,"t":{"127":{"position":[[233,12]]}}}],["actual",{"_index":89,"t":{"16":{"position":[[12,8]]},"121":{"position":[[143,6]]}}}],["ad",{"_index":40,"t":{"6":{"position":[[32,5]]},"27":{"position":[[71,6]]},"69":{"position":[[407,5],[1014,6]]},"117":{"position":[[67,5]]}}}],["add",{"_index":47,"t":{"6":{"position":[[180,5]]},"16":{"position":[[70,3]]},"29":{"position":[[110,3]]},"31":{"position":[[178,3]]},"43":{"position":[[969,3]]},"69":{"position":[[449,4]]},"78":{"position":[[8,3]]},"89":{"position":[[8,3]]},"123":{"position":[[148,5]]}}}],["aim",{"_index":572,"t":{"127":{"position":[[28,4]]}}}],["allow",{"_index":8,"t":{"2":{"position":[[77,5]]},"16":{"position":[[224,6]]},"29":{"position":[[178,6]]},"41":{"position":[[136,6]]},"69":{"position":[[947,5]]},"80":{"position":[[659,5]]}}}],["android",{"_index":57,"t":{"10":{"position":[[106,7]]},"22":{"position":[[29,8],[99,8],[491,7]]},"41":{"position":[[423,7]]},"43":{"position":[[259,7],[776,7],[1130,7]]},"49":{"position":[[19,7],[168,8]]},"93":{"position":[[157,7]]},"127":{"position":[[123,7]]}}}],["android'",{"_index":573,"t":{"127":{"position":[[170,9]]}}}],["annot",{"_index":538,"t":{"121":{"position":[[379,11]]}}}],["api",{"_index":119,"t":{"20":{"position":[[109,3]]},"31":{"position":[[9,3]]},"69":{"position":[[299,4],[486,4]]},"80":{"position":[[196,3],[293,3],[590,3],[790,3]]},"121":{"position":[[109,4],[244,4],[303,4],[403,3]]}}}],["api(\"co.touchlab:kermit",{"_index":383,"t":{"69":{"position":[[744,23]]}}}],["appli",{"_index":233,"t":{"33":{"position":[[651,7]]},"41":{"position":[[193,5]]}}}],["applic",{"_index":530,"t":{"121":{"position":[[65,11]]}}}],["argument",{"_index":171,"t":{"22":{"position":[[56,10]]}}}],["artifact",{"_index":117,"t":{"20":{"position":[[20,8]]}}}],["assert",{"_index":533,"t":{"121":{"position":[[253,9]]}}}],["assertequals(\"mi",{"_index":570,"t":{"125":{"position":[[1029,16]]}}}],["assertequals(\"th",{"_index":568,"t":{"125":{"position":[[954,17]]}}}],["assertequals(severity.info",{"_index":569,"t":{"125":{"position":[[991,27]]}}}],["assertnull(throw",{"_index":571,"t":{"125":{"position":[[1057,21]]}}}],["asserttru",{"_index":562,"t":{"125":{"position":[[616,12]]}}}],["atag",{"_index":323,"t":{"43":{"position":[[745,7],[815,7],[858,6]]}}}],["atom",{"_index":271,"t":{"39":{"position":[[708,6]]}}}],["avail",{"_index":230,"t":{"33":{"position":[[499,9],[547,9]]}}}],["avoid",{"_index":145,"t":{"20":{"position":[[649,5]]}}}],["awar",{"_index":66,"t":{"12":{"position":[[39,5]]},"20":{"position":[[103,5]]}}}],["back",{"_index":354,"t":{"55":{"position":[[419,4]]}}}],["bad",{"_index":373,"t":{"69":{"position":[[385,3]]}}}],["base",{"_index":110,"t":{"18":{"position":[[136,5]]},"22":{"position":[[338,4]]},"55":{"position":[[229,5]]},"121":{"position":[[410,5]]}}}],["baselogger(loggerconfiginit(platformlogwrit",{"_index":422,"t":{"80":{"position":[[990,49]]}}}],["basic",{"_index":62,"t":{"12":{"position":[[4,5]]},"14":{"position":[[306,5]]},"20":{"position":[[1087,5]]}}}],["befor",{"_index":456,"t":{"95":{"position":[[617,6]]},"109":{"position":[[165,6]]},"121":{"position":[[485,6]]}}}],["below",{"_index":241,"t":{"35":{"position":[[38,5]]},"95":{"position":[[378,6]]}}}],["better",{"_index":88,"t":{"14":{"position":[[444,7]]},"39":{"position":[[834,7]]}}}],["between",{"_index":308,"t":{"43":{"position":[[150,7]]}}}],["boolean",{"_index":459,"t":{"95":{"position":[[705,7],[1094,7]]}}}],["both",{"_index":142,"t":{"20":{"position":[[576,4]]},"61":{"position":[[0,4]]}}}],["box",{"_index":15,"t":{"2":{"position":[[167,4]]},"4":{"position":[[97,3]]},"45":{"position":[[49,4]]}}}],["breadcrumb",{"_index":358,"t":{"63":{"position":[[73,10]]},"100":{"position":[[8,10]]}}}],["breadcrumb/log",{"_index":347,"t":{"55":{"position":[[98,14]]}}}],["breakdown",{"_index":310,"t":{"43":{"position":[[177,9]]}}}],["breedcallbackviewmodel",{"_index":237,"t":{"33":{"position":[[725,23]]}}}],["bugsnag",{"_index":98,"t":{"16":{"position":[[269,8]]},"55":{"position":[[569,8]]},"59":{"position":[[4,7]]},"72":{"position":[[28,7],[84,7]]},"78":{"position":[[29,8]]},"80":{"position":[[719,8]]},"100":{"position":[[0,7]]},"115":{"position":[[373,9]]}}}],["bugsnag:2.0.3",{"_index":396,"t":{"74":{"position":[[63,15]]}}}],["bugsnagkotlin.setcustomvalue(\"somekey",{"_index":398,"t":{"78":{"position":[[87,39]]}}}],["cach",{"_index":359,"t":{"63":{"position":[[84,6]]}}}],["call",{"_index":69,"t":{"14":{"position":[[21,5],[271,4]]},"20":{"position":[[218,7],[298,7]]},"22":{"position":[[321,5]]},"31":{"position":[[98,4]]},"33":{"position":[[134,4],[525,5],[710,5]]},"35":{"position":[[301,4]]},"37":{"position":[[66,4]]},"43":{"position":[[725,4]]},"69":{"position":[[8,4],[80,7],[165,7],[338,7],[422,6],[463,4],[960,4]]},"78":{"position":[[62,4]]},"89":{"position":[[66,4]]},"111":{"position":[[205,4]]},"125":{"position":[[92,7],[610,5]]}}}],["can't",{"_index":261,"t":{"39":{"position":[[114,5]]}}}],["care",{"_index":431,"t":{"91":{"position":[[16,4]]}}}],["case",{"_index":131,"t":{"20":{"position":[[284,4]]},"39":{"position":[[13,6],[369,4],[480,5]]},"41":{"position":[[602,6]]},"43":{"position":[[552,5]]},"69":{"position":[[330,4],[510,5]]},"121":{"position":[[543,6]]}}}],["catch(t",{"_index":83,"t":{"14":{"position":[[389,8]]}}}],["central",{"_index":213,"t":{"29":{"position":[[189,7]]}}}],["chang",{"_index":180,"t":{"22":{"position":[[327,6]]},"39":{"position":[[66,6],[123,7],[279,7],[433,7]]},"121":{"position":[[465,6]]}}}],["check",{"_index":27,"t":{"2":{"position":[[289,5]]},"95":{"position":[[600,5]]},"109":{"position":[[464,8]]}}}],["choic",{"_index":412,"t":{"80":{"position":[[304,7]]}}}],["choos",{"_index":227,"t":{"33":{"position":[[422,6]]}}}],["class",{"_index":183,"t":{"22":{"position":[[470,5],[509,5]]},"33":{"position":[[19,5]]},"95":{"position":[[205,5],[385,5],[846,5]]},"117":{"position":[[19,5]]},"125":{"position":[[65,7],[220,5]]}}}],["click",{"_index":513,"t":{"115":{"position":[[513,5],[601,5],[689,5],[777,5]]}}}],["client",{"_index":125,"t":{"20":{"position":[[190,8]]}}}],["clutter",{"_index":339,"t":{"49":{"position":[[64,9]]}}}],["co.touchlab.kermit",{"_index":443,"t":{"93":{"position":[[635,18]]}}}],["co.touchlab.kermit.logg",{"_index":427,"t":{"80":{"position":[[1277,25]]}}}],["cocoapod",{"_index":385,"t":{"69":{"position":[[789,9]]}}}],["code",{"_index":10,"t":{"2":{"position":[[110,4]]},"14":{"position":[[37,4]]},"33":{"position":[[517,4]]},"37":{"position":[[84,5],[151,4]]},"69":{"position":[[36,5]]},"111":{"position":[[362,5]]},"121":{"position":[[77,4]]}}}],["collect",{"_index":243,"t":{"35":{"position":[[105,10]]}}}],["come",{"_index":471,"t":{"104":{"position":[[25,5]]}}}],["common",{"_index":104,"t":{"18":{"position":[[23,6]]},"20":{"position":[[273,6]]},"22":{"position":[[19,6],[484,6]]},"37":{"position":[[77,6]]},"41":{"position":[[199,6]]},"43":{"position":[[325,6],[841,6]]},"115":{"position":[[506,6],[594,6],[682,6],[770,6]]}}}],["commonli",{"_index":312,"t":{"43":{"position":[[208,8]]}}}],["commonmain",{"_index":41,"t":{"6":{"position":[[46,10],[105,10]]},"69":{"position":[[604,10]]},"74":{"position":[[0,10]]},"85":{"position":[[0,10]]},"107":{"position":[[0,10]]}}}],["commontest",{"_index":545,"t":{"123":{"position":[[72,10]]}}}],["commonwrit",{"_index":92,"t":{"16":{"position":[[125,12]]},"93":{"position":[[63,12],[374,16]]}}}],["compat",{"_index":336,"t":{"47":{"position":[[37,10]]},"80":{"position":[[676,10]]}}}],["complex",{"_index":35,"t":{"4":{"position":[[54,8]]},"37":{"position":[[180,7]]},"80":{"position":[[1234,7]]}}}],["compon",{"_index":63,"t":{"12":{"position":[[10,10]]},"33":{"position":[[626,11]]}}}],["compos",{"_index":12,"t":{"2":{"position":[[132,10]]}}}],["compromis",{"_index":374,"t":{"69":{"position":[[389,11]]}}}],["config",{"_index":36,"t":{"4":{"position":[[79,6]]},"39":{"position":[[77,7],[384,6],[666,6],[892,7],[970,6]]},"41":{"position":[[495,6]]}}}],["configur",{"_index":25,"t":{"2":{"position":[[274,10]]},"4":{"position":[[0,13]]},"10":{"position":[[75,10]]},"14":{"position":[[244,9]]},"18":{"position":[[247,13]]},"22":{"position":[[622,10],[738,14]]},"29":{"position":[[208,14]]},"33":{"position":[[120,9]]},"37":{"position":[[188,14]]},"55":{"position":[[238,14]]},"72":{"position":[[18,9]]},"80":{"position":[[72,13]]},"83":{"position":[[18,9]]},"127":{"position":[[212,9]]}}}],["conflict",{"_index":414,"t":{"80":{"position":[[450,8]]}}}],["consid",{"_index":542,"t":{"121":{"position":[[514,8]]}}}],["consol",{"_index":61,"t":{"10":{"position":[[186,8]]},"43":{"position":[[290,7]]},"93":{"position":[[232,7]]}}}],["consolewrit",{"_index":435,"t":{"93":{"position":[[211,13]]}}}],["construct",{"_index":330,"t":{"43":{"position":[[1108,11]]}}}],["context",{"_index":379,"t":{"69":{"position":[[569,8]]}}}],["control",{"_index":108,"t":{"18":{"position":[[97,7]]},"41":{"position":[[150,7]]}}}],["conveni",{"_index":239,"t":{"33":{"position":[[793,11]]},"35":{"position":[[334,11]]}}}],["convent",{"_index":337,"t":{"49":{"position":[[27,11]]}}}],["core",{"_index":402,"t":{"80":{"position":[[146,5],[233,5],[636,4],[899,4]]}}}],["correspond",{"_index":72,"t":{"14":{"position":[[124,13]]}}}],["could'v",{"_index":86,"t":{"14":{"position":[[430,8]]}}}],["count",{"_index":514,"t":{"115":{"position":[[519,6],[607,6],[695,6],[783,6]]}}}],["cover",{"_index":116,"t":{"18":{"position":[[228,5]]}}}],["crash",{"_index":95,"t":{"16":{"position":[[239,5]]},"55":{"position":[[0,5],[131,5],[297,5],[339,5],[385,5]]},"61":{"position":[[5,5]]},"63":{"position":[[56,5]]},"65":{"position":[[70,5]]}}}],["crashkio",{"_index":346,"t":{"55":{"position":[[42,10],[429,10],[516,9]]},"72":{"position":[[40,9],[74,9]]},"78":{"position":[[67,9]]},"83":{"position":[[44,9],[78,9]]},"89":{"position":[[71,9]]}}}],["crashlyt",{"_index":97,"t":{"16":{"position":[[253,11]]},"55":{"position":[[553,11]]},"57":{"position":[[4,11]]},"80":{"position":[[703,11]]},"83":{"position":[[28,11],[88,11]]},"89":{"position":[[29,12]]},"98":{"position":[[0,11]]}}}],["crashlytics:2.0.3",{"_index":428,"t":{"85":{"position":[[63,19]]}}}],["crashlyticskotlin.setcustomvalue(\"somekey",{"_index":430,"t":{"89":{"position":[[91,43]]}}}],["creat",{"_index":100,"t":{"16":{"position":[[328,6]]},"22":{"position":[[359,6],[416,6]]},"33":{"position":[[81,6]]},"35":{"position":[[257,8],[358,6]]},"37":{"position":[[102,6]]},"39":{"position":[[175,8],[463,8],[913,6]]},"43":{"position":[[1218,6]]},"65":{"position":[[319,6]]},"80":{"position":[[574,6]]},"93":{"position":[[266,7]]}}}],["creation",{"_index":147,"t":{"20":{"position":[[673,8]]}}}],["current",{"_index":333,"t":{"43":{"position":[[1160,9]]},"55":{"position":[[526,9]]},"121":{"position":[[395,7]]}}}],["custom",{"_index":190,"t":{"22":{"position":[[670,9]]},"29":{"position":[[119,6]]},"43":{"position":[[933,6],[1227,6]]},"78":{"position":[[12,6]]},"89":{"position":[[12,6]]},"95":{"position":[[22,6],[543,6],[728,6],[1027,6]]},"117":{"position":[[177,6]]}}}],["d",{"_index":76,"t":{"14":{"position":[[211,4]]}}}],["date",{"_index":327,"t":{"43":{"position":[[983,4]]}}}],["debug",{"_index":360,"t":{"63":{"position":[[132,5]]}}}],["decid",{"_index":432,"t":{"91":{"position":[[24,8]]}}}],["declar",{"_index":488,"t":{"111":{"position":[[59,8]]}}}],["default",{"_index":16,"t":{"2":{"position":[[184,8]]},"4":{"position":[[71,7]]},"10":{"position":[[3,8]]},"20":{"position":[[124,7],[235,7]]},"22":{"position":[[81,7],[250,7],[343,7]]},"27":{"position":[[82,7]]},"31":{"position":[[75,7]]},"33":{"position":[[60,7]]},"47":{"position":[[75,8]]},"63":{"position":[[95,7]]},"65":{"position":[[214,7]]},"67":{"position":[[97,7]]},"69":{"position":[[130,7],[522,7]]},"93":{"position":[[3,7],[27,7],[547,7]]},"95":{"position":[[115,7]]},"115":{"position":[[12,7]]},"127":{"position":[[4,7],[131,8]]}}}],["default_min_sever",{"_index":250,"t":{"35":{"position":[[465,22]]}}}],["defaultformatt",{"_index":367,"t":{"67":{"position":[[73,16]]},"93":{"position":[[732,18]]}}}],["defaultlogformatt",{"_index":320,"t":{"43":{"position":[[630,19]]}}}],["defin",{"_index":118,"t":{"20":{"position":[[43,7]]},"35":{"position":[[13,7]]}}}],["definit",{"_index":149,"t":{"20":{"position":[[725,11]]}}}],["depend",{"_index":39,"t":{"6":{"position":[[11,10],[118,12]]},"43":{"position":[[695,9]]},"69":{"position":[[628,12],[722,12]]},"74":{"position":[[13,12]]},"80":{"position":[[906,10]]},"85":{"position":[[13,12]]},"104":{"position":[[116,10]]},"107":{"position":[[13,12]]},"109":{"position":[[485,12]]},"121":{"position":[[23,11]]},"123":{"position":[[20,6],[85,12]]}}}],["deprec",{"_index":202,"t":{"24":{"position":[[100,10]]}}}],["design",{"_index":215,"t":{"31":{"position":[[16,8]]},"37":{"position":[[121,8]]},"69":{"position":[[228,8]]},"80":{"position":[[297,6],[477,7]]},"115":{"position":[[37,8]]}}}],["detail",{"_index":302,"t":{"41":{"position":[[699,7]]},"67":{"position":[[27,7]]}}}],["develop",{"_index":31,"t":{"2":{"position":[[323,10]]},"10":{"position":[[90,12]]},"93":{"position":[[614,12]]},"115":{"position":[[56,12]]}}}],["differ",{"_index":32,"t":{"4":{"position":[[18,9]]},"14":{"position":[[96,9],[141,9]]},"16":{"position":[[43,9]]},"55":{"position":[[366,9]]}}}],["difficult",{"_index":172,"t":{"22":{"position":[[120,9]]}}}],["directli",{"_index":136,"t":{"20":{"position":[[404,9]]},"55":{"position":[[313,9]]},"78":{"position":[[77,9]]},"89":{"position":[[81,9]]},"111":{"position":[[210,9]]},"125":{"position":[[831,8]]}}}],["disabl",{"_index":366,"t":{"65":{"position":[[350,7]]}}}],["discuss",{"_index":192,"t":{"22":{"position":[[708,7]]}}}],["dispatch",{"_index":70,"t":{"14":{"position":[[46,10]]}}}],["display",{"_index":191,"t":{"22":{"position":[[686,7]]}}}],["doc",{"_index":300,"t":{"41":{"position":[[673,3]]},"72":{"position":[[101,4]]},"83":{"position":[[109,4]]}}}],["document",{"_index":196,"t":{"24":{"position":[[24,13]]}}}],["doesn't",{"_index":451,"t":{"95":{"position":[[138,7]]},"121":{"position":[[118,7]]}}}],["domain",{"_index":352,"t":{"55":{"position":[[376,8]]}}}],["don't",{"_index":126,"t":{"20":{"position":[[204,5]]},"22":{"position":[[192,5]]},"41":{"position":[[231,5]]},"43":{"position":[[1079,5]]},"111":{"position":[[107,5]]}}}],["done",{"_index":439,"t":{"93":{"position":[[441,4]]}}}],["dramat",{"_index":540,"t":{"121":{"position":[[472,12]]}}}],["dure",{"_index":436,"t":{"93":{"position":[[308,6]]}}}],["e",{"_index":78,"t":{"14":{"position":[[226,4]]}}}],["each",{"_index":56,"t":{"10":{"position":[[53,4]]},"20":{"position":[[335,4]]},"22":{"position":[[312,4]]},"33":{"position":[[705,4]]},"43":{"position":[[998,4]]},"93":{"position":[[49,4],[413,4]]},"115":{"position":[[69,4]]},"117":{"position":[[204,4]]}}}],["earlier",{"_index":351,"t":{"55":{"position":[[258,7]]},"69":{"position":[[196,7]]}}}],["easi",{"_index":23,"t":{"2":{"position":[[255,4]]},"102":{"position":[[27,4]]}}}],["easier",{"_index":549,"t":{"125":{"position":[[151,7]]}}}],["easili",{"_index":176,"t":{"22":{"position":[[233,7],[694,7]]}}}],["emoji",{"_index":494,"t":{"115":{"position":[[106,6]]},"117":{"position":[[61,5]]}}}],["empti",{"_index":178,"t":{"22":{"position":[[268,5]]}}}],["encourag",{"_index":205,"t":{"24":{"position":[[140,9]]}}}],["end",{"_index":158,"t":{"20":{"position":[[1011,3]]}}}],["entri",{"_index":257,"t":{"37":{"position":[[240,5]]},"93":{"position":[[469,5]]},"125":{"position":[[502,5],[823,7]]}}}],["environ",{"_index":33,"t":{"4":{"position":[[28,12]]},"31":{"position":[[121,13]]},"69":{"position":[[99,12]]}}}],["equal",{"_index":362,"t":{"65":{"position":[[118,5]]}}}],["error(messag",{"_index":425,"t":{"80":{"position":[[1121,14]]}}}],["especi",{"_index":483,"t":{"109":{"position":[[440,10]]},"111":{"position":[[303,10]]}}}],["etc",{"_index":164,"t":{"20":{"position":[[1252,3]]},"69":{"position":[[646,3],[740,3]]}}}],["evalu",{"_index":139,"t":{"20":{"position":[[495,9],[686,11]]}}}],["everybodi",{"_index":416,"t":{"80":{"position":[[512,9]]}}}],["everyth",{"_index":555,"t":{"125":{"position":[[323,10]]}}}],["everywher",{"_index":231,"t":{"33":{"position":[[557,11]]}}}],["ex",{"_index":169,"t":{"20":{"position":[[1327,3]]}}}],["exampl",{"_index":160,"t":{"20":{"position":[[1162,8]]},"22":{"position":[[407,8]]},"31":{"position":[[139,7]]},"33":{"position":[[573,8]]},"43":{"position":[[617,8]]},"47":{"position":[[117,8]]},"69":{"position":[[910,7]]},"80":{"position":[[810,8],[1242,8]]}}}],["except",{"_index":350,"t":{"55":{"position":[[181,10]]},"65":{"position":[[199,10],[329,9],[366,9]]},"117":{"position":[[145,11]]}}}],["exist",{"_index":415,"t":{"80":{"position":[[468,8]]}}}],["expect",{"_index":444,"t":{"93":{"position":[[654,6]]}}}],["expect/actu",{"_index":254,"t":{"37":{"position":[[26,13],[275,13]]},"93":{"position":[[495,13]]}}}],["experimentalkermitapi",{"_index":537,"t":{"121":{"position":[[356,22]]}}}],["explain",{"_index":301,"t":{"41":{"position":[[677,8]]}}}],["explicit",{"_index":376,"t":{"69":{"position":[[454,8]]}}}],["explicitli",{"_index":388,"t":{"69":{"position":[[1003,10]]}}}],["export",{"_index":218,"t":{"31":{"position":[[186,6]]},"69":{"position":[[878,6]]}}}],["export(\"co.touchlab:kermit",{"_index":387,"t":{"69":{"position":[[813,26]]}}}],["extend",{"_index":24,"t":{"2":{"position":[[263,6]]},"95":{"position":[[184,6]]}}}],["extens",{"_index":419,"t":{"80":{"position":[[687,10]]},"111":{"position":[[180,9]]}}}],["factori",{"_index":255,"t":{"37":{"position":[[40,7],[289,7]]},"93":{"position":[[509,7],[555,7],[781,7]]},"111":{"position":[[70,7],[142,8]]}}}],["fail",{"_index":167,"t":{"20":{"position":[[1282,7],[1318,8]]}}}],["fairli",{"_index":37,"t":{"4":{"position":[[104,6]]},"69":{"position":[[180,6]]}}}],["familiar",{"_index":107,"t":{"18":{"position":[[79,9]]}}}],["feedback",{"_index":411,"t":{"80":{"position":[[274,8],[341,8],[395,8]]}}}],["feel",{"_index":338,"t":{"49":{"position":[[59,4]]}}}],["few",{"_index":311,"t":{"43":{"position":[[204,3]]},"45":{"position":[[18,3]]},"80":{"position":[[253,3]]}}}],["field",{"_index":181,"t":{"22":{"position":[[425,5]]},"39":{"position":[[673,6]]}}}],["filter",{"_index":479,"t":{"109":{"position":[[298,6]]}}}],["firebas",{"_index":355,"t":{"55":{"position":[[544,8]]}}}],["first",{"_index":393,"t":{"72":{"position":[[4,5]]},"83":{"position":[[4,5]]}}}],["fit",{"_index":175,"t":{"22":{"position":[[205,3]]},"95":{"position":[[146,3]]}}}],["flexibl",{"_index":286,"t":{"41":{"position":[[44,9]]}}}],["follow",{"_index":103,"t":{"18":{"position":[[16,6]]},"41":{"position":[[522,10]]},"43":{"position":[[669,9]]},"95":{"position":[[822,10]]}}}],["form",{"_index":159,"t":{"20":{"position":[[1093,5]]}}}],["format",{"_index":214,"t":{"29":{"position":[[197,10]]},"41":{"position":[[16,10],[206,11]]},"43":{"position":[[988,6]]},"47":{"position":[[21,6],[97,9]]},"67":{"position":[[12,10],[45,6]]}}}],["formatt",{"_index":298,"t":{"41":{"position":[[644,11]]},"51":{"position":[[5,9]]}}}],["framework",{"_index":386,"t":{"69":{"position":[[801,9]]}}}],["friendli",{"_index":216,"t":{"31":{"position":[[38,9]]},"69":{"position":[[249,9],[290,8]]}}}],["fun",{"_index":152,"t":{"20":{"position":[[779,3],[890,3]]},"35":{"position":[[390,3]]},"39":{"position":[[1085,3]]},"80":{"position":[[1042,3],[1117,3]]},"93":{"position":[[661,3]]},"95":{"position":[[433,3],[656,3],[928,3],[1045,3]]},"125":{"position":[[534,3],[846,3]]}}}],["function",{"_index":137,"t":{"20":{"position":[[432,8],[478,8],[618,8],[760,8],[982,8],[1022,8]]},"33":{"position":[[805,8]]},"35":{"position":[[346,8]]},"37":{"position":[[48,9]]},"49":{"position":[[146,8]]},"80":{"position":[[107,13]]},"93":{"position":[[517,9],[563,8],[789,8]]},"127":{"position":[[259,8]]}}}],["function(",{"_index":259,"t":{"37":{"position":[[297,12]]}}}],["gener",{"_index":106,"t":{"18":{"position":[[69,9]]}}}],["get",{"_index":381,"t":{"69":{"position":[[618,7],[712,7]]}}}],["getloggerwithtag",{"_index":490,"t":{"111":{"position":[[161,18]]}}}],["getwith(\"breedcallbackviewmodel",{"_index":238,"t":{"33":{"position":[[756,33]]}}}],["give",{"_index":291,"t":{"41":{"position":[[295,4]]}}}],["global",{"_index":220,"t":{"33":{"position":[[143,6],[288,6],[537,6]]},"39":{"position":[[213,6],[861,6],[929,6]]},"41":{"position":[[453,6]]},"111":{"position":[[279,6]]},"125":{"position":[[104,8]]}}}],["go",{"_index":480,"t":{"109":{"position":[[321,5]]}}}],["gone",{"_index":87,"t":{"14":{"position":[[439,4]]}}}],["gradle.properti",{"_index":203,"t":{"24":{"position":[[111,17]]}}}],["handl",{"_index":345,"t":{"55":{"position":[[29,7],[171,9]]},"95":{"position":[[314,7],[519,6]]}}}],["happi",{"_index":417,"t":{"80":{"position":[[522,6]]}}}],["hello",{"_index":51,"t":{"8":{"position":[[11,6]]},"14":{"position":[[348,6]]},"20":{"position":[[1135,6],[1223,6]]},"33":{"position":[[268,6],[388,6]]},"39":{"position":[[1089,8],[1111,7]]}}}],["help",{"_index":484,"t":{"109":{"position":[[451,7]]}}}],["helper",{"_index":472,"t":{"104":{"position":[[137,8]]}}}],["here",{"_index":148,"t":{"20":{"position":[[698,4]]},"43":{"position":[[167,4]]},"95":{"position":[[534,4]]}}}],["higher",{"_index":365,"t":{"65":{"position":[[306,7]]}}}],["hold",{"_index":532,"t":{"121":{"position":[[192,5]]}}}],["ignor",{"_index":189,"t":{"22":{"position":[[636,6]]},"35":{"position":[[73,8]]},"49":{"position":[[100,6],[202,6]]},"63":{"position":[[169,8]]}}}],["impact",{"_index":274,"t":{"39":{"position":[[758,6]]}}}],["implement",{"_index":324,"t":{"43":{"position":[[923,9],[1234,14]]},"45":{"position":[[22,15]]},"55":{"position":[[285,11]]},"61":{"position":[[21,15]]},"80":{"position":[[956,15],[1259,14]]},"93":{"position":[[769,9]]},"95":{"position":[[29,14],[123,14],[282,9],[347,14],[787,14]]},"104":{"position":[[55,14]]},"113":{"position":[[26,15]]},"117":{"position":[[165,9]]},"119":{"position":[[7,14]]}}}],["implementation(\"co.touchlab:kermit",{"_index":395,"t":{"74":{"position":[[28,34]]},"85":{"position":[[28,34]]},"107":{"position":[[28,34]]},"123":{"position":[[100,34]]}}}],["implementation(\"co.touchlab:kermit:2.0.3",{"_index":46,"t":{"6":{"position":[[137,42]]},"69":{"position":[[650,42]]}}}],["includ",{"_index":53,"t":{"10":{"position":[[19,8]]},"16":{"position":[[114,8],[295,8]]},"27":{"position":[[13,8],[38,9]]},"29":{"position":[[38,7]]},"31":{"position":[[53,8]]},"80":{"position":[[32,7]]},"121":{"position":[[7,8],[161,8]]}}}],["incorpor",{"_index":413,"t":{"80":{"position":[[375,13]]}}}],["info",{"_index":96,"t":{"16":{"position":[[245,4],[287,4]]},"20":{"position":[[162,4],[973,4]]},"29":{"position":[[126,4]]},"43":{"position":[[880,4]]},"55":{"position":[[253,4]]},"63":{"position":[[115,5]]},"115":{"position":[[383,6]]},"125":{"position":[[0,4]]}}}],["info(messag",{"_index":423,"t":{"80":{"position":[[1046,13]]}}}],["initi",{"_index":264,"t":{"39":{"position":[[316,12]]},"72":{"position":[[50,15]]},"83":{"position":[[54,15]]},"93":{"position":[[315,14]]},"109":{"position":[[146,11]]}}}],["initializd",{"_index":262,"t":{"39":{"position":[[136,11]]}}}],["inject",{"_index":232,"t":{"33":{"position":[[606,6]]},"102":{"position":[[39,10]]},"104":{"position":[[127,9]]},"111":{"position":[[230,9]]},"125":{"position":[[31,6]]}}}],["instanc",{"_index":55,"t":{"10":{"position":[[40,8]]},"14":{"position":[[75,10]]},"16":{"position":[[84,9],[178,10]]},"22":{"position":[[375,8]]},"27":{"position":[[100,10]]},"29":{"position":[[10,9]]},"33":{"position":[[45,8],[97,8],[157,9],[469,8]]},"35":{"position":[[129,9],[281,9],[380,9]]},"39":{"position":[[199,9],[298,8],[412,8],[451,8],[580,9]]},"41":{"position":[[76,9],[315,9]]},"43":{"position":[[493,8]]},"47":{"position":[[58,9]]},"53":{"position":[[39,10]]},"55":{"position":[[79,9],[207,9]]},"69":{"position":[[1047,8]]},"95":{"position":[[232,9]]},"111":{"position":[[89,10],[247,9],[293,9]]},"115":{"position":[[123,9]]},"125":{"position":[[45,9]]}}}],["instead",{"_index":265,"t":{"39":{"position":[[518,7]]}}}],["integ",{"_index":470,"t":{"104":{"position":[[14,10]]}}}],["integr",{"_index":468,"t":{"102":{"position":[[0,11]]}}}],["intend",{"_index":529,"t":{"121":{"position":[[35,8]]}}}],["interact",{"_index":80,"t":{"14":{"position":[[312,11]]},"121":{"position":[[87,9]]},"125":{"position":[[473,8],[793,8]]}}}],["interfac",{"_index":244,"t":{"35":{"position":[[164,9]]},"55":{"position":[[477,9]]},"80":{"position":[[594,9],[732,9]]}}}],["intern",{"_index":539,"t":{"121":{"position":[[446,11]]}}}],["interop",{"_index":369,"t":{"69":{"position":[[65,7]]}}}],["io",{"_index":59,"t":{"10":{"position":[[138,3]]},"41":{"position":[[269,3]]},"43":{"position":[[277,5]]},"93":{"position":[[207,3]]},"113":{"position":[[46,4]]}}}],["iosmain",{"_index":382,"t":{"69":{"position":[[701,7]]}}}],["islogg",{"_index":455,"t":{"95":{"position":[[576,11]]}}}],["isloggable(tag",{"_index":458,"t":{"95":{"position":[[660,15],[1049,15]]}}}],["isproduct",{"_index":464,"t":{"95":{"position":[[1104,12]]}}}],["isproduction:boolean",{"_index":463,"t":{"95":{"position":[[881,21]]}}}],["it'",{"_index":5,"t":{"2":{"position":[[50,4]]},"22":{"position":[[389,4]]},"109":{"position":[[249,4]]}}}],["itself",{"_index":305,"t":{"43":{"position":[[63,7]]},"65":{"position":[[108,6]]}}}],["js",{"_index":60,"t":{"10":{"position":[[170,2]]},"20":{"position":[[327,3]]},"41":{"position":[[276,2]]},"43":{"position":[[287,2]]},"93":{"position":[[250,2]]}}}],["jvm",{"_index":270,"t":{"39":{"position":[[700,3]]},"43":{"position":[[315,5]]}}}],["kamp",{"_index":28,"t":{"2":{"position":[[299,4]]}}}],["kermit",{"_index":0,"t":{"2":{"position":[[0,6]]},"6":{"position":[[4,6]]},"10":{"position":[[12,6]]},"14":{"position":[[329,7]]},"16":{"position":[[107,6],[212,6]]},"20":{"position":[[306,6]]},"24":{"position":[[71,6]]},"31":{"position":[[103,6],[193,6]]},"43":{"position":[[1018,6]]},"45":{"position":[[0,6]]},"55":{"position":[[53,6],[278,6],[444,6],[505,6]]},"69":{"position":[[13,6],[216,6],[346,6],[429,6],[885,6]]},"78":{"position":[[54,7]]},"80":{"position":[[43,7],[139,6],[161,6],[226,6],[320,7],[629,6],[762,6],[892,6],[929,7],[1306,7]]},"89":{"position":[[58,7]]},"93":{"position":[[11,6],[527,6]]},"95":{"position":[[588,6]]},"104":{"position":[[104,7]]},"109":{"position":[[158,6],[424,7]]},"121":{"position":[[0,6],[102,6],[439,6]]},"125":{"position":[[348,6]]},"127":{"position":[[21,6]]}}}],["kermit'",{"_index":177,"t":{"22":{"position":[[241,8]]},"31":{"position":[[0,8]]},"80":{"position":[[546,8]]},"104":{"position":[[0,8]]}}}],["kermitkoinlogger(logger.withtag(\"koin",{"_index":476,"t":{"109":{"position":[[42,40]]}}}],["kermitloggermodul",{"_index":487,"t":{"111":{"position":[[4,20]]}}}],["kermitsampleios[58575:7607179",{"_index":503,"t":{"115":{"position":[[266,30],[472,30],[560,30],[648,30],[736,30]]}}}],["kermitsampleios[58575:7607442",{"_index":505,"t":{"115":{"position":[[342,30]]}}}],["kit",{"_index":29,"t":{"2":{"position":[[304,3]]}}}],["know",{"_index":297,"t":{"41":{"position":[[633,4]]},"111":{"position":[[322,4]]}}}],["koin",{"_index":469,"t":{"102":{"position":[[17,5]]},"104":{"position":[[9,4],[82,4]]},"109":{"position":[[198,5],[272,4],[386,4]]},"111":{"position":[[42,4],[137,4]]}}}],["koin:2.0.3",{"_index":473,"t":{"107":{"position":[[63,12]]}}}],["koinappl",{"_index":474,"t":{"109":{"position":[[4,15]]}}}],["kotlin",{"_index":1,"t":{"2":{"position":[[12,6],[103,6],[338,6]]},"6":{"position":[[76,6]]},"20":{"position":[[96,6],[183,6]]},"22":{"position":[[140,6]]},"24":{"position":[[17,6]]},"31":{"position":[[31,6]]},"33":{"position":[[275,7],[395,7]]},"69":{"position":[[29,6],[173,6],[283,6],[358,7],[562,6],[578,6]]},"93":{"position":[[107,6]]}}}],["kotlin'",{"_index":128,"t":{"20":{"position":[[226,8],[1042,8]]}}}],["lambda",{"_index":122,"t":{"20":{"position":[[147,6],[1060,6]]},"125":{"position":[[650,6]]}}}],["latest",{"_index":48,"t":{"6":{"position":[[186,6]]},"123":{"position":[[154,6]]},"125":{"position":[[491,6]]}}}],["layer",{"_index":405,"t":{"80":{"position":[[200,5]]}}}],["legaci",{"_index":527,"t":{"119":{"position":[[0,6]]}}}],["level",{"_index":73,"t":{"14":{"position":[[164,7]]},"18":{"position":[[9,6]]},"20":{"position":[[64,5]]}}}],["librari",{"_index":4,"t":{"2":{"position":[[41,8],[176,7]]},"18":{"position":[[38,7]]},"22":{"position":[[161,7]]}}}],["line",{"_index":328,"t":{"43":{"position":[[1003,5]]},"117":{"position":[[209,4]]}}}],["list",{"_index":564,"t":{"125":{"position":[[811,4]]}}}],["list - +

Search the documentation

- + \ No newline at end of file