├── 01. template.ps1 ├── 02. demo.ps1 ├── 03. Import-Configuration.ps1 ├── 04. ArgumentTransformation.ps1 ├── 05. Import-Configuration.ps1 ├── ReadMe.md ├── export ├── images │ ├── bg.png │ ├── cc-by-nc-sa.png │ ├── header.png │ └── prompt-exception.png ├── index.html ├── libs │ ├── highlight.js │ │ └── 9.12.0 │ │ │ ├── darcula.css │ │ │ ├── darkula.css │ │ │ ├── highlight.js │ │ │ └── reveal-code-focus-1.0.0-mod.js │ └── reveal.js │ │ ├── 3.7.0 │ │ ├── css │ │ │ ├── print │ │ │ │ └── paper.css │ │ │ ├── reveal.css │ │ │ └── theme │ │ │ │ └── white.css │ │ ├── js │ │ │ └── reveal.orig.js │ │ ├── lib │ │ │ ├── css │ │ │ │ └── zenburn.css │ │ │ ├── font │ │ │ │ └── source-sans-pro │ │ │ │ │ ├── source-sans-pro-italic.woff │ │ │ │ │ ├── source-sans-pro-regular.woff │ │ │ │ │ ├── source-sans-pro-semibold.woff │ │ │ │ │ └── source-sans-pro.css │ │ │ └── js │ │ │ │ └── head.min.js │ │ └── plugin │ │ │ ├── chalkboard │ │ │ ├── chalkboard.js │ │ │ └── img │ │ │ │ ├── blackboard.png │ │ │ │ ├── boardmarker.png │ │ │ │ ├── chalk.png │ │ │ │ └── sponge.png │ │ │ ├── chart │ │ │ ├── Chart.min.js │ │ │ └── csv2chart.js │ │ │ ├── embed-tweet │ │ │ └── embed-tweet.js │ │ │ ├── markdown │ │ │ ├── markdown.js │ │ │ └── marked.js │ │ │ ├── math │ │ │ ├── MathJax.js │ │ │ ├── config │ │ │ │ └── TeX-AMS_HTML-full.js │ │ │ ├── jax │ │ │ │ └── output │ │ │ │ │ └── HTML-CSS │ │ │ │ │ └── fonts │ │ │ │ │ └── STIX │ │ │ │ │ ├── General │ │ │ │ │ └── Italic │ │ │ │ │ │ ├── GreekItalic.js │ │ │ │ │ │ └── MathItalic.js │ │ │ │ │ └── fontdata.js │ │ │ └── math.js │ │ │ ├── menu │ │ │ ├── menu.css │ │ │ └── menu.js │ │ │ ├── notes │ │ │ └── notes.js │ │ │ ├── search │ │ │ └── search.js │ │ │ ├── title-footer │ │ │ ├── title-footer-mod.css │ │ │ ├── title-footer.css │ │ │ └── title-footer.js │ │ │ └── zoom-js │ │ │ └── zoom.js │ │ └── font-awesome-4.7.0 │ │ ├── css │ │ └── font-awesome.min.css │ │ └── fonts │ │ └── fontawesome-webfont.woff ├── markdown.md └── web.config ├── images ├── bg.png ├── cc-by-nc-sa.png ├── header.png └── prompt-exception.png └── should-have-been-a-book ├── 00. abstract.md ├── 01. Help You Must Write.md ├── 02. Naming Conventions.md ├── 03. Inputs and Outputs -- Types Of Objects.md ├── 03.5 History of classes.md ├── 04. UsingTypesForParameters.md ├── 05. ValueFromPipelineByPropertyName.md ├── 06. Starting from Process.md └── 07. Outputting errors that are unrecoverable.md /01. template.ps1: -------------------------------------------------------------------------------- 1 | function Import-Configuration { 2 | <# 3 | .SYNOPSIS 4 | TODO 5 | .EXAMPLE 6 | TODO 7 | #> 8 | [CmdletBinding()] 9 | param( 10 | # TODO 11 | [Parameter(ValueFromPipelineByPropertyName)] 12 | $TODO 13 | ) 14 | process { 15 | try { 16 | # TODO 17 | } catch { 18 | throw $_ 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /02. demo.ps1: -------------------------------------------------------------------------------- 1 | # A basic prompt 2 | function prompt { "$($MyInvocation.HistoryId)|$pwd> " } 3 | 4 | 5 | # When there are errors in your prompt 6 | function prompt { 7 | Write-Error "Typo"; 8 | "$($MyInvocation.HistoryId)|$pwd> " } 9 | 10 | # When there's an exception in your prompt 11 | function prompt { 12 | Write-Error "Typo" 13 | "$($MyInvocation.HistoryId)|$pwd> " 14 | throw "grenade" } 15 | 16 | # You should know to check ... 17 | $Error[0..2] 18 | 19 | # Let's look at how PowerLine handles it: 20 | Set-PowerLinePrompt 21 | 22 | # Your prompt is an array of scriptblocks 23 | $prompt 24 | 25 | # We can add an error to it 26 | Add-PowerLineBlock { Write-Error "Typo"} 27 | 28 | # We can hide that warning output: 29 | Set-PowerLinePrompt -HideErrors 30 | 31 | # Even if it's an exception! 32 | Add-PowerLineBlock { throw "grenades" } 33 | 34 | # Hiding it is probably a bad idea 35 | Set-PowerLinePrompt -HideErrors:$False 36 | 37 | # So let's look at the errors 38 | # We can see which block caused them 39 | $PromptErrors 40 | 41 | # And look more closely at the exception 42 | $PromptErrors[1] | fl * -fo 43 | 44 | # Then we can put our prompt back 45 | Remove-PowerLineBlock { Write-Error "Typo"} 46 | Remove-PowerLineBlock { throw "grenades" } -------------------------------------------------------------------------------- /03. Import-Configuration.ps1: -------------------------------------------------------------------------------- 1 | function Import-Configuration { 2 | <# 3 | .SYNOPSIS 4 | A command to load configuration for a module 5 | .EXAMPLE 6 | $Config = Import-Configuration 7 | 8 | Load THIS module's configuration from a command 9 | .EXAMPLE 10 | $Config = Import-Configuration 11 | $Config.AuthToken = $ShaToken 12 | $Config | Export-Configuration 13 | 14 | Update a single setting in the configuration 15 | .EXAMPLE 16 | $Config = Get-Module PowerLine | Import-Configuration 17 | $Config.PowerLineConfig.DefaultAddIndex = 2 18 | Get-Module PowerLine | Export-Configuration $Config 19 | 20 | Update a single setting in the configuration 21 | #> 22 | [CmdletBinding()] 23 | param( 24 | # The module to import configuration from 25 | [Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline, Mandatory)] 26 | [System.Management.Automation.PSModuleInfo]$Module 27 | ) 28 | process { 29 | try { 30 | # TODO 31 | } catch { 32 | throw $_ 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /04. ArgumentTransformation.ps1: -------------------------------------------------------------------------------- 1 | class ModuleInfoAttribute : System.Management.Automation.ArgumentTransformationAttribute { 2 | [object] Transform([System.Management.Automation.EngineIntrinsics]$engineIntrinsics, [object] $inputData) { 3 | $ModuleInfo = $null 4 | if ($inputData -is [string] -and -not [string]::IsNullOrWhiteSpace($inputData)) { 5 | $ModuleInfo = Get-Module $inputData -ErrorAction SilentlyContinue 6 | if (-not $ModuleInfo) { 7 | $ModuleInfo = @(Get-Module $inputData -ErrorAction SilentlyContinue -ListAvailable)[0] 8 | } 9 | } 10 | if (-not $ModuleInfo) { 11 | throw ([System.ArgumentException]"$inputData module could not be found, please try passing the output of 'Get-Module $InputData' instead") 12 | } 13 | return $ModuleInfo 14 | } 15 | } -------------------------------------------------------------------------------- /05. Import-Configuration.ps1: -------------------------------------------------------------------------------- 1 | using namespace System.Management.Automation 2 | 3 | class ModuleInfoAttribute : ArgumentTransformationAttribute { 4 | [object] Transform([EngineIntrinsics]$engineIntrinsics, [object] $inputData) { 5 | $ModuleInfo = $null 6 | if ($inputData -is [string] -and -not [string]::IsNullOrWhiteSpace($inputData)) { 7 | $ModuleInfo = Get-Module $inputData -ErrorAction SilentlyContinue 8 | if (-not $ModuleInfo) { 9 | $ModuleInfo = @(Get-Module $inputData -ErrorAction SilentlyContinue -ListAvailable)[0] 10 | } 11 | } 12 | if (-not $ModuleInfo) { 13 | throw ([System.ArgumentException]"$inputData module could not be found, please try passing the output of 'Get-Module $InputData' instead") 14 | } 15 | return $ModuleInfo 16 | } 17 | } 18 | 19 | function Import-Configuration { 20 | <# 21 | .SYNOPSIS 22 | A command to load configuration for a module 23 | .EXAMPLE 24 | $Config = Import-Configuration 25 | 26 | Load THIS module's configuration from a command 27 | .EXAMPLE 28 | $Config = Import-Configuration 29 | $Config.AuthToken = $ShaToken 30 | $Config | Export-Configuration 31 | 32 | Update a single setting in the configuration 33 | .EXAMPLE 34 | $Config = Get-Module PowerLine | Import-Configuration 35 | $Config.PowerLineConfig.DefaultAddIndex = 2 36 | Get-Module PowerLine | Export-Configuration $Config 37 | 38 | Update a single setting in the configuration 39 | .EXAMPLE 40 | $Config = Import-Configuration -Name Powerline -CompanyName HuddledMasses.org 41 | 42 | Load the specififed module's configuration by hand 43 | #> 44 | [CmdletBinding()] 45 | param( 46 | # The module to import configuration from 47 | [Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline, Mandatory)] 48 | [ModuleInfo()] 49 | [PSModuleInfo]$Module 50 | ) 51 | process { 52 | try { 53 | 54 | $Path = Join-Path $Env:APPDATA ( 55 | Join-Path $Module.CompanyName $Module.Name 56 | ) 57 | 58 | Import-LocalizedData -BaseDirectory $Path -FileName Configuration.psd1 59 | 60 | } catch { 61 | throw $_ 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | --- 2 | theme: "white" 3 | transition: "slide" 4 | highlightTheme: "vs" 5 | slideNumber: true 6 | defaultTiming: 100 7 | --- 8 | 9 | 10 | 11 | # Bullet-Proofing 12 | ## Patterns & Practices 13 | #### Survivable Advanced Functions and Scripts 14 | https://github.com/Jaykul/DevOps2019 15 | 16 | Joel "Jaykul" Bennett 17 | 18 | Battle Faction 19 | 20 | 21 | 22 | note: 23 | 24 | Welcome everyone to "Bullet-proofing: Patterns and practices for survivable advanced functions and scripts" ... a presentation for the PowerShell + DevOps Global Summit, 2019. I am, of course, Joel Bennett 25 | 26 | You may know me as "Jaykul" on Twitter or on the PowerShell Slack or Discord or IRC. I've been running that online chat community for about 12 years, and I am a ten-time PowerShell MVP. 27 | 28 | Before we get started today I want to tell you something about myself: Occupationally I'm a programmer. My business cards (if I had any) would say "Senior DevOps Engineer" or sometimes just "Senior Software Engineer" or "Software Architect" but at the end of the day, I'm a Battle faction hacker. It's important that you understand that as we get into our subject for today, because we're going to be talking a lot about design, but I want you to keep in mind that the only reason we're putting this much thought into our design is to make sure that our modules are usable by _other people_, and that they will survive first contact with a newbie. 29 | 30 | 31 | --- 32 | 33 | 34 | 35 | # Disclaimer 36 | 37 | My code may not actually be bullet-proof 38 | 39 | note: 40 | 41 | I want to be clear about one thing: I can promise you, up front, not all of my own code is bullet-proof. As a battle faction hacker, the truth is that in my public code, I only rarely write things that really **need** to be bullet-proof, and as a result, if you look me up on github, you're not going to find all of these patterns followed, and you may find a lot of commands that are missing exception handling. That tends to be a side-effect of the types of modules I write, where errors are unlikely, and not critical. ;) 42 | 43 | At work, it's quite different -- we write infrastructure automation and software deployment scripts. There, I have to be much more vigilant, and we prioritize logging and error handling, and so on. 44 | 45 | --- 46 | 47 | 48 | 49 | # Survivable Code 50 | 51 | - Errors are handled appropriately 52 | - Commands make sense & work together 53 | 54 | note: 55 | 56 | To me, survivable code means two things: it's about design and about error handling. Of the two, error handling is the easiest, so we're going to talk about that right up front and get it out of the way. 57 | 58 | 59 | --- 60 | 61 | 62 | 63 | # Error Handling 64 | ## What's Appropriate? 65 | - Sometimes that means not handling 66 | - Usually that means catch and release 67 | - Normal use shouldn't produce errors 68 | - Wrap **everything** in try/catch 69 | 70 | note: 71 | 72 | Obviously in PowerShell it's relatively acceptable to let errors flow from your output, but you should always do so by catching and re-throwing, not by just ignoring. There are a lot of explanations I could get into about why, and how sometimes exception only show up when there's a try/catch, but this is not an error-handling talk, it's a patterns and practices talk so I can just say: 73 | 74 | Follow this template, and add custom handling inside it when you want to suppress errors, turn them into warnings, or convert terminating exceptions into non-terminating errors or vice-versa. 75 | 76 | -- 77 | 78 | 79 | 80 | ## Code Template 81 | 82 | ```PowerShell 83 | function Test-Function { 84 | <# help here #> 85 | [CmdletBinding()]param() 86 | process { 87 | try { 88 | <# code here #> 89 | } catch { 90 | throw $_ 91 | } 92 | } 93 | } 94 | 95 | ``` 96 | note: 97 | 98 | There could be more to this template (and there will be, later), but for the moment, the point is to start with a try/catch wrapped around the inside of your process block (and your begin and end blocks too, if you need them) 99 | 100 | At a bare minimum, you're going to be rethrowing, to make sure that you don't get surprised by exceptions if someone wraps your code. I actually encourage you to test your code with `-ErrorAction Stop`, to help you identify potential problems. 101 | 102 | Remember that you can add additional try/catch statements inside, to wrap specific lines or handle particular errors. You can _of course_ handle particular errors even here, if you just need to customize the error message, or whatever, but this is meant to be the last stand, so you can't really do much to _recover_ here. 103 | 104 | Ok, let's look a real-world example: What happens if something in your `prompt` function has an error or throws an exception? 105 | 106 | -- 107 | 108 | 109 | 110 | ## Demo 1 111 | #### Not handling errors appropriately 112 | 113 | ```PowerShell 114 | function prompt { 115 | Write-Error "Typo" 116 | "$pwd> " 117 | } 118 | 119 | function prompt { 120 | Write-Error "Typo" 121 | "$pwd> " 122 | throw "grenade" 123 | } 124 | ``` 125 | 126 | What happens if something in your `prompt` function has an error or throws an exception? 127 | 128 | note: 129 | 130 | If we run these ... 131 | 1. we can see that _errors are ignored_, 132 | 2. but when the prompt throws an exception, PowerShell tosses any output it's _already gotten_ and gives you the minimalist prompt. 133 | 3. You're expected to know that this prompt means you should look in `$Error` and figure out what happened (oh, someone threw a grenade, classic). 134 | 135 | -- 136 | 137 | 138 | 139 | ## Demo 2 140 | #### Handling errors appropriately 141 | 142 | 143 | ```PowerShell 144 | Set-PowerLinePrompt 145 | $prompt 146 | $prompt += { Write-Error "Typo"} 147 | $prompt += { throw "grenades" } 148 | $PromptErrors 149 | $PromptErrors[1] | Select * 150 | $prompt = $prompt[0,1] 151 | ``` 152 | 153 | 154 | note: 155 | 156 | Let me show you what PowerLine does in that situation. PowerLine is my prompt module, and in it, your prompt is `$prompt`, a collection of script blocks. Here's an equivalent PowerLinePrompt, and let's see what happens when you add an exception ... 157 | 158 | You can see I actually still got my prompt! But I also got a warning and we can see that it's telling me how to _hide_ the error if I really want to do that... 159 | 160 | Of course, I don't really want to hide the errors. 161 | 162 | If I throw an exception, it gets logged right along with the error, and we can look at both of them in `$PromptErrors`. Notice that it tells us which block cause each problem, and of course, in this case, we can just remove those blocks. 163 | 164 | -- 165 | 166 | 167 | 168 | ## Friends log everything 169 | 170 | ```PowerShell 171 | try { 172 | Write-Information "Enter Process Import-Configuration" -Tag Trace 173 | <# code here #> 174 | } catch { 175 | Write-Information $_ -Tag Exception 176 | throw $_ 177 | } 178 | ``` 179 | 180 | Invoke it with `-Iv drip` 181 | 182 | ```PowerShell 183 | $drip | 184 | Where Tag -Contains Exception | 185 | Export-CliXml exception.logx 186 | ``` 187 | 188 | note: 189 | 190 | I want to encourage you to _log_ everything. When we're trying to track down a problem, it's extremely helpful if there are logable statements for each logic block -- you know what I mean, right? Within each branch of an `if`, or each statement of a `switch`, etc. 191 | 192 | There are a lot of **better** ways to log than what I'm showing you here, but if you don't have a logging solution, you could do a lot worse than writing it to the Information stream. 193 | 194 | The information stream is timestamped and sourced, and it's full of objects, so you can capture it with the `-InformationVariable` parameter and use Export-CliXml to dump it to a file. It's pretty straight-forward, and can even be used across remoting. 195 | 196 | -- 197 | 198 | 199 | 200 | ## In summary 201 | 202 | - Always try/catch 203 | - Rethrow by default 204 | - Only handle specific exceptions 205 | - Always log 206 | - Especially exceptions 207 | - Even Verbose output counts 208 | 209 | note: 210 | 211 | OK, before we go back to design, I want to just summarize this a little: the point here is that you should always try/catch, even if you're just rethrowing. 212 | 213 | And (especially if you're supressing exceptions), you should log the path of execution, so when something unexpected happens, you have the ability to say: look, this is what happened... 214 | 215 | OK, Now, let's improve the design... 216 | 217 | --- 218 | 219 | 220 | 221 | 222 | # Usable Commands 223 | 224 | - Intuitive and discoverable 225 | - Play well with others 226 | - **It's about good interfaces** 227 | 228 | Let's talking about design, 229 | this is my favorite part. 230 | 231 | note: 232 | 233 | So. I told you that survivable code was about writing commands that make sense, and work together. 234 | 235 | What that means is that it's about designing good interfaces 236 | 237 | - commands people can use even without reading the help, and 238 | - commands which work well _with other commands_, 239 | 240 | Let's talk about the process. 241 | 242 | I know I said I was Battle Faction ... but the truth is I'm really never quite happy with a module until the commands can pipe into each other, and the number of nouns has been reduced as far as is comfortable. I don't worry too much about total newbies, but I want to write commands that people with some PowerShell experience can pick up and use intuitively. 243 | 244 | To design commands correctly, we have to think about how they'll be used 245 | 246 | -- 247 | 248 | 249 | 250 | ## How will it be used? 251 | 252 | - How do you want to call it 253 | - What parameters do you want to pass 254 | - Where will you get those values 255 | - What are you doing with the output 256 | 257 | note: 258 | 259 | You're going to brainstorm, in a sense: How do you want to use it, or how do you think other people will use it. What commands exist which people might want to use it _with_. Where are you getting the values for your parameters? What are you doing with the output? Are you passing it to another command, formatting it for display? 260 | 261 | Now, our goal is to design the command to make these scenarios that you come up with easier. 262 | 263 | It's a good practice to start by writing down concrete examples of your answers to these questions, in pseudo code. It will help you get a feel for how you expect the command to work. When you do that, write them like this ... 264 | 265 | 266 | -- 267 | 268 | 269 | 270 | ### Write down your examples ... 271 | 272 | ```PowerShell 273 | function Import-Configuration { 274 | <# .SYNOPSIS 275 | A command to load configuration for a module 276 | .EXAMPLE 277 | $Config = Import-Configuration 278 | Load THIS module's configuration from a command 279 | .EXAMPLE 280 | $Config = Import-Configuration 281 | $Config.AuthToken = $ShaToken 282 | $Config | Export-Configuration 283 | 284 | Update a single setting in the configuration 285 | #> 286 | ``` 287 | 288 | note: 289 | 290 | When you start writing out the concrete examples, write them like this ... 291 | 292 | Hopefully, you recognize this as comment-based help for the command -- and I'm very serious. The first thing you should do when you start writing a command, is write the help. 293 | 294 | --- 295 | 296 | 297 | 298 | # First, write help 299 | 300 | We really require three things in the help: 301 | 302 | 1. A Synopsis and/or a short description 303 | 2. Examples -- for every parameter set 304 | 3. Documentation for each parameter 305 | 306 | note: 307 | 308 | I'm not suggesting you can write all of the help before you write the command, but ... 309 | 310 | When you start writing down your ideas about how you're going to use the command, it can help you to visualize what you're going to be doing with the command, and that helps you think about the necessary parameters, what the output needs to be, etc. 311 | 312 | I like to talk about the help you can't not write. That's three things: 313 | 314 | 1. A Synopsis 315 | 316 | First we need a synopsis or short description of the command. That's all it takes for the help system to engage, but describing it in a sentence can also help you to start thinking about the command: what it's job is, and what it's job is not. 317 | 318 | I encourage you to also write a full description, but for now, just write a synopsis (you'd probably get the description wrong anyway at this point). The synopsis is enough to get started. 319 | 320 | 2. An example -- for each parameter set 321 | 322 | Then we can write down our examples. At this stage, it's important that your examples aren't contrived. They should be the result of your brainstorming for how you want to use it. Each example should have an explanation of the purpose of using the command this way. 323 | 324 | In the simplest case, you can provide a single example (with no parameters), and a sentence explaining that this runs it with the default values (and explain what those are), and then explain what happens in that case. 325 | 326 | You don't need an example of every parameter, but you do need an example showing all of the _mandatory_ parameters for each parameter set. 327 | 328 | Now, maybe you don't know what those are yet, but these examples are long-lived, and you can update these and add more as you progress. 329 | 330 | It's might be worth saying that if you can't think of a real example for a parameter set -- you probably don't need that parameter set 😉. 331 | 332 | Long term, more examples are better, but only if they have significantly different _outcomes_. Examples showing parameters which just set properties on the output aren't necessary, because we're also going to write... 333 | 334 | 3. Parameter Documentation 335 | 336 | Documentation for each parameter. You can write this as you add parameters, by simply putting a comment above each one. In fact, I strongly recommend you do it that way (rather than using the `.PARAMETER` marker) because it's harder to forget to write and update! 337 | 338 | The next thing we're going to do is ... 339 | 340 | --- 341 | 342 | 343 | 344 | # Then write tests 345 | 346 | ## Remember this is design 347 | - Write tests as documentation 348 | - Document your intent and design 349 | - Prove your implementation works 350 | 351 | note: 352 | 353 | We're going to mostly skip over testing, because that's an entirely different talk (or two or three), but let me say this: 354 | 355 | You should approach tests as documentation. Think of them as documenting your intent, your design, and your examples, and ensuring that you don't break one of your own use cases at some point in the future. 356 | 357 | Listen: If you're not writing tests, start. Grab Pester. Write some _acceptance tests_, and read a little about behavior-driven development. Have a look at Gherkin syntax. 358 | 359 | But the bottom line is: make sure you have tests for each of the examples that we wrote above. 360 | 361 | --- 362 | 363 | 364 | 365 | # Pick good names 366 | 367 | Once you have some help and some tests in place, stop and think _again_ about naming things. 368 | 369 | This really is the most crucial part of your design. 370 | 371 | Parameter names define your user interface, but also your programming interface, affecting pipeline binding as well as discoverability. 372 | 373 | note: 374 | 375 | I know most of you spend some time thinking about what to name your commands right? What to name your functions or scripts. It's inevitable, because there are rules in PowerShell about naming. 376 | 377 | But you _should_ be spending even more time thinking about the names of your parameters, because parameter names are not just about users discovering how to use your command, they're also the interface by which commands interact with each other. 378 | 379 | -- 380 | 381 | 382 | 383 | ## Remember our example 384 | 385 | - So far we have one parameter 386 | - What should I call it? 387 | - Module 388 | - ModuleInfo 389 | - PSModuleInfo 390 | - Maybe `ArgumentTransformation` for strings 391 | - What about Get-Command & Get-Module 392 | 393 | note: 394 | 395 | Show the Import-Configuration code 396 | 397 | So far we have one parameter. What should it's name be? 398 | 399 | Personally, I'm leaning toward ModuleInfo, because I think the "PS" looks like a module prefix that I should not use, and ModuleInfo makes it clear that I'm not just looking for a module _name_. 400 | 401 | However, I'm considering three things: 402 | 403 | 1. Perhaps I could write a TypeAdapter for ModuleInfo to call get-module if you pass a string name. That would mean "Module" would be a good name anyway. 404 | 2. What sorts of objects exist in PowerShell that might have a ModuleInfo as a property? CommandInfo! It turns out that the output of Get-Command has a `Module` property which would work for this -- so even if I name it "ModuleInfo", I'll need to alias it as "Module" for that to work. 405 | 3. The command that returns `PSModuleInfo` is `Get-Module` and most people probably don't know the type of object it returns. 406 | 407 | -- 408 | 409 | 410 | 411 | ## Good parameter names 412 | 413 | - Recognizable and specific 414 | - Implicitly typed 415 | - Distinct 416 | - Consistent 417 | 418 | note: 419 | 420 | So what makes a good parameter name? 421 | 422 | Obviously, it's a good name if users can tell what you want! Specifically, if a user can tell what information they need to pass to each parameter --and what form the data should take-- without needing to read the help. 423 | 424 | So here are some guidelines for picking parameter names. Sometimes, these are going to cause conflicts in terms of not being able to meet all of them, but they are in priority order, and also -- you can use aliases to meet some of these goals. 425 | 426 | Parameters should be: 427 | 428 | -- 429 | 430 | 431 | 432 | ### Recognizable and Specific 433 | 434 | | Good | Better | 435 | | ---- | ------ | 436 | | `$Path` | `$FilePath` or `$DirectoryPath` 437 | | `$Name` | `$FirstName` or `$FullName` 438 | 439 | 440 | Users should know which value you actually want 441 | 442 | note: 443 | 444 | Users should be able to guess what you actually want. I put some examples here -- the idea is that more specific parameter names help people know what to pass in. 445 | 446 | -- 447 | 448 | 449 | 450 | ### Implicitly Typed 451 | 452 | | Good | Better | 453 | | ---- | ------ | 454 | | `$File` | `$FilePath` | 455 | | `$TimeOut` | `$TimeOutSeconds` | 456 | | `$Color` | `$ColorName` | 457 | 458 | Users should know what types they can pass 459 | 460 | note: 461 | 462 | Users should be able to guess about what type of object is needed, or what the unit of measurement is, and what format the data should take (that is, you know "Red" not the css hex value #FF0000) 463 | 464 | -- 465 | 466 | 467 | 468 | ### Distinct 469 | 470 | - Save typing by reducing common prefixes 471 | - Avoid uncommon terms 472 | - Avoid similarity 473 | - Avoid duplication 474 | 475 | | Good | Better | 476 | | ---- | ------ | 477 | | `$AllowClobber`, `$AllowPreRelease` | `$IgnoreCommandName`, `$AllowPrerelease` | 478 | 479 | 480 | note: 481 | 482 | Consider what happens if I use PSReadLine's `Ctrl+Space` to list parameters (look at Install-Package as a bad example!) 483 | 484 | Multiple parameters that accept similar information in different ways might seem desireable for flexibility, but it will confuse users -- even if you put them in different parameter sets. 485 | 486 | Ideally, each parameter would start with a different letter, and be a unique way to pass a specific piece of information. Less typing is better. 487 | 488 | Here's another example: if you need a username and password, don't ask for `$UserName` and `$Password` -- ask for a `$Credential`. Don't offer both options either (that is: Credential _and_ UserName/Password). More is not better, it's just more. 489 | 490 | It's ok to limit the ways a user can invoke your command (even if it means forcing them to create a credential), if it results in a dramatically clearer interface where there's only one representation of each piece of information, and it's more obvious. 491 | 492 | -- 493 | 494 | 495 | 496 | ### Consistent 497 | 498 | - Reuse parameter names ... 499 | - Match properties on output objects 500 | - Match properties on pipeline input 501 | 502 | note: 503 | 504 | Being consistent with parameter names across your module, or even parameter names on common PowerShell commands, will make it easier for users to learn and to guess based on their previous experience. 505 | 506 | Also, when we're using parameter values as output properties, try to make the names match. Your users may be already familiar with the output object, but even if they're not, they'll learn your conventions faster if the name repeats consistently. 507 | 508 | Finally, the same consideration applies to the names of properties which you want to use as input. Not only is consistecy important, it allows pipelining. 509 | 510 | Don't forget that while you _can_ use aliases to resolve pipeline inputs and even handle user expectations, but when there are too many aliases, it can lead to confusion too -- it's a lot easier for users to follow if the names match up exactly... 511 | 512 | --- 513 | 514 | 515 | 516 | # process first 517 | #### Improve performance by reducing calls 518 | 519 | - Most commands could participate in a pipeline 520 | - Use `ValueFromPipelineByPropertyName` 521 | - Or `ValueFromPipeline` (one parameter per set) 522 | 523 | This improves performance! The overhead of initializing a command is substantial. 524 | 525 | note: 526 | 527 | Once you've written your help and tests, and put some thought into parameter names, it's time to start implementing. 528 | 529 | You should start with the process block. 530 | 531 | The reality is that initializing a command is expensive (commands are objects), so it's faster to pipe multiple things to a command than to call the command multiple times. 532 | 533 | Obviously getting that improvement depends on your users calling your command that way, but you want to be able to do that. 534 | 535 | I believe most commands should be able to participate in a pipeline -- and in order for you to write commands that can, you need to put some or most of the work in the process block, and make sure that any parameters you need to use there have the `ValueFromPipelineByPropertyName` (or `ValueFromPipeline`) in their attributes. 536 | 537 | Basically, my position is that you should start by putting everything in the process block, and decorate all your parameters with `ValueFromPipelineByPropertyName`, and then remove logic from the process block as a performance optimization. 538 | 539 | 540 | -- 541 | 542 | 543 | 544 | # Optimize process 545 | 546 | What can we remove from process? 547 | 548 | - Don't pre-optimize 549 | - Begin and End blocks only run once 550 | - Code there can't use pipeline parameters 551 | - Setup and teardown code 552 | - Test and validation code 553 | 554 | note: 555 | 556 | It's tempting to just leave everything in the process block, because that pretty much guarantees that the command will work the same way regardless of how it's called (with parameters or on the pipeline). 557 | 558 | However, you should always look over your code before you're ready to share it and consider whether you can move code to the `Begin` or `End` block -- anything you can do once instead of every time will improve the performance of your command when it's in the pipeline! 559 | 560 | Some obvious examples include setup and teardown code which doesn't need to be re-run each time, and which doesn't use values from your pipeline parameters can obviously be moved, but in general: re-examine your use cases! Look for parameters which you anticipate passing only as parameters, and never as pipeline values (for example, consider `-Destination` on a `Move` command), and see if you're doing anything with _just those parameters_ that could be moved to the `begin` or `end` blocks. 561 | 562 | Remember: you can't _safely_ refer to any parameter that's set as `ValueFromPipelineByPropertyName` or `ValueFromPipeline` in the `begin` block -- but you _can_ collect those values for use in the `end` block. 563 | 564 | --- 565 | 566 | 567 | 568 | # Customizing Types 569 | 570 | Consider writing Classes or setting the `PSTypeName` on your outputs. 571 | 572 | - Parameters bind to properties by name _and type_ 573 | - Formatting is customized by type 574 | - Piping objects can communicate _a lot_ of data 575 | 576 | 577 | note: 578 | 579 | I want to leave you with some thoughts on custom objects. 580 | 581 | In PowerShell, everything is an object, and the [Type] of a object is fundamental to the formatting of objects on screen. I don't have time to get into the intricacies of format files and so on, but I'll make the time to say: 582 | 583 | When you're designing a set of commands that work together, you need to think beyond the function itself and think about your output objects as well. Consider what properties you need on the output, and which ones you really need to be visible by default. Consider what information you have available within each command that you might want to pass to other commands. 584 | 585 | -- 586 | 587 | 588 | 589 | ## What Type of Object? 590 | 591 | - Built-in, Dynamic, Custom 592 | - Write PowerShell Classes 593 | - Write PowerShell Enums 594 | - Constrain with `[PSTypeName(...)]` 595 | 596 | note: 597 | 598 | In PowerShell we deal in three general categories of objects: the built-in objects which are part of the .NET framework, such as the FileInfo, dynamic objects (i.e. "PSCustomObject") such as those created by PowerShell when you use `Select-Object`, and custom objects defined by the functions and 599 | 600 | However, there are lots of very good reasons that you should define your own object types. 601 | 602 | 1. When you want to customize formatting, your output will need a type name 603 | 2. When you need to pass a lot of data between commands, you'll want a name for a parameter type 604 | 3. When you want interactive objects, you'll want a custom type 605 | 606 | A lof of the time, you can get away with just specifying a custom `PSTypeName` -- it's enough to let you format and even contrain inputs. However, it doesn't help users who are trying to tab-complete properties of your output objects, nor is it easy for users to create the objects to pass them as input. 607 | 608 | Why do we care about types? 609 | 610 | Probably the best interaction between functions is to take the output of one command as input to another -- but the best user experience is not necessarily an `InputObject` parameter of the specific type, sometimes it's better to accept the properties of the object as parameters. For one thing, it means that a `PSObject` will give you enough structure for pipelining. For another, it allows users to just pass values for each parameter. one much easier for users who do _not_ have the object to call your function, while still preserving the ease of use 611 | 612 | -- 613 | 614 | 615 | 616 | ## Getting parameter values from the pipeline 617 | 618 | - ValueFromPipeline 619 | - Input from specific other commands 620 | - Easy custom objects 621 | - ValueFromPipelineByPropertyName 622 | - Properties from other commands 623 | - Speculatively allowed in-line 624 | 625 | note: 626 | 627 | Hopefully, you've already encountered the `[Parameter()]` attribute, and it's many switches. Two of them allow you to collect the value of the parameter from pipeline input: 628 | 629 | - ValueFromPipeline allows you to create an `$InputObject` sort of parameter to collect each object. It's a good fit for when you only want to accept the output from one of your other functions, or when your objects are easy to construct (e.g have default constructors so you can easily build them from hashtables). 630 | 631 | - ValueFromPipelineByPropertyName allows you to collect the value of a single property from each object. Of course, you can set up multiple parameters like this to collect multiple properties. This is a good fit when you don't have a specific object in mind, or when you only need the key identifier from it (e.g. `PSPath` for files). 632 | 633 | --- 634 | 635 | 636 | 637 | # Thank You 638 | Please use the event app to submit a session rating 639 | 640 |   641 | 642 | https://github.com/Jaykul/DevOps2019 643 | 644 | If you have good things to say, 645 | I'm Joel Bennett 646 | 647 | Otherwise, I'm Kirk Munro 😉 648 | 649 | 650 | 651 | 652 | -------------------------------------------------------------------------------- /export/images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/images/bg.png -------------------------------------------------------------------------------- /export/images/cc-by-nc-sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/images/cc-by-nc-sa.png -------------------------------------------------------------------------------- /export/images/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/images/header.png -------------------------------------------------------------------------------- /export/images/prompt-exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/images/prompt-exception.png -------------------------------------------------------------------------------- /export/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | title 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 37 | 38 | 112 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
124 | 125 | 126 |
127 | 128 |
134 |
135 |
136 | 137 | 138 |
139 | 140 | 141 | 142 | 144 | 382 | 383 | 384 | 385 | 386 | -------------------------------------------------------------------------------- /export/libs/highlight.js/9.12.0/darcula.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/highlight.js/9.12.0/darcula.css -------------------------------------------------------------------------------- /export/libs/highlight.js/9.12.0/darkula.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/highlight.js/9.12.0/darkula.css -------------------------------------------------------------------------------- /export/libs/highlight.js/9.12.0/highlight.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/highlight.js/9.12.0/highlight.js -------------------------------------------------------------------------------- /export/libs/highlight.js/9.12.0/reveal-code-focus-1.0.0-mod.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/highlight.js/9.12.0/reveal-code-focus-1.0.0-mod.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/css/print/paper.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/css/print/paper.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/css/reveal.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/css/reveal.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/css/theme/white.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/css/theme/white.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/js/reveal.orig.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/js/reveal.orig.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/lib/css/zenburn.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/lib/css/zenburn.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro-italic.woff -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro-regular.woff -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro-semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro-semibold.woff -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/lib/font/source-sans-pro/source-sans-pro.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/lib/js/head.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/lib/js/head.min.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/chalkboard/chalkboard.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/chalkboard/chalkboard.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/chalkboard/img/blackboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/chalkboard/img/blackboard.png -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/chalkboard/img/boardmarker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/chalkboard/img/boardmarker.png -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/chalkboard/img/chalk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/chalkboard/img/chalk.png -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/chalkboard/img/sponge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/chalkboard/img/sponge.png -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/chart/Chart.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/chart/Chart.min.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/chart/csv2chart.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/chart/csv2chart.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/embed-tweet/embed-tweet.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/embed-tweet/embed-tweet.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/markdown/markdown.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/markdown/markdown.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/markdown/marked.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/markdown/marked.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/math/MathJax.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/math/MathJax.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/math/config/TeX-AMS_HTML-full.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/math/config/TeX-AMS_HTML-full.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/math/jax/output/HTML-CSS/fonts/STIX/General/Italic/GreekItalic.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/math/jax/output/HTML-CSS/fonts/STIX/General/Italic/GreekItalic.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/math/jax/output/HTML-CSS/fonts/STIX/General/Italic/MathItalic.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/math/jax/output/HTML-CSS/fonts/STIX/General/Italic/MathItalic.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/math/jax/output/HTML-CSS/fonts/STIX/fontdata.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/math/jax/output/HTML-CSS/fonts/STIX/fontdata.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/math/math.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/math/math.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/menu/menu.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/menu/menu.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/menu/menu.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/menu/menu.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/notes/notes.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/notes/notes.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/search/search.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/search/search.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/title-footer/title-footer-mod.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/title-footer/title-footer-mod.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/title-footer/title-footer.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/title-footer/title-footer.css -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/title-footer/title-footer.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/title-footer/title-footer.js -------------------------------------------------------------------------------- /export/libs/reveal.js/3.7.0/plugin/zoom-js/zoom.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/3.7.0/plugin/zoom-js/zoom.js -------------------------------------------------------------------------------- /export/libs/reveal.js/font-awesome-4.7.0/css/font-awesome.min.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/export/libs/reveal.js/font-awesome-4.7.0/css/font-awesome.min.css -------------------------------------------------------------------------------- /export/libs/reveal.js/font-awesome-4.7.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- 1 | wOFF~� ��FFTM0k�G�GDEFL �OS/2l>`�2z@cmap�i� 2 | �:gasp��glyf _yL����Mheadb�36��-hheab�$ 3 | �hmtxb�� 4 | �Ey�locae� ��\maxpl� ,namemD�㗋�posto`�u�����=���O<0�1h�x�c`d``�b `b`d`d:$Y�< ��x�c`f�d��������b�����������ʢb�� l ��|6F�0#�F��nx�͒�J�q��gje��>�"�D���>�{�E�O >�����,"�u�^�[[[���j�os���_�M��%:0g80������B�.L�s�zðפ 1Y��lKWv�es�t��)Mk^�Zֵ֪�m���׉Θb�k̳�2����6���>'�Y�Җ����jukZۺ�g�m2� ����(�4�-iEk�Жv��}�X�B� �Y`���`����c��9�Z�JV��5�e�Y߆6�G ΂�`3�| 6�����[uI�p�n�-�����[pL��0�Lp�;��׸�%���8�o��>F8� ��G8�`�W�ί������"�E^�_�=(K,F�K�+�y�b�����x��� �TՕ0��o�}{�uuuwUWի�n�njmz-��nv�E�EAAJ!*�(��hD�2c�%F�ʦ�Ebb6���$&�����7�߹�UUW7 ���t�w���{�9���8�m�8b��I� ڃ�����݌7 �S�E�G�!�3�����j�㔐=w;�P�^I�A;RR�n��k��LS�.��)�o8G�([��)�9O,,�At�S� 5 | ��h 6 | y�u�jZupPGx�N �o��n��{��ho2�A�D�-r��]��u��5��e��^��dM�X�8=���r5ͻ^Q\�~��2��V�0 �o�0kC� qA跍 ����G<� 7 | �9���v�`�|N�X�W�I�:"�'�a��W޺O=}��k�#�"���7�e ��%Vs�~-�y$ŵ�������X��w&'q���.n.�E��K�#��JD�ڝn봽7�����=�|�w�L:Ӎ2vmrRv:=0P�@D�ۓ��V�Z7eO��d��7�HM�SY�|�[o����f'B��L}��Ʒҗ�V�����^�+�{W�=���uҤ֦='j��,�| ;�v�A���o=��0�q8"�I³��8���yZ�6Ǵo9��q< i3���k������1%�&�� ���u���k�� ���{H}��@΁W�—^q�Է��4;gg7����N�y��/�� q���P���OЌL�4��q�,���ԇ�"�Sv�=jL� /U�jC�-w�o���ȍn���j�̮�{�j\�� ��vE���k ���z�>p�n=�^=�ajID(����෠����qu��F;э�5֮�s7 ;QC7�U��[����׈����yZIۘ�ػ�*�!$ �dⵄ��Ŗ�-ˇ?��{��m�������f6��po��~�mԽw��o���G6M��oz�a�--�m#]?]?V��k�z��ܥܵ�.�>�)�9NH%�&T/� ��_���I�Ax����O��B��]8(���.v��)�G=���H�P�S�U��P���>f�F�E�-G�G�s|���'?~z�I*���R�|��[` ���-V�'ݙG�P3b�'\R���I̞#n�;W ��ٟD�T��ѹb8�0�^s6,rȥ�� i���������sm15kk��,}��q��Wȝ;�t�s��e�Yq�qC/���0�q��|>�� 8 | 3������W��/�ը��s�F�"���s��I�oAHI� 8��C��„�� �w���~�@ 9 | ����_�(�]h=�������r�9���p!� ;�H���-[If���w;%=�d��꯵���bmH)��k=o��\���h�E��i� 7i:-!mn:`[�G�]���GE,�;��s�yH6�2�ƈs�՗:��I��@�^\�w���OV�õ������<�g?]�Y{?qK�g�H�[��X��&�td�n�[�,��Z�!H�6#�=nݳ����;O��W�U����G4]]�6�ٰp��7��[�aM�5P�����B�]?����4������P呂������7o\�!׺ߜ����ؤ������ ��2>8�/p�2�h@�k~ھ���B~�a�[�r��=Pr8�S�e���sc�F� ӗ�� ��S�#P��|0z��'�z��S��)��8aFB�FE ��V�r�J��(E���fDp���U�\���'h4P�� �j��d3}Cv�f����M�}Zlf���,.��p��j1��t�Y�j��2�lƗ,U������<:�z��t[�%�Y!1v��M�frc:_n�"��7z�w��v��m� z�ui��dt���O��.3K��u�� =�.#Cjn(,THu��_Z��� 6�q�����hh�P�4#J�H�%jt�3�M�)�#��z���z���dt��1Dn~�9�/��ȋ������B��@NV?�p'r� �f:� ;�b�B�QHb�$h�3�CG|��#v2�y�d�m)�e���sv��w�~٬�fp�~��DG� �r� 0��^Xzˣ�����Շ��c���l& \�`\�8HHa�� IC?��������6���:5�H;�l��ވ�4C����&�\�F����jԬ,�|MC�ݔ��/f8��ܮ2��� �.��ҍl 12 | _/��A���kT�V�Νg �~T��΂<`2����Q�&;�X�A�W@��@g��j{��j,� �s�uuE ����֟���:�A�� 8,&���ռ }|��b0��lFQ$px=��4ddm7��nru"�N:O� u^��x@񝂍��C�G����*�%F�>Tm��?��2.�o��p������ˮ�1�r�\T��١K+L�؜c���n��:8����q�y�N��\Dv�j���[��ܦDy/�*=H �[0�l�8=���`�D��d&�<����qR���}~��|m?9[�Y {�H�I��FP��H�p;@���Y�����[D��]j��}�*ÞhJԆ�'v^��6XD��L���V��a@XF�k�<��������N����.�����pV�e�u����p����+O�;����FG�\E��нb�kfy 13 | z��s�� X����k��M֊P����Y�_g��#�f��}{���Lh.tMV((���/���4u�X�4u�<�k%�Ņ��s=x�f�Ȍ�ݐ��P��(�.(��q\��+����i}��J�/[��O��k�����76�t�O�d�٧�,崅v���2+�׷� TU[�NHN8�W|���fG{�ܘlT�_���Z1 ���8j �`A����r��㼌��` h �*�b��� ���#����ռ��B����j���0s$n�^�7��w �$�Gɡ;�N 14 | .�A>3;M��y��?��zpͥ�Ι��4�aqp҃GF��w�|]��֯��!��ؾ�bv�q8�e�+�)��h.,U~�4]�h.�P4s��)��+k���q�D2�u����ϸu��E3 V�⭯�ҟ�f�S��8��/D�]5���ޖ*xWG�j���}�l&k�lnçi��Pv'�6#�������(%��)>q��E��o6U+�6�ŋ�8ۢ��lޏ>��� `����M���n'���'��zB-t�/ꬱ����3ik�3 15 | ���55��Z 1ao�|+� őm�� 16 | ��0$Yə�Oa��1ag�9��up��9Gת+����b��=H߀��Q1h�T��]�Ғ�Q���^��?������s9��ػ��� ��l��B�|4�TN���YBL�,� g�#�5��A�㉐=!�7~=�/X]W��uw�ZW�����避[��Ꞟ�W�d==B��m®�ҏ΋v�?$���� 17 | E# 18 | �L�!7���ط��!����T��RR�I4��)���H#��l*�:#��H.���)����pӇ� źR�M�B���=�ƅ��(ǂ�͵���˥�>A��,�_��2�%�5�p�yn�6/���Mb�t,�L֮���l+�9�Q�Gb]*�D;� ����{PZ!�*��U1���|���s��{�"�3�\�g�������Gχy��G:�-nQg7��`ԏ3�x���Ax�%ÏU���XMZ�&HX9�>o��s�Ga�� 19 | ��'��!�lü��|�EW-��e�b���bxs��Y0��6E��>�)�V��H��� ߰}��V=��G~�Yk�h��/;��ۇ��0�{4.c��\h`�5��� 20 | F�A��5��Tg�[4��#����S�o3��yuy��=����<'j{� h�N�k�6�� �@1c/��5 -T:��`Y�X]��g~�����i��l�p�!��e>�1x06�?�e�oA�s�b���̪fy�b3�@B�߂�Yq�?;�m)�h4s�k�P� �����UfW��62��c�>8F�(�t*G�C ym 21 | s��r�p�?� �I��C�Y:ϻ&͜9��9T�Y�-k���%�)�@�|FF�h�9*��(Rt���K��ǻ�T��XM-IP.%�C"���?�,+ˆ�=�� ��>���t�������U�gQ���W��w#�Υ7 ݋���[��P� ���ޮ���'j7� �7̗�9Z���I �S����O4YkDE�͂�B~�`�Ig;�m������u�֢z�Sg)����r��E܉�=m�K��9�ZD�]�4����~7߉R6Hۂ(��j��i!�BldpӜ^���zz拾�g�F:�qꢝk�Wl�/С��uX2�r��TsB�נ��������ͫڂ�t�}}ƶ��_5� ��k�4��� �A;oH�L�Ϲ�)�z�.�qu���A�z��yx�j�k5�F�-��@�lҙ��c�ڗ�җ\6�=� ���O]9�/�5ڔ�볝�\tO���C�T3�f(i 22 | ]�w �P��iQ���w�γ�=J�ߌv�Gޮy���[�[���,��Et&Q��o�c�Â��yb66k���MK|�֋$Y��z%���P��(���^�87D�rK���`��%�5�.�:�� �Ďx=m��n�ً���m]�Ю�&�2G�(-@�Q7xu3%@�p���~н��t��� S�]���=�)AG�� ���A��Vg;�� *=�$mz �-|_E�Z�ˢk�<�5U5�fF�I�j�������`�=H}���)0��~�F�,"����N�6�k��"��}�Ṓk���T��"$��mZPc�',�ϛ�tz�����Յ��];+�j�� +�NG�>K#�h-zp�6\��;y��b�~�9�.m� �\�=�qrqü�=fS 23 | 6�u(����؍��3���#����0��� � 24 | :�Nz{S�M�]"��`R�� ����.C����r`-��U{낍�z�n�q�� t�x�� �ic+Ԛ:3Y��㳙N��*�a�V��P�� 25 | �`�1�Q�b���@fc^X�9�̼����ܶ�����jtҜY ӂ��hھ����3� i�js��+\�8Tv��i|�Q< v��߹c�8��1���-��t�������\1����6����G���I��n�J�:̇�h�X� �G��r�+���<��O�|a��l�yxuco����7狿P�'�j{���G��w��s��ʥ���s����� ?��?kL5>4��Hj��v4���l���!���,��c�C�5�4{�ٱ�4d��R��~��p�*;9n����C%d��}�d�A 4Q8�i��O�i ���T����gd��ul�U�S���A�q�$.j6U;�MǶ�ۏێ�ۏ���j�9J�D�vAF��b�m�LOI=`�j�f:��>Iǁ�J!� 26 | �6T�xư�qn���̓��S9�ĀM|��!ґ8X)��h�ͅ��ͳ�(����,�ӌ���2����+l�D���3Qɕp�$`�Pt�[���� ���DV��2�op��o%x�Z)�����n�:p4�N)�F Նt�T7M�u`8��P*r >�(��O^�����tX�i(��M4! t(�>h��cU��<�@��ܦç��$�M'���(��J�׳��Q�܃���<8�Vj��j7P�?Ͼ;��������_��!Q����.h|:B��)Ӓ��xܘs��_���d9���aN=�.WO.�\|�_O&t�k.�".D�p53�͓ 6�`8����I�u�������Kj��k/�����wi�U��S��us��U�lr 27 | ̥;��ѠMe`�T���B�&��n¦\� g2pd���[0��O�v�z��� �I�'m%�4���1}�@�€:įZ���/r @1m8_.���W�R���lv(F5A�ս���~]*@Qؿ 28 | V�����g��M܊�����:M��ʞQZ�㖵��. 29 | H��f��J�wK�IA��\������f7�z���l��}5�V��z����G�� ��Ɛ� 30 | u̻vߋ�a��ɰ��Z(�S6W �z���7e��k���[j������ #6[���6i����Sڣn��@�d��`�[��}�i�]<{b�N&k��G�[�Q������`E���������k��$|'������GO���R��4: y��X��1d��hz3T�ʷL-�3��D�G%�Z 31 | ��b锥�3�I��陌R�^cy,�3��P!�@�ieNq좀FS'}@4�шÏ~�����*�T(��P���Y+�=�!?�}>�Ю�+�������w*�3��U�����sƽ ��i[�9�a���\��u�We�Y5��� ���+����,��iK�\��ʚe�<�����z��K�C�&�Hd�bktݩ7<��Gh��� 32 | �f�O���fp�+d<�8�Y���X��(�ϴ�s�>!;B�TR@J vK��U�8�bU�H^Q;O�k�b%�[Q�H���O� 9谉����0r�0��}����U��>�ʔV5^����ܵ�����}ecF���mۈr����qLEl�� "�I5��ڦ�fU���2c��W+�O, ���MJ񝁧6���y�?*�0&N�ݚ�xq?�)��>�e�(� @��qT�Vx��>sjA�i�2W@�W���U����{L�Г�K^ A'�96&�E[ h8�����J*�X�>�w��yW���+��V���c�*���Y���P����!���3� ��^�� ����%�"��`�ɒ�R������cD@�2�ܵG��5g��L6}*X�l틵�\�"������*�����p9������B4M�z�A����65L��.���2�k,0���^��>�G@���@H�ty��� �Z4iepWt���A�h,8�<{9Ƚ��ǷƶwZ��OY�E�< ���Z�)��t#�/�崐�\F7ʔ�B>(���&��6�ld�i���t��/���=�n�>?&s��]@Ν�0Z.3Ĥ�9M�G�6�XI�J�H�Xa�:��C�}��3�� ��6��~>�D���3��U�O>[vZ_�}ס�qN!ʃ� 36 | ��-�W�� ������� 37 | S� ��Ha)Y���'l�g8=�`z��(bwv�����i:2E�!��`�;x��,����Y ������ߩ���� 38 | =��Іj^ǻ��Q�^���_�Yy`���Q����[&aY��Q u�s0{&m胑*�����j)���T�C��$ YQ�>*�P����}H��������˥��_�7��!n?Vا(s����O�GRB�X���bG/*󨴉b����E��(��"�lrʔ$Ϋ����dJ�wGp6��� 39 | P�/�#j� �mtC�R0�}B�j̣R��X�v��I�>(�j=���:E�C�t�V�:O[h[5�"u�E�3W��. f�[eܫ8�P)�e 40 | �0Rԁ��d.ُ:~}����t<)��/Q c��O�B��GGp�<��"-G�-b΢�y3�b�#����5�RPCk{d˚� ح6�d��]���������L�d�Lu鋶 ��LCz�Ӯ��IYs��;�A��@*n�yڢ�����Kˏɩ���E����W����eM����â��x�[�*u ����-z��җ�rizH>���� ���2$�� ���=�_������j7�{�!�h7Ύ�|p�fs%9LA�Q,��2��WH�(EEug��&�/� 41 | $̃cm$0^(K_� C]D�����i����+�/�TR�hOJ?��N���ޛ j�;� 쁳�#��ISm0Q�4W�����Տ��5_��fd�� �"0�ԏ� ��~D}��R'��k ��GK1(���_/�T��F�Ȥ8��>��Q8����m�.m���s��t�Á��-��`wZ�a���x���x�";ͯ��2�o2�:�h*4X���-hW�3sn���P,ɞ 42 | ��"ޗ`7�Nw8ɐ�D\��� �(,f鄝� ��I�M�|؟��ն���k��ÿl�5�n�v �xL/L��M}��ݻ/�Е�um�.�u��m�d>�Nh���&k�Ե-h���#� +���q����s�}v.��L��8�c|�P=/2�,��T�,��\f��x���P!:*���}��uL�v�yj{C� �[�� ���^�܋�����lV��͛C���Z��k������9�~�_��+�2_�ʗ�����7��%�\~�N�V�w�|�:$^�fH����-œl6��[D���n��i�D���>�=�}4b��=�U{��x�C��u���:����6ݨ�18��=�Z��%�ܓ��&��?i*�V�߻"��z��,K���=�,�5keb �PÒ��}aM)d��Ő".Aǝ�2�An�K% 43 | ���%7;� �QΤx9: �J'���s�������9��:�(��w��̿s��lt�W������N�~�+lA�ڏ��m[w�7���7n\������W<9���-N�߹t���i�?��"�;�i�w�[��;L�vP�2�z����r�g�k�cl;#��E�*��b���8�*�<~h!������:�Q�@�qӼek�/��#�@w��ꪫ'��� ���r���*2_�2mp�pm��"Oގ�:�wFgR��ۜ����������{z�h?U_3��������m3�ؾ)��[�_�.��/��d�� j�����G�̨�.��+{����7g�|�6w6؟>d��5��;{O"�-��<���+�jaW2�2�����p�����W�a��g��y6&�Bh��I2%��1���S������*�[Ϥ��F��۷�%nwT�� Q��Ķ!=����00!�dP��$O����j!%��l�6bd������[6�,6��`^H���fɖ3V ߶[��8|\��M��Q 44 | ���lƜYxj�?KO�3��ٲ�%)�����)JrGƼQ��̼)���2c�"����^�–�;��@Y5��u�!���'�h��VGTi M9��#�(ן<�4�s�{��������@�e�fQ`�Gy� �8�L��"KB3�+��fOx����_�c`= C@�d�-T�Oj�+�Jw�]��f1���򉠦J��� ��-�L��[,�Əv�u�&}��z�)Aԫyz�X߶"��M�Ww�P-蒺Mr�k���� 4�4L�ZvɎiZcK���U/N��j�a,�a���� !"Y<��]�K�����-��������{S� �&�,�-��� l�5�V�(��DSJZ�������U����+�6��U�Ԥ)�j�ȀMXju5xk�O�x�kC��f���>���v;o�Ău)O[���H����%��rJ���r�ZN���C�Q�n�?|��x�����_B��*k��gY�n��3:B��4Wͤu�Q��������.�R�M�F�2���>��8�G�3J<ZŠ�r���Vŗ�Y�~P�9��w�;�< +�iչ+�5�D��D�hp,;ʹ�j���fƼ=䵫9�� �3��Ƒ,�@�('h:���Ƌ&m��TkP�q�8�󨴱�!�ä.���#��Q�{�=����= 4��V���#��m���x �_�)If�C�#y��F��N������� u����Q�R��PQ��y��Q �u���:�]�g�*O<�j,0?��g`O�N\Z��\�F�k�rIݝJ%QM $%G�/-�S_hz��t�>U����֧�c���'��P���fՅԭ���ں�o�>x�,u������P^��"���������yXdc�i+�Y�_'�z�����6~(+q$��U�;{S<�^x�Gn}���ou�vXt%�&3`�.:gA����'�%���O���0j�@E�w���:���м�jd���q�g��e�������4c�&ū��Y3�]��*��tI�*� 45 | r6% ���&A�R�^3��$�p��,a2GÇ�}O>W4�7�6Ո�n7[�Y���Nq����O�e�cu/=�cm:&�4���C�o��<���}��i�A�O6�ă�N�Y�����m�:�̲f3�J�"M��K:�Ek���:e-O��7� � 6��;k��h}x�?�1�/\���g^��y}7�|�4����q���'�7o^�� o.�Uξ&�d�5���v��� ����3�_P� Mp���Ĺ�V�jl�U� � �a^vqǹ�܈\��?虽쪰��:���Oo���b2AL2���9�zXv��Q� VUq��^�k%@�����$Ǡ��#�o}��Ts�cFW}�$y��F�����$y^2:�����l4�/�m�a���Խ�&�o�L�3Ѥ�N��Iq�!�#��ĺ~������N>�0=��ٞ���bD�A�w� ���O��h�� C���Tѡ�� �����֩F�I��.��M[�V�#�Œ�3�z�e�{��EvceR]� � 46 | �ecsER����n��`{ah��Z]���'3W�0v��Ix�V[mQ�8��f6�4�Sc%�Wr��F.aR�6�a��Lv0�n���=,L ��Z�BU\���]�a�JX��L���7�e銛 ljQƀ�c��H�j\���}MG����ޛ �[X@"�W�dNS<���+�������#(���;<�"w�~o�myL�'�D���pEb�Y?�~�{{�����,o,�RD��(J�bC�>�ܶ�_�dՇw���f�f�s�ܦk3�ގ&��~�L �=�$&����Cyd�"�le��؄� ��tQRʉ�@*����΋����7����JՄpC��#5-�V�g�o� �!G�i 4�&��N�pO���o޴խ��9�k�'y=JS4���/�;�٬�����v�Y���3M�iB<� 47 | ���(Yuv<�9_�m��@|zU�� 48 | _<'�;��^;��#�b})�K�yw���n����o�%���6��,i7�-+v�(�k6i�c"Ym���=t#WRT�����m���R[����na��<���j 49 | X�)G�VX�,��gB���&blц��*�ϸ"^ (���^�Bk(tǒD�>f�ʭk��l�W�޼����(�I��d�r�U��U5=^�Df�j}-���:�$r�p(� �%\�x�+>w�W�؄ O��u��� gq�/�,��W:˺/Ɏ��+ �����y+�&��Lo)� ���@�[�@e�x���b�i���u;���:��Ykw�[50��x:��r���s�S&_Xx��f[b�T���:7ak�}���Yx���<5����r'���(>q�-��p�r�����o��ɴ2��H��U&�I-K������m�h�ɠ\���YF���Y`��|fM0]63���B�w5�%#�'iH(�8�[*�k�.�Etc&a���Nm�V�JQ�K�T�M��b�X4��?��#4c�왓Q�,<��v�5���?J�� [��J�s'�ڛ�iӒ��Ӈ�C�>�䶵���h��Mz__�m2�7��b�2�HC'� �� j 50 | ,J�N؋���� ��Luq�M�Z�W7��'./�^L^�DL���%S� ������n��4:O�W���^��o�f߷Rпl�q�{��\�PȖ叙y4*x�Ba�v���� k��x@͗qY’.3�HQ�F����|�:r�Ɣ���9`P_�SRL��� 51 | 6b�|jAn~<D��N��"�u���0��Q����\�� W��u�ާ��fn6�oH�玤�N N'�S;���)̓vG�vejO��XJUP��s�p������s<���׷4�����}��a��m}S�j�T���Y�Cheubm���20���~�t��'r3��:_H7��M�笜�Y���rN:1��!-��z��\�M�a��P}���l��&pq�6�*_U�Y�IG�~O����_KU8��FT{��t��( ���av"CBf���_F��;Q��n�qӳ�B$MU*r��g,�^��GD�,I�H:7FD� �Jl���k6��c'�]�u��;��&�� Fb���F��iB�"�&͙Myk�U�����P�\�M���]J��~q��Z JP�$5K���?��1/,# K:I�)�D�o�Y��:Mg�!'�S��$���M� }��Ê�N��~�$��Ū��3�w��m6�]r׊s���O^� 52 | ���ll 6�H�{R�vB����o���Lg(�i��Z�hVd��˂��]�w!��r�<3��H�/����7Cy�Y�N9���Y����@��Lc���eY�֖�Y� ��$�rz�2�d��k`����8v1�gI1�"0��k�~��,��c�$�� ��ty��h2� ^/�sv���骩m{� �T�����UM~{�W������Ï���ɿm���k�U�ٹ������?���΅s�4a��:���Z�D�g�;�@�V�ם�4�����`�gلw]x�/���g�o��L���v�w�'v��ڟ��ڔ��y���K<+�Ǟ�����~NF�=ΐ7�.'�h��ٖ�}�t�)v�SK4�Yԉ����s]kW��N��-Я��K�`~k��R�-^���"9BF%`%5��S'$���^\o��;��NKM#_5y��r��֖ �j����K�g�M�dn7Y n� Nl��ݮ��m�G��Y��N�̂0�9E&W�K��b�K�|�ĸ������JﱵWr{�ݷ���kQ�cZ\2�R��؛�O����ۡ��_��h]��Ը��y��&܈V��;~���M��/�׭�n�߮>�_����[.��/m�2�������A �q�J���{ �>��L�� �M���8�A��f��]��'�v�HTUO��μ�Ń���̚u\�eA���b�~�u��:�y���nw��������ݥIٸ��$j[Q�����V*b� 聇nE�C�*�ZɭE�o?҃�&k=�t��#��=�K��T�rf�W�Q�jJN^yٔ������Q�W/����O��o�^�rr��j��;�N�M4I���`0wϚ�� _���ߜ�� ��!Io���uz�#�3�tz�i 54 | ��k�j��m��f�L�'��k� 55 | ^9�u�Dћ������Vn�Ǽ^����߲r���n_����CSC ���"�6�Gi1#�W���0=p�'��]�@8z}�Q/ 56 | F�"�̒� �&=�lF�w�d�F3v1��F�uDFY�V�'F���`.bN��u�䡁�� V�l�|I׀��ɷ�*�~���)���Z�*�!+��u��Qv���C�M/��vԂ.q��c���Ys��, ������wD������iN6� Y���r�L����U߲�[cr�c�q5)V��!�c0�31;��B0ތeG͝Ua�V��NU�e� �(��;�;��|d���;��_T��A"�?/}�M�i ���;]��w�t7W�Y㰛�n�����Ng��h7���E��B���7_R�E=S�x�V�5P �s���m�`��ržYa����������z�Ra�t�� �k�����_�F��=�� �dVٿgC��j��߇%��T��}�[��n.�Z$��Uq�:�ۛ*<gg�n�Gh� (U?.b�=Ђ��� z��3ek� 57 | 4�� v^�QVJR�T����+N�1�E�y� ��D���;Y�C�+��dN�A݇n$9��M���Ay��hpJ����=^�蹭�%[ҫ{���\r8L^Rڠ����g8�ޥ~�a�d8U=�gP��'�1�.#l� 58 | ��=ΑѬzR6��np�~[�E��fn��G�+y��|:���f���E˻�~E׶�M�ʟ�]�����f�}jE�3�qMOϚ���{��d?]u���U?���#�/;��s�~����򹃫ؚǀK��-�6�B��'闘̵�L��gc��g&�=��G����'� ���}�S�唩���VC�I�s�y������RCM�)�r�d��7&UC͝w�4�N�sc�a7�fl���]t��Tw�ݵFè4�o��u��֍�2�B�>#o7(���J~j�E(�EM���-P<��n}�en�pt^��� �^<���5�fͬ�>3����/rQQ@��Wヌ�����(�Q��Um��)!s���G��7����ꜜZ�4��� ��…U� �l���ڟ��p�d��:�Cc�e���'s2�E���;�u�*�'����$�]"��� c4��}� v�zyDz�ɨ�n4��bTF�.b4R#�P*��~6��t�jt���ŋd�ۥ�y1 W!�ןD}g��lْW_A�4R�/�u|��]���P �Ǯ~��:t���[�����94{-�.�ǀ���y�A��0�� �x��6-NMv�M$�c50g���hQ6����1���B��n����W_u�s��;B��E���g��}\���"\�a���Q=�#���ͧ���վv�����1�ŊS�Y(R.i�[��9� ��Jd��QӜ< 0@B�Nya�)�j0Vh�2쬄�s��O�eP5>I��~���1!����-�A8ag�j�Nq^7�6��e��/�쾇ݳRuԢ�Z&�U�EJ��l�p�Yo�<2�"_���:��97�9f���阎���.�! hI��4 Rk��Cj�G�Bu +b���tQ�P�u�/ А1��TZ5�����V:+�zp��8��j����y\ST��!�zr����u8Y۸$��Յ�F�uFY�� �Tj 59 | +[k�j`�GŦ��+�yl�֦Y닍�4R����,�+��h"�)=��U�>���yV�˕!��V]�Z�8G_ 60 | jW ��p��H�� ֬Q6P��8=w�Q9�]W���80��9���{��z$�5��p�+��҃D%ꔒ�-���R`5CbJi��h�EI@����x�Q@��-�J����h�n��א!7���#ם��Y 61 | ѣX�����2��M��n��Ɣ���i&�#i�x2n�B��~��#��}2n)Ͱ�.w��o��B��(�� Y�k�"��5n��G PTF����;�N�Q@�(�奣$���%l7Q?��lR��P�fB!w�ҤJƝa�îG�ٍ�J� �vK�g�WOӬ��L_�$��t���a��[!i&�M�>J�LBf�R����%� ۣ6!�o� ���"$�,J�{�l2"Qo����#BQ'!"#�� ��H�:�. o ��<�9*a$ 62 | <1ʔ/- 63 | ᪠(J&���$� 64 | f^o� ћ�}��6�,����+�7��� 72 | �g��2�.��;����H\Ұf��,-Jǒ��Ew\��B�wjǎ>�fM�.��.kl�Dj�.Xv�}����mW\:5֔j����K�ضV�3�B������S��$l��&�ijD�YdIO�~q��!�rW��)\�3� H��.iT2�R 73 | ˔D��'�i���>-�(*�Q�����o�c��$`������g�#A��ꆘ���0������ߨn������7.>�x��;w,yc�?�Ơ��3����6I6��1��q��� ���($��������,��Njwܴt�r(y��h�2�l{s\p�@ 5�H?��]�J�Hʽ����g�Ihh�h�{�� ���e��f�� 74 | �zUs|�+�D�W��xst���� -�}�"��<;�p> �#��?���X;$}�u�pȖ�ow/�&�ν'�dޒ���M-�3�g�֛떤������$y���I��E�uR� 75 | ;�5�It��Б��f<�n ;u->b��{g���-:��6ާ���>�k�0ڹQ��s.A�,1��xB��U\�tBBA= 76 | ��)~�3�.{��ҍPa�~�OBP��:s��QS�=��:Uf�s1�K�ɗM 77 | �@����P����s�y���gQ'�)�_�@\l`�|N�1�6f�p�p3��,Y��,w�Z�1��~ט���On���oy�'�Ǘ�lfC���W�?�Ot=��Kz 78 | ����(U�QC��dP��n��.<����=y�]��S�����d�2�K�Zu���{�d���^�&P�^ q��h��E�AakF��Q���7>�<�~̈^�=Qby��A�s�X� Gr9�A���ժ���`� ���� Ε�Mʆ�돱��,� ���,)���4K���ݑ�Y���Z���?0J�d\;|�����h��~��ki��?�e��v��宰������K��v��2�)i�9J��cj��~�Uivo�� V޴�ʍX�~�eC�k�ˆ���Ɔ�K�ڰZ�n�߹ZX���ko�n�퀭���:�h7Τ�����G�+Ș��}I��]Sfn"u�!�`*��ئ(E3 ��M ��N�4���j�nRX�M��Gs/Mtb������RS���{i��+�-��v ���a�J���u�3�Z/�WS9ZK��]>�Ɵյ�68N^~�i�>v$�$�&x���;�ό/n�Tu������� �_�p��d���R7���#ƌ��]��Kqk�^:J�1�)Ǥ5���$�2 ;�ʗ$X��[���Z(ޜ�h�J���7*�%2E叙#����z�g��{��hLK,����M��������#�ǤOkdւ� n�n���V����Z��Ħ��پ�[���ȷ����kV���%��ʂ�:�@S>Զ��}��S���~�.��vm[k������l&�ż��V�L��s��H���uvM[2���/z9ն���.�S<#y\�6 n�G����fmȬ@���xʃEӻe���iwX��D��v [#:b��L�_�hkm[-�Nٌ�E��Z~�emM����%Y��뛮��%���Zbt�h%:����9}6xn���.��^%,uXF>�.1^�x��o���U��Q��O7��������}����\�1�B�,53V̒ׄ���'Ō�z�w6�7Oi�6���o_���rU�����qp��,�1���qOi#*�n�;6�������F(�Ny�'�+ܣcT��q�������3��3�3���~x�h�4[� �A�=,O�c⋢�rx{�+=�.z���f�G�A=��SM�ϒk߉�kѥ1|���u�g��\==j��=$��rR3�,� �xٰ�U`B�!��"LQ�� �Jc@(��{˯��F�/�����4��3�i��bM6A� >A� �0Z���������(� ��zc��d�I Q&������Z+8L�T�W���&�� ��a�Q<a���"��*F�S)1�^T�}uМ�5`��-q'6nh���־� ڻ�O׬��%��3<h��%r���ܿ�e�� :b�� 79 | VY��� z�l�N�]6���p��/oyiOc������5x����r�M��{�>_�ؾ��v���5������>9�X�ru�ʓ�3�r0�rd����e���t�|��¶����L��d_���*�5�hct,g�}���W��i��\�<�c�s���p=�i�v6��l��۽�N��8��E�߹�����ٿ}aq̈́�s���+Wߚ D�ٶ�D^�؉>[DP�jq\j3t��h �d[�)��7r���h����UW]�jiK�97� ��� 80 | X|�����/����>g],p�K�4�Y�W_�ځ��/&����-�.S���0�����+���0:���A��H4bc�����7o��|~۶��F�y�W��ub����^yV{1���� ��o�8������S8#(�緥~���w�޹�jҢ����6��ĉ�"�h0P�T� u)�� �$���`]+�E:�E��q؎�W7jD����-7�(3�uŲ{�Q�l`Y���$����OC�oɊ���= ��;h�>���E3g^tP��e����N���B*���ʘ��!x� %� �֙�Y}IK %�ep��H� �ZR� ́�H�+!)�ʵ * 1B�1ˬ�B`�>� &�)ç�� &�� 81 | ���)��,~�)|H}��ؚ"����od�A��[�aO:)�禓�G����wLr��(y����ļ��C��g�Q���#[U�N��84��~��c�!yz��ݰ��ҔZ�3�;z�ss��.�F������M�ؾ�1 F�SI`A ��4Q�ByE軼a��"�Oi���P��S�b�nByḰ��XK���G�����`SVЍC/|WM�߫ʪkj��v�! �:�|uQ�(�U�Ϝe׷��]N��#h<;������v�U{�}���f��j�H�%X&? V�u�����~���V~j����6���A'��MY�v�M��!�GP۹re紳�� ����D��k�����/�s�)�k�q8vI8���#x� ������G,�c�?��;_�?��!��sy�ٯ3��ηw�>w`�����||�������t����u�P~I�������hh�nE/��&�j��y+���ٸ�uT��S6�o�o�O�oh-N�p8ޗU��2$�u�]������v$0$�� c�� �߂��S��T�6��h�Bڭw�.ci��[�����ҙ-: g��������*�K���h�q��{F�A�� 82 | �lW���?}�'�M��R~<3.(�[v<�QHPC����c 83 | }I�br`\~`8��{�;N\�w��Yu��I-��U'N��y]��9 84 | ��Kp;�+��I^����^�V۳dv�9!Ns�߁��_倻l�1p�~ �G��� p�F#�:��:ԅ�[���� H��˯������쀿�":s�-@w��;1n��3�+��� U�&����97��ϳJ�:���W�����ja�3�,���)���a>�� ��'Tgx4J�A�]ԧ?21:��yA�c4�Qd�8�`��b���4�D�lu�*�l��.]�&'� ��N�Y �?�_EJ�OG�#�y�n� ^���TA��/UB 85 | {d��Ȏ��U�}xX�1r_i}~8b*��=�^]W*s->��K��d��fgQ�U�(����s,�Ze��M\������]2�)�1 86 | ��$l!?OnG'o~��P]h�꙾V�'���E���6Fo���/�q��+Z����j z�*�S`�O�Ɓ�| M�U�a�����{o���0�3g��}�(骪�5�J8��+�5O�OWU�$# ��+�����Z �J,�2Y��i�n���>Ŗ��X���p� 'E!��4�l񺻜��i�� S�(�߁T��R_ʠ�̈́�$^����ŊM����O�wޯ,�cӊф惞�\I�`�T)���&IX��3��W�� 87 | Sv$F�ݸ{�e�1�fH�ț��aw�(Q �\�9u�\����O�x���7N�Ѝ�%��hۑ\W���TT۪��˻�Um�ʂ�j���r�����S�-���kU-����n�E�*+g]4u�,}���뮻mf��msM����X���9�U�uu�UNGQ>+���U���UG7O���(��Y�A!��9ې�#I�%�y���\��gf<�/ ��Z-H��L�HP&O���E��Z�:�3.&0B�}�H������`n�(�.�Y�2�,L�~�]��Da��x�Q�`2�:��6_u>�6��)+���{?�D�C�<���Uk��mb���~�c|T��`�ᾮ����&�� 88 | >E�7�"B����1�����;��/����� ʤ�A�$v�Bf�������Ytج�G_))P@ p�7�:�z3hfa2 ������:v(�^&��m胍���ɛ�7Mi(�&�+�;���v�v���&����1��S��� {��\ر���%���W��[�7m�nYm}������5q�oqQ��ˊc���^��nBq]�dZ������CG6�\i�9I/�����`��b��}��ޥ7���5!���pa�r�H�ٰ�) 89 | |���\����n���@s�؇Ӂf��s�޿j��Z�V��+m��#~xd��� ���Iq�|Y�;$����`k�G^i[ي�F��T�X� *�Ql�N��+����xD��Ց���� ��-M��L���[J�� ��ϧ����},��i.F,2"B��G�щ�����0���~�Ie�O���Ö��[咛���o���}�T�a>��ľ��/����o���z>�E}ʋ� `v�z%5Q��l��ҥH��+�+��l6g���S�Ô|�B��h�8��ڱ�t}C_Ꮐ֣*�=��d�[™��M{�W�J���fw.a4��4���D� o��*��V��VA�8�sP-��Ҟ�}��A���"� �@�"Ȥ�����t0���+|�|E�4N� �Ł�ݓ1 �9��)*���Y��Ѷ����QoP��@� �J�2��::b��?2�H���ϴ����3�Y_�n�x[��b¼�Y1-��M�ҧ���i��.�#?<���e����n��g���_�+�w,��1���?�Q�`����tt@��܁� 90 | �w|3OQ�������ozi�/#��� �@ :�ۨDl���#����w��w 91 | k�h�i��Sy�I����M�@�$��I��g�QC�3I/���Iү�RО��c����}>�\!��Б��c�k3Fʷ�׌8'�חe�d($lٷYS �hC�:Sl��i�,�ɯ�䝂�F�i���$��柌��t���n�_=���Pp��T �;�(�3V�{I�D{��iEZL�I ��sҢ�c����"3�[*8#��^NG#�c�`4�cCf4q���&������E�:��r�@B��$��=��D���M�RI��'���04 �'yP^�?R���xS^�3�Ԡ���j�"�����!���p��sm�h��g8������G41$�G>Lx���Ny8���.'R�ԇG@"�L��C�8S1�I�.u�ߣB�G�?>����� sj��6�خ0FƆ�{��1�7qD����X�SJ�Rʳ�R%F�L!sM(�~l^0���������a�v$.��X�V]�Υ��t:�J��t����1�"GЏ�e��C7�aR.#*�f�E�|[r���X�\�p����M�[�\c�3�����`�Z�*�؇q�fPW3f���!�u������6������1SJ���rm�o��XQ�N[�1�c�_.ʁ 6�a<������K�#�QGRs�7�gc7�P߀s���ޝ�to��s02z�r��� ���{V�{n͕�{6>]y��T�Њ�X����(�|�'��׵�h����%"� ���׫��{�i���`./Md�!����]Ђ�[�x ��C9w�<�X�c�pKC�a��bP�#lm�Пur�8�/���^�W`���Mfs�� (=TA��{r ���\�X݃f��?8��:4�g������d��<�Pm#�4V o-Y@PV��p �׆9�1JȺ�C�F?��!i�&0���I��SH��H�o 92 | 7A?�U'S��C]� 93 | 7�4���O��z�C$���=*E�L��@1NfY�oȒ�:4�����#�}n,�uN���\}Za�gi���~��@S���d�&l�'�Y��p}�@�&:y�0�o�)�@���}H�U��q����Ss��G��|����@S� 94 | ��$q�Os�I�#K H�OsY�d�Y/�R�����&5�@�ѩ�F f� ���k.�`����G뺦��Ÿ~%�0iB�7}�y�����1_��w�lᆬ��q�_�M���R�uŐ���p�t�����{��JH��E�2#�f�,��t��D%Q}�:�0�Z`�1�� 95 | b�������W6K�+���b�d� f��e�+7�r�JLZ+S�!�}w��P�3�wi-V�6�u���o�+6��]� �`W��d�d)���P��L �#,{yi��*�+��ӕђ����� g,cʺ9^V'��0Y�2����[��g�?��)M�������~0�9?8�21�����^:3y��+�|�W�#�ܻ���oط�� ���{^GǼ�?]��M��=p��K�W 96 | B��K�捋fljh9i\�� ����ȜE��Κ�Ι�v����ÿ+~ 긇���}�$���9�3&�E�4ɹDR�u$���c���<�a!�;���Ă��Ȃ!ŕ�1/嗋X�v��`�t�K��e�K @H���2؅�Ѐ�8�6T��jLeˍ4�T�,� . ��7:́�b���x�*GASt�=����I��,���"���G^H�Pu�e��PCn��A� �G���W�fD#��OR~^�e����*��\�����NY���LW|i��=��<��ѵh �ώ~<�h�� o��Btt��U��]Ns5x�O��|�2�lm�6h��ݎ]7;��S����.���i����ZU��\W9�?�[��ڜ���Uj��u���rl���!�.���� ��D߄I����D1 97 | �'�G�W�<�Qf���BŒ��*1S8�)�Z:! 98 | )QH 99 | ��I„Zu#��v����Ro�o������ 5��\G��zx��dT�f17e�E�X����\9�ZAm�vP����{�Lj� ��t8/����Ҩ���9��ӥ���%���}����� �{��_�<`F��=�2!���1��������ʔ��ۢ�n�|�����o v&F��H�/�~�_�:$���n��Q���$�ǟ%�~��:���٩2j��2�A����l0�l�Z3�q�єɢGĉ�k&b ����i[���cu<~��x�����sE��U@}�Mt��nZ4�01yS�Z��&�l�^}o�_l 100 | Ev�k�����`�oM���M��`�7-�����҈����lXd�m��)\Ԩ�HA�q�j+o �ƥM�,Zq�O��,��eT-5�ڂ�C���$���(*��9l�R�:��j���j:��+�=����ҟ��F���k�*WE���pIk�� Y�j.8���J� ���� 101 | :S�5��G^М��F���m���.䜼����CcT��@��%���������kKH.!�% 102 | ���ud�)�kAA�T��1��x�7�*�\�y��p�����g�� *����5�U�ftL���1���ń��Zm��I���j42`���W�Y��c�D1��_��-����D�w���|㟥lS�2�4�B���a" 103 | �OR��z#2���(Klq�h\X�*I��_-�4V�.��7&޹kxp�����1��*{cG�I� 0��ݻ� �q���M�e�O>Y��c�� 104 | O�����*Eu�DmO[,��� �f<�a�#$�K�0w �>�s� �6�W� X�����6��� ��b%���֢Bۇ�ߕ"l?Y�k�Z��&��|�l� ��!��\I�8����� �|��`�&��1����1�P�/� �IK)����){@'ZY�hv�&��g� 105 | @6`� wE�&yI���IJ9D�I=A���b̚�|�/����H����u<��R 禓���̘*���Y.��F�E���vP�ߡ��<�ݓg��Z�E��=tL�T�"&ǣ2=��"��ǾG 106 | GL `D݋g�9��X�F��Me������ 107 | 8�~ErnE�F�*�Mlu|BWY�Bv���i��J~{��^*/m��*X\�wt��˥e���R,k��T��$�ӈ�� �t�R��6j����<ڭ�'������E6���ZhP���q;��q>D���@&� ��찇��NQz�^�~y� 108 | ��@^,, �Q�� `q�q__X(.l�{^��/�/T8 �c�#*b�i����&�O���a�S� �l"y�$�&̲D�s7P�u�� =j\.Qܑ?�҆���|r���z�4�ʻ�}��ǃ�� �u�fůs���fB�Q���B���Ev^M9�4�$?��8<�"<.��L��3�j��L(L5��FV��w߽wpf.p©��M�n�c^��8(Uν>�n�.K�e���y�@��{SF׆�{�`�|� ��73���7K��ݒ�pȕHd��Q"�p�(@dY� �T c�T�YK KJ�+�V�O�wd�C$Zѧ�tH��ο����n� ���w��? �&i��G,��� 蛙��������|шD�>y��A�-@K��#��L����җ|sĩ�i@3@g�M��/<�X��6t��\��_���e���y�̺�q�*�������+j�/������2������+&�Z=�9s��{�] F�l���Ǝp7�@��Ŭ�7G��/Ð"�^9M��4%?�}e� %C�i*�fFi�i�&8{L�?�p���G[m�����Xګ`d�l�'k��&���cb5n�����cd`A0g� -������X 109 | R��Y�<� �z�ŽU-���̞w�'� 110 | v�8� j�BX���V�����>�ג�k5`Y� TT�j���,O�Ƨ. 111 | �f�ء�6;*;��Z�dNywM���"�� �0ԈKՒ4D=#���eL�p�E��H�6_�-�8��(�u��wʫ���%S���$���#0��z�ޓ���d%NQ��o�c�[:��@~ƹOq���S>P� ���䬕�}Ǐ��{�"�f+�wm�3;�a�8Z�x���� 112 | 9�a>��n ��� f�|��}�X����ϓѸ?G�c�"[yg������g�Y�Q�@z䛒��K=�"�aU5v�:t� �o�p ���I+���'��� /N����AO٠#HzK/� �]^z� 1Q�8��0�)�]��h"� ��+�_Ta�U8�i�cm<����ǥe�}�d���@ų���Ac`h9�NQ�S&�ݫ�M���XK���X�~������� �JЃ͠�X���)��=Pԯu<�u�LU���A���i>M�7�:u��&�e�V�b�{��u+9���de�n���W���jdS���X 6>�A8ozt�+�$�5�Fv��_��iN�&,�����>�V�2�� 113 | ���7>��#_f� 0Z�Ҭ�`>�&$+H 114 | кe���H�!oڇ����և�h���N�+?����]����¿�0Ck~��\�,���������?0evg�φ���� 115 | �cuH��`�s$%��C_�V���@D��b��Q���R���Uͫ�YA��$|E���{Z|u����a�ޡU���_C�Sn�n "�k� ���ǥ�ES��ʇ�8��A<��vQ �#��\�W)WI0���# F`�w�i~m�!F���Q�R^�ȥ��H#�|ap�m� �#���gaH���F�A�>� 2}桫��j� ���>��M_d���d2���/��?�(�J�t5X�O�wN���n� ���r>-�|<��+��> ���z?=y 116 | W~>����<����W䯀������\0�gj[�y��c~޷��CՀC��C��<�9O�E2VnK+�g�j�2*��j�~�y�\'oޱL+0+1{��iu�W7*�v���o�ܨ���U�j�Fc=��|LƦ�~�߮��e����˴P9i�̫���ˉ�~��d� 9y��r }�u���f�**�?��8��?'a"U�[/�͑zyU�@��ʙ�p��y=�K��.��۳�H+9�ې�3۽��R�NgQ l�]�}g+D�d���3E� 117 | d�٠�C|=����"�猖���D�$����1����K��/%���c�io&5�O���p�F��r���r��re�+��9�Sn*���Y�L�I�D�#�#�@ fq �패����a�#���'��b��}=�I�\̮��'� 118 | Z�h|,=��:=(���T"����)F`E�E��V��j��,���Q��|�FQ��_�/���a��| 2�r�K�bIx�X��^��b����I�&��$J�t2(i��]�NE�Wؗ�,�ޥ���x�V��c�m�pF&+a�) 119 | ������z؇d�=�>���>1F_9�=�!��~S��`�����;{�L��|c���pn|U�^;�-�.�߄�m���"��;�aX�(��Ȑ�1|Y�Yz�_-�^U��{���������3�u��!��C+Hn9��d>�)Ȯ�˵�U�I�ͧ@E�$*}���*�~�� V���9�_��X��AW6��Я5�D�T��@BlE��M��+��Ք��d0X �v����� ����mRf�Fu%�T��c^���*-q�)tS9岠G�)A�o�jYJ����}A�8�I}J�J�e���r(��Z`Y~Ir��Ximf�)~�U�(�0�$���(���@z)��p�_\zv�Ow�^�9;]�W��U�� ��5�c(? z���?ܶ�g��'�h��N�rG]u����a���!z�"�!�`4y��p ��A72E{�\ G9 �T2 f��t�B��IQ� W���sxn�R��P>� #G����\(:�4Q�S�R 120 | ��7�~�F��9�����r����@ ��:b�Q&e�P�3��R�N�ZD�%&J ��~�2�{�@1H��r�X���/�SV�18c����Y�Ϸ����w�5��m��4�����y�� �/T�4"9� |�O��"u(�M�(�֍�nb.e1�"���r%�� �ӆ����ڠg��t� }*�ݶ7�DH��B�lg�]��rt9m72��Z�.��T �6ku��u�N��������^�=���Œ�B��a�F�_�l���cY����@2n6J �Ea� �(z��6���i��d0[\����Ioھ�fЅ�<����j���W��}�q�G��9�aM�\WWr�!���(�^�k���=s��F��-멜� jH ��NQ���k��p�è�],/�?��nM��b=�Z��dy׻�p�Q�/{B5T�)�~ �+�������0�c�ы�[�p��kM��[��J%����~uD.7Jwuw��:�l���{��ٻ<��X�rf��qU��� bÆ�f��fkL��v�[����R�^U��O 121 | ���[>p=�[�amEeĉ�u�B=\��,�UX�簙ŀ�b\CӴq��<�a����23'Z����@�cA��"�H��Qj��H}g{�;k�����*Sp� 122 | g���Y&���3������֚�������J���K�V~c}l�w�]�O���h���p�h��}Rm9������x�q��fQ4���j��sD��,/�yQ�e�H@ ���ʋ�u_@�WaJ��M9j1�2R_%�F�j$��l�g����P� 1���l#�L�щ��t�JA�8�g��,:�F�ջ�����-� 123 | �& 124 | ��|Q�5Jp��l兡��Ep�d,��$c� Η��Q~�(�����QOtu��1WJ~ɲ�1��dSʨ�H{�pTWؘ~I~|K,y�x�D��[C�K���.��.y��?ґ ��}� ��i(�v 125 | �h{�R@�[u1)�s�"�>�� 倢#Ҥ��Za����͍�t���a[;Ogxl����Ll ��{�]W&�#3�l�����w��G��O܏�z ���a�5xs�bV�3�w�g�ug��=N~%8w��o���%q�����1c>(G�3��J&�i�J��t�X2�E�4}�� {ѯ���D�VV��"����o�N��`4���~[�b���1BM%�CvL|"0�-��m�}Fq$Y"��;(:j�ш-��P=4]W�� im+�w�ԀvZ9�Z���ی|d涋���]v�8Uz�xc����]�N�n�Sz묝�-'<S����hC5�j<Ҕ������ <��X�*��]����r��j;sj Q��Sp��{�~5�7���������A�ǀf f�� 126 | |��:�54=hGq���A�%�xIl�w�J�`ޔ�Pv�,��K�7 �E��oA������� ��瑽o)�n��6u�,T~x���.��{�>{=��.t������(F������~>WZ�Y��fu3 �����i7�Q�K���T�� 127 | �h2 128 | SF}R&�U���*�0����, 6�1*a��p������2Հ����:��:�A/��J\���`�����`�A�I� �_/�q�ZΤ��oޒ�W��z���������]����aГ�2KV�@o��/��,h�Z�[��8��F�CwЗ��<�����O~��p���z���7Q3�;��{���a��N� 129 | �j�i�Z�C��1�j��v���WqӰ^�@ub ��w���+#!δƮ2��_Y��~�t�$ّI�)�s�";�g�Z�A��� Ie���ߔ���Z��=F���a�V�;vk��u��v�f��e��[���ϳ��}�{���X�O��V ���`^B5� �����5յvv�NN�y�J���>���)�M�`h�3�ͮ����sw�����׈�sR����7mKWl�Xu���8wN�Y�o������k׬?��޲<�;Y��(6.x&��U�8�����ǹՓ��9�G��̯�/��!��?��C#��F�l� ndB]�]�y����u?� �y;��x�� m/1HB � 130 | D_���A//Q!�;t�B�!�Ll��� 131 | 1�q]e������e%]���/��+� 132 | �8{k:|�K����V�U�Y�3i�$���a�m�b�A���l�]�V��j�oin���ݮr�.xIA�-��>�9X�h�J����f�3�U��Va������1s�8�ٗ7R��mD��C��1�/Th��&���Dc5��[O���`�L�o�F�E� 133 | �&_ug�K��y��%�:jz�%!W`׌��O�t�\�hԆMKMgZ"�� H{<ܲh���䂥3BNOsim�M�6W�˂͢oab ��x�+@��] �&m 134 | 6����b��Z��ؑʩ�������;�G�_^��W�"Z-�F��E�/�.�[X�Ge��#^e�Y3,1h@$N�E `���u�:�i��4jA���y :� 135 | ~�%� ��|8@�0mLtJ<����,�a �Z��Z�Q x7Y�fK��'�_�6��=�i��V;h� ���vo�8?i�;ZWd��u�.�;9 _�H@���X~��w��+*&�V݄��0����Ƴ�G�3y�&��|�����fsGj�lO��8�vN����_���Z���?��dy1������BK��:��87����+��UZf{R[$��Ґ��&w(T��5!�����=��.M�dnEk2�M �=2�������M����t,u�������E��F�q7�-�_��� ���h��᢯��!����ZE���S�Q=��w�"���6�x���o�גyyQ�;�����aZ@dԋ�c�?ڭ% �<�%]C��^�%=Dhtw ��2}O�g�����+a����9g�5ԸA~i�j�]���i�Xc�Ǵ�Xm��ŕ�c-�� kU�����¢�HQ��� �.aQ��i�Ӎ��.�nz 136 | ~L�C������}S������Paa��#Tf-��V5K-�=��?�����QU�qx��������l��#_X� �,��U{/�~|<�k��J&-\7+�gC��ۭ��֤IoMN/�t[S7g�q�M�>�i�j�Q����?�iځu��o'?<]�~��d�l���p@����`��K�ys�MI8�p��j��� 137 | �2�2 �A8_��;�ͪKp�A�u|Q�_���_�n�Ng���)!(��N��iU~�[�^��T V�mCg��-V���祯�̌���$e�E�z� �h΁���v@�ba��p�(��[�Ӣ���~^�՘�)��8oy�#�k��m�>-��<n��~�"5 >�� �����`,�g�0�}�`���O��1k(O1�F�N��/�2���+l�ESs����_��*3 ��- D��[�H � 138 | |$>�h��^���zN 139 | �R �%� x�N!�+ސ�_SR���C��Ap��4X�e��tf��+XO\7��뮋/F�ä�hZ�,� ���:o��EJ���R�b[� ��hX`l�� �@��6�)��?��l�lG���z��0=,�E��l�#;��B���cY�[�7�?�6��s��>��9=����1���,� ���?䟃"z��s��`<��h\������Ȥ��?,�/gyLI��h�k��������h��6�ҋ��;���^ ׮}|���GioH'a���n��C�����ҧvѻ���KN�u�����u9/� m��Br��h��S�����ڱ��t���b9���y�97�e�4��O�1� 140 | �ĺb�.y�p�� ��vY�&�k�[�j��_8��ӟ�籺��\$�����%i�2NC;q��*O��<$����~J>o��Iz�wm"8#�e"���L� 141 | �:R�4p�E�\t�#����)_�����/�9�^�\�-��}�\��_����r9*G��B��pH~}>���jƊO�f/a�A���l�}ع0�3��wW��r�KDoSB﹄E�;N#iQ"�H����������܅ :��3�3#^�b��Z�=.* �t�7 142 | /�l�N3�/]��#�Ԋ�����Yo���������d�/���2'a-�r�a|�ƙ�p�g+�}C��2ٌ,��KK��K<���]`�m�f�k��Z�̱��&ˆ-�NZ��hn�;�������]�-_T���Dך�N��jڢ��������n�������NO]�eOȽ�P4�]��}i�CS]��I_%VuY[ ��4d�oD:9a�*�X����P} �3��FU�. 143 | ����!n��S`9^ik��3XWG ��sJ�Ayx�4͢}}4�WN��Ik{��+B�6c����[���z=k�K����L�w|���c�\k)��[�����#��^� '�?�'����xP:̚wky�ݺ^t�Z&�gX�^��Z<4�\k�r|�Ur�H�`��4͇ ��>�pk�lw�*iB�U���� ~�u��㪗K�:�_�m-\b��l@jG�C���1`�Y�����*IbQԟ ��X=��G��,�=�i�[:�[Y�3� fȏ���g��Y����\���.۸����EC铞���|;�� FS[�Z|Q�Ё> ��Y�`�-tSkESI]��S�q ` �k:��/�mդ�����7�);p��s�k~&�*�.(�O^ް�o���P�T�Q�1j�}l�~e6�w댂N�è�ZU�@����N�fIb��b0�SB�4���T�V���q5H ������`9�;Xed$i�8p3!3@7��f�%�St��3�����w(�<�K0�Pp`�3V 144 | ��2���zO�.==��pF� 145 | ^���NA�_�@Y�ͨ=C$�QU簰��0�J�Xf'�� 146 | 2ܪ 147 | ѝ�jg7��]��Y�`B��ّ�o�~��S���+W���cy]ݬ���E��X,�NO���� 3a���^�������A���P�h�,�|ы�Ζ���b���� �h3�����\�(` Z����?J/�\rh;v�bz�rX �+}.��w }��H�7�1��u+���2�"Itҁ(�6F�'Fݲ�,�tnʒT�`u�,.���Zb�z��Z��p�8O� �è������{�v�ch���iAs33+Q9�yA���f0�*�!9�*y��`䧮x{�T�h��a|�����)r��(��h.��77���5K�U�?�?+��*x+�1����/�/5�a_Y�>��7f�*ojB�(���%�&�4H��� x*L�T��B<��q�����J7�����;x��Ē��B1u9�hԏ���0��P7����@š!O��v���)��c?���p��Y"��h���#^��ކV�!ю���@JI�+��h�� X�jȏ3n �A�V�p���Z�C�/��LU�:4��q�aE�aa. `�M���1���8�@��� �a�)�p#`�DIq�hފ�����ո>I��P����!`6���N$Or[�F�Y��-�a�Mz-�J�RƤsjh�6��4��2@ =?��4 y��i�o�O.6��&�@��ƪ��8 g/��"�*,v�h���_�.�@k�u��-X�+v�& ��N�����8,s{Y����k���UCӂ������v#���tᬘ�Vf����(:fi �46/9�����-e�h�t�GS&T�#h����*zD��l�B ��J@���]���BZG�z���ղ��2Q�\g�9��Fc��6i�, �2�F���V;䝎�+� �(�� ���S�@�VL)�ݛ�%�NV� �:a���E���(B�?M�����'8��iѪ�p|G��A����5A{�z�```]wxB���a��U��&$n�unw�/�E��!�l�t�g�6�tF���^���`r��� ΀vM����s��²=j_��/ʷ�NS��\�������ֶ���B�rgU��X4��9��m�_C{������3 �Sj�Қ=&�@� h(6UCZ�E���J�`p��j&=�`�Z��JBsŌ� �aL fɤe��e����2�[��4_�6���{�A\�qڊ� 148 | %� k ^�q��TUJ��j����Z��l��pU�Hݖ�ym��ĠWO�Y\jY`��B�� ��x�q�z�0 `�4 ?������1F��Q���K���n�EF��6�Ȏz2zK�����g,z�B�y|�Dk`t���鳲��T�9 v��C�h� �h��nB��Ӻi~��l/�t�kc�k�6�x֮r(r��X�c���7�L)��D��� ElP���{��W(@�*��M1G�3Q_\Uܶ��eIsP(� ��p�[Y�m�\zip���G>�6o|��v��ݫ�ȃx���Hwx�IJ�Q$�*c�|�ZBSʳr����_� ���t���B[��Q́�����F��&��F��D�Ǧ� ��ݵ>�F�F^n�4Ļ���H��dZg03���������LE��-6tmYQ��y��[���n��[uZ�]�k�]�������O-�\J�XwP4�Q��g�8�vi"3��b����N� �~S ��Q��K.���B.S(W�����b� 151 | ��d'~L��Y��R4@�lm$�����/����kmȕ�X�_51� 152 | i���sQ��� ��u ��Pf�����������`�>y�It��/�&N��K4����G��K�� �a��t�=��K��2��A≫ 153 | ���l�6��Q�����K'�?��� �ݛ�R:!+ t�³�BGw���$Iz�5��08�;6 156 | o��b���-��b!�B�6�� uٳϢ��) 157 | �)�e�g���K�Y@��\͍4�VB���}��f�$��9�z��x+C�#�…{ 158 | �i������<��A���ǜ�J=żT�g�յ4�k�B�(g�j�t7Lp�:�d<È��So^�,��齺��S v�5k�u&sQ����9Q�c��s�F�l��ǜ��-� ��EЈ���`s5�Dr�Yu����o{���wi�g�����a��m��j `��I���hf܄v�SWzM?�6�YNB�&C�m� 159 | ����@S���Y:�h�k�]һ 0��b_c�␾�_]����|Ik�:�dMZ��#�kv:�##^55�ZO]��ƬN�gc�D��#���5XJx��b[�ZBPCcH�TT� 9F�Xe�*:��~g��b��m�Q(�-��D�6n�]]}�o� 160 | �#�˧�Q������A������?�����W&��M�d8��qW�������а�cۼIS�@�.js�1��� �/����1���������� Ņ��9�l\>�$��6��e��b��/_�S�fŲ��'�{n�,8>;�l�������O��0�0-q�`@�6��m5 161 | zԡ���wգ��2���ӝ�X㬞�V�K�u�y�cRT��9��|�b ��$�O�m����k��Ǥ�%�̣��bgD�ܣ/<��/��_ʷ�_}�~P�D�x5�(�߿|��o��m��C�٫��g��ߤ�俾� 162 | ��F~VY�C��N$�m�k/4U9�'(h, 6�q�p��i�ĢU,��i8hx�k#��9�dwz-�]�|V�ٲY>��rI�@�ڒ���\0׷�˷�D]�}JNJ9 ���W.h���,cи��� �H��%,g5���Px� j���̭�fvU\�hH[��m�\h��5��՘�;;9�i�6_�Q��}֢��c&���;ڢ���1��9-}>��W�����Ab� �.c)�In%�UD���>��,�/h�021�:�AJ1{+����������[�{���q���`�)���~�jo��cG����j���1iL�� �b�*�i�dS!2}���5c�����a2�Z��l��d��iˊ9KqsT��ɴ�; ;��afT��U>���%�+k��b���GY���jQ��,VC�j)�[eP�� ���G<����\�x�՞[�]�jt=�~'}��� ��6*�#A�8����ϭT �2� 163 | �X���bK���p��D�Z�(�����׷���e�!�?�����x�2�K-_ȥ� �5‚���Ap��� ~Uj�,{��?���?�Z/���g�o�~�ڒ�����[ 164 | "m�'N:����L�a:��� �h��x�>�,j�Q���� 165 | �8�;Ѡ;�_�+B���U�����۴�}���K�Pkj6u����O{�{�i�I= �?��s~����^�X����@����,h*�*#���Q԰��Q��3aXHp)Brk�$,1J=�$�����_ߥ9����$�t�0��us0�(L�L>��(�U�3'�)˲��X�|bk�{.�$�#��{��b�*��M 3R*���V��.+��r?Q~{���3F���O��]��j\��x� �_�b}�*JpPh���=�->"�WT��������>��#��БZ: a�^�a"�/�9��$����3yɘH�y����❕�;�/)���������a��Pp-��YVt�E�z�����k;K�KC�m�?���9 ��i�N_u"��iS���"b���Pɦ���˿ ��w:�W(x �7��(c�غ����D��d��b Q�"!�2��4�:� �n�H��%Ux;�R<�4�~�:w�C��������r\3��������2;^q���]��9�;�ʉ��4�q���6{���;���������-g����*������{���t��G�w�GUe��{�{�7�f��'3���N���zh�w ahb��(Qv,(�Y�ZP��ς����� s����L��t?��?0����}��s�9�eq�r��>��rt<�gn)�Ȼ=!^�?TG/�J�鹠b��{5ق&�:"@�vd_Ү�C����i� I��M��@%����})6��~Z�s��yi�� �&��zåU���C�C��-F���� ���uMΜ�|�:��AY���A)j!�ff���íYKl���dD��x��y8��% 166 | �,�̓��Tj1E�x B!�D?A���Ax'�?����ą�h≩}�7��5[���X ����� ^n�T�?��A��M�����JY��δ�� 167 | rx5Ͽ9l�R'�5������Ӹ,�\0���b�<��0J���$�0�6tϥ�Ly���+�� @��۷���!�A'���+>A/����;w��S��@ʇ*���]N���r J=�R��ҵ�Ԟg�u�H(-�]�R����R�$l^��� �}���{�����n�"<̩'��T]� ��Gh=�:6�'cğ0J��1�HC1��T��O�k��0��q�)�}F?H}wÊہ� �4i؟�q�O�m�'���ێj��%#��=k3:��)%���ї�¾�袺�s�ql&�{��d��ܑ�xMJf�W8�O� 168 | �� 169 | %E��T 170 | ���O�'%�_�I�h�N��$t�Ϛ"������58>��s�dO2~�$��3џ�~�烌V�JLL��L�dR��Jj�ˡ\����䰼�N1=f21]8��GЋ����A���R�yã�[f�� 171 | ��j�S�G����Z3GZ ]��� �&�D��� �g`6Ko��$XL�� ����ZU�}xRy$��f��s�w�,��J���6�ؐ�R(� ��K |�F��K�dU����X�:4��r��i�8���Je�~Y�h���O!y�΢��R>�z�Vt��UG��V���w�<������0v��&���7TG����8����Vl����Ƣ!;�^�8O�W/�&H#LD90((ѓ���? �a��)A�m�!�L<| ئ���%\��ÌL4⏕`n�?`�������V�Wk���h��b�+i�Ś��b�%8t�i���5���@��/th��$�pK�套��s�����G�X����h%��bɻ�b�/u�5K:����`��Ěc�bֈ^�:Mžr�ݹ��׶gY5e�\pA:K#xs"��N�t;�f 172 | d�����B�C 3�v���Dk��/����U��1��ղ9GsX-B�����C<��27ǽ���� �M�.E�guL�͋\y��Y6��{��Zbu��y���E�5%���.wA�P3}�S�nc� e����z���5�2�QYͫx`�բ*'/Η���C�i�~��E�'`ciE�*������&9��ҞKA��#�� �\���:+/�c)q!�r�^=�{�p��n7�\ݱdq;������z������kڗ,\�Ր9�N.�N�[�EZ4��w^/<4�z29愘�+GU�=��0R=��� 9��#}�^�)t�r������grt:��".����^Q~;���3�ʪr�mNEE�@~��}P�f\t�z���Mբ�I�`/81iS����N��M�PV�v�<_aO�6)���h��N�v�9dy�X�O�JA�1�`S�N�F� 0d ���7�����`z�$� 8g0: �a�ї ���Z\f0< \o�����qg�~1�?8`|�l�"�[��nb�1 �Mys���B�'F~���Zb�vGN ���u_f�͉�k�E�/���˚�>����6��D٘����HN �T1P>G��O��6g��\��=������WNe��qo��t#u�z�:J�O���'�)�%��A]4Q�WC���MR�& �$%�j��¢ 173 | �7�Hl�%��Gm�P�P�F� ���@9sBM�\���+�,u�`4c�NZ#�,�U̥�����.a�L��Q<4I&ũ1��@��aWN�]��P9�h�^^�=T0}�\��$y����'�Ѿ�Y!�aE�D��*��n�Ĉ\n�E���*���e����S���4Op����D��1����K��r�2B��}���qj���1�Ʀ/T��� 7�8K�YY&�駵��l�W�S�J9�=�4OG��:�ٝf+\����*Z8�N�ʢ� g^�@��$�|%�-ϦWH�M� �VLR:/Q�J�h{8�s*dX��J�5`��j�[p��k��&UY��b���d`l�&��L�S�Tr��@�� �t�ڞ�)�{i�E���ڲ��Z�w�:��0Th��� &�!̀\��V`)��;^��L1�C�|]ߢ�����r.-���8��e�u� J�|�W>R���N��r �8x�A���#��b�+�<���SfL�M�6�e-�� !��d#_��Ԛ�Q&��q����qPB�k����A��(#Zq�Ɨ!���Jp��l"�1ײ�kI�ZV��p@�?-�=6�S��s���,��e:3���eZ5���R9+7�N�9��In�ۇםX��gCSٮ嫳lmu� ��,�3��m�9z��O�PEǰ�B^��r�������F&B^m�c� �r�4�s�ͅj�\�g1H9T1rFBC�Z��0JPh��w����an��]b�յ�P5��ނ�G���n��W��g��k�uʥC��?■�ͮ� �|���@�-^%;��x>�@5e�yA�U�9��54mƄ�Wbp�\!,�G��hD"�� 3!� 174 | 鄛HT\�6H8�`9L�E5t�V�\�)����{`��{���� 175 | ꔻ�@`N�����{��9�瞞ݷ�v5�ٛ:W�nY�u?={���%�1�4*v e\{z�?gm��e&��b+hP��9B��{� O�Q,m��ճ�U[`l�\5zH�ṽu�=���`��zr��������X ~�UӚ �gv�^5y�#�Q(2'}CW��Ks륊�O6��7�Րo6k��C��D��&PS���<�J�N��,\ՅDe�PZC1$ӡ� *r���1ѽ�c�ȅOQe�4}�TB��%"�9:���v̀��OHn! ˆ�"B]b��� ��PIH'h�$tl$gup;0 y�\#��0�¸iI�q�Z����!����-z9$Ey� (�WȬ i�����*/c�[4� �\6����P��u𹚫�� �H53�g=>㯳�X�N�o�Q�5���\�8<��O�n�����}�թN��h f ft+x��2�����mS4���8�vו2�� 176 | )ѻ����$:(��Z�1��F������bpB�2k��Yc�ÐQ+Ꮏ�n�#�4w��ݩ�/��+�kO�T=�#�ʶN��= ;��3��3�Q� 177 | @&.֯ɗ/�oD�{� ���L��=a���M�M=I�����;�eχ,'���d<�FO�c��J��wy^��@��L�{��i׼���ɥa��r�q�SY��<��.��'\�J2����+��]>(E��5�^B�K��1��g��Հ�bAt�������p��7o�C/�Ҳ�j8�Q��Q��ޢ>”�Y�nPj.����$Qlw������[�Dž@>�����|���rF�R�=�v�?$k�sH �L��k꿿�� 178 | �N �\|D g�������C ]�ݭ�~wS$cw��T<б�|�"QDRMc����jI�d*Y �N5����~w��Q�Hպ�A�k�3��`�$0 ��t1B�(_�%�Z��U�h*\��Tz�R׋Py��Rя�9�h����`A����s�d�Ӭb ��ဟRX|� 180 | N�j��hZ��; �'���h0{*�A��Z+�ehȦ��`�<�����r�����^P����Hm˄V�����}��T��WkO��' �#gm��k�O���W.���Q���ZQ��� �{�p������=4A6 Ҙ‹B�3?��#9���Db%>O�Cxu�'@<�����>W�8���-{�j��>���9أW�9�.Yz&�o����m�C}�s�1��e5�\Z|犩��] �C�-`����.��*���� 181 | �4�5���K���}_.]|[NIw��z�������d� �6?rp������%�K끼5�kq��Ag��Z ���3�g!B��E ��R�Ǖ�>C�l)I���]{�k�m;���sZ���=-�C���s�[����֯{l���|~󪧭�[�OV�ƀ�#@��I�k�<��I�{wKk�[�V�?Z�����E?��oxtϥ��A�� E?P��R�> Tk �l�R"7(�/��C��m�Ue�@$��8��} ��,� a�[ҳxq�^�Q:�ZRP��j�Vu� t��%n�2�f9��ر]7�~,�U������n�6c�6:�g���ѫ�� ��+-.?�M�&��fv߱����s#zV�wq:꙱m۫۷��c$_�g)���O&�&�\@�b�d�3�4�n�'B�X̡�����1�R�;�q�"��LN�,`/m�O䔰m�8�����F0�V���\6&�������yhM&��t�3J0��`���g�����@���5��zzX�—#�Ն1�o�ԠRڮ�T�}�V*�y���p-����"D$ן2�pԓ1 �8��G����0��7O��y#��xh��(���������> 182 | ���M�s�wL��iw��:&m�H����)�yi�*F)�I�$q�����K��wN^�~2��I�����6JU`>�u���<����I{�2��Yp���)\֤M}�����$/p���3�7��`r�$����k�㹗8AȬ�UP��L`��}�QLda��~�� TW�l�i �f�Gџ0Q"�쉠 E��oE�V���-ȃ�Ǘ�1I`�|��؁����%Aݶ�����8���C���D �À��H�R��.L4I���f��N� H�Ry����K3�{>0P5m���h��9v��y����ռ���%��M��|Vεz0�cQ[} ��У��cvg��-�����3�� �盲��^Y��)��Vؿ�娢V�ԳV��B��a�\��Α���.ї-�&<���_6��0�¡��0z�̈���B�@�} 183 | ��0�g�I=�FS]�+(��]`� �\x�����\J�� 184 | K<�WRC�Q�4j:�s�ۨ�ۨ�T/�.�Ez����Gq3���h�9�< Fv��Ķ7a&�8�P�����3���(���e�ӊ;8�sd�� �g$�"ٔ�0&FD��2@�l��D�i�az��s�B �x�_�o�:�@ B 185 | Z�IH�\�V��Jf9 186 | �J����\!��2ٙ/ ��:T��٠Tf6ˤ�v�jUȡ���f3T��F�� ���� ������(��KZN>��R�q�bN3�8��ʔ�ʗ5 f �j�A3]�֚�@�Z��Oj�M$%��RN �Y���[�w��z�t��e�r�Z������l�JYV�����9��q*� �N&[��5���L��[2<2?��K����l��*��}*�g?je܏�Id���?r 187 | ��`�^1�}/U�߃wyE�|k4~ N�T��~��Wr�Z�@ 188 | �څ _(�Z�� �V���T���%��ZZ#�X�>u㲻�^Eo2˽�T����'��v����� <Ր�*`��c�N-FK�+���P��� 189 | ��W�A�v4?JScF�'�c�7���3 ���SR��Ӏ�\��Q>j2;�ⱳ�I�ܯ3s:�,([.�edW��=s 190 | ~��=; �!F�Kl*`D��ǯ���P 1�I����𿐁�I���� �Ș,a�8����p�c3X)W�W�`:�5KQy��7��j$uE��|p�M�5* `�l�h� �$��J�6�R/#�������4*�8B��ݺ�ؖ���WX.m)R3�fa�-�v4�+�JP�<�g(b�v��#l.�؄�+�a���攀��³�eGw_���HXc,�@�u���-���ѫs:�f��p{����(nX8fQ����:����h�o�6���֏E��: �~�D|%�5V'���8��jK�mڿ/�ѐ�K'��oB�vNg!d��K�uK��,`�靿������|�����Zh� �����Q��f$�v�,��>��%F������v��ځ���'�C7�8-6��F� �@����6��a�Y9�_��,G�o���Чͳ%�{#Q�kA6>��oh���ͻ�㥌��d�����͟���_G����蓌����/t�k `�R�Ӎ) ��|:2r �⯿s<�ʖ����5E躉�]���]Z��m/x�Ɯ�����O� X�R����\�r��o�yt�X� Q]���$��^����Ӎi���ܠ���*�nR� gf�5�/C�7A5 (�1����������G��u@����|,J�$�4 �DI�������ID�m��x��8=9��="�zc�����q2���wНv�ȅ GZ�5�5��!����_�u��*�Zm�ߴN3^#�7$��Q��LZu%!^A I1)��91�C|G�D�M����߰A7Y݌:֨�n;VB�������NRS�q%y��o|�&5ز��g��t1���cL���0�o�1Cٍe��^w�>����½!6�jf4��K��� Gzi� �d�ߴ���L]���/y �r�E��F�~ӛU�Q@�߉��`��1q��Uwb���\L(�bY�����%�)� 191 | Z��Rlҿ��˪��0-Wi�UФ�I�S��+��_!���y���]����+���r��=`�'tv7{�������}��1���{\ǃ��$ ��c�ϜZ��; 192 | �;usg,�kv۸U��߻|�oz��r��PQ�w�Gb������� 193 | �����"]lɵ\��{h7���{�‡{8ֻo=`����#�vN���_�2}N��$�sSz̙Z 6t6��@f��n:6�i�!�T��$" �W8=�����(}�mZ�x}}5hK�ż�{�8P�޾7�yƾ7�^:�8,B����7l�{�8���O<�Ĥ��lt �j��C`�)7�a�9��J��l��6C/��?4g�Z�+q�+�Ia���Ʌ��������q&�g���� w���.���yE�Z�EW~q7��� ���K&*�/��: �;,w��oܳ����eCk��5�7��n��u��g͵�&շ��7����ڱ�f�}������?��u���P��;�o>r;��N�}�z�t�Pu]C<֘���јs�Uۧ.���� ��o bo���?�7�g�W�� ,I�$Z* �!N�|˲f<s&|헪��m�����:�?������^K���g<����CB]DSX�I*᪤��hs�9!?+K��_���_�%9����@�s 194 | Nz��O|��j������ĕ�D�������A���i���������$���ڇ��~�>��z��Qtc���+���k����x>�7n�鸧���H1���L"�b�N65�|#.h��d 195 | �`/�0�뉚�]R�>�[�K�� ���R;tHdNk�Vrh�*�<;?G��j3� d4��� ьi��1;����^C�g���&c�P ��S��V�9y8xqcn���蒳�ѡϷ�]��j^��� �閪�8�����w<:ml튵ݳGV�t*�魏�7Ϛ�q0J����g�!�=B_Sb>7L�S���*�J�&�o#�'����q��&���]+F.O�� s��!����qLCDk�tK���||���4c�LzbU��[���)���3K�!w����Y�޶��o�������X�q��¾���é��� �[�?�b(\�5�La�乖�/{�s �a��t���q�/�Rˀ�Ɠ���/�=����V�!疕�� �r�R�|��B�DP�xt���|߳eg)����V��A"#�^A���� qF��$ڻ"��d���b&B��%�+�ձ�����a�6��U���{�����n�m0�Y�o��M}4�Ғ|�y|*������I{���6�b =�} ��6d1y�ݰ��=���s�/�}q���U�|gF���OS��1� j~���;q/^��u� 5�eZ�XnK�Dk��c`LSU���xM��֔v)#(���&:�!��P U����Ԥ:��ˮ>�eKqGe��6(ABO3�cC~�QgTh&�*�F&��ak�[:�V#U�J���5.Ugp+* �¢�*���f����=�c(ך��W�����1^��4���٠.Q�K�� w�ƐetC��<�(�a,��z�B��0�������V<[M��>CwUc:�y'܃i���9�}��^<� C��08C\�OPE��^1��sZ�R5��Hvn}}n6m������p�b1, ��P ��������؊������ ����A�1���e�Wv5�wǽ�����# ��h�#/����_]�ps3:��������u�8���i�fٟ�>�0��[��v۶�D��Y�4���a�g �"DR � 9K�v���H�R�]�S�Pŷz�Jƛ�3�в ����?X§)�V�F�� �1�I��o���0O����%�eœh�yw���� x�������A�;�2ބ���I�>���g�vz 198 | ��_�a�p����^�i5���ҕp}��ϛwJ�9���ˉ�lԔV�4��W5q��H� >.{�C[�|_B�>�N�=�^[��r����9�^5b�U�Ιv��J��ڂ�k�|�߰8��Ng��NJh��J����,�J��A��9����*��r��D��x��0s��{P�6_WF�����j��pm8Ϛl#�)k��u?���!K�́�Г�� V�{=��ӓi�3a��3� `�F�`v�i�n`�n7�< 2n���7�un�h�C�"�$T/^B��dG�#�y�Yl޼r�U 5)� ����������嘭���C�/Y�Z��,�[,� r�ͱZ����h��XqE�~D�jŗ�=�k����q�W[Y�$9.��v1r�q�j�3�܈�m7�%���q\���b�r��2:�.�G�!�D�8��<��%r�ըר�i��^��`:�X����+�r:]�<c�r6� ��yi���䜂��?D��E;�x6��@K��Ih�u���϶��aں��q�V-���6 u��U;����V��3�� �V��Z��������G�>E �;B4�����1zb�_h 199 | {b��#g�¼ ��p9�t�(��J�����8!�RY'�%��saX{�D_�!"8�d����r50�.&ʷӾ�6��ې������9�p:��X� �q�w�3Ϡ��h��u8�e�D0�7D{ s&B�yf��th �sȤ��'�7VT���� l�L������.�/!��”��.7����5��^����FV�= .H*�^W�R�֮,_�0.�iW�]��ee+�ܸ���&��w��o]M�P��{�(a�W���80�=���p���\�����qZkք�΁���w��3�V]��"�K��f�� E����J���ne��*����k��T�7�*��>q{-��ȕ*��Ln�w��WX�r��.� �ҫ��.��z���=���b6���9b��X`-���Q� 200 | �@�w�����?qm��Ep_���|#�KW�W�%eB�3µ{ҷ��e(�K@ږ� �˃K{�[@ Ǹys0df ���Q�9��)��8��{!�����p笯k.��U }�>�}�kk�׳v�@�՗.�q٥W�&���o����E�3C^?C�?�G[��۷��={b<}���a��A�� ���ui���������p�(u����iW�����2JM�_+����X ��� ^]��"�~ǡ@�)��<��MN=�B�ó�M-�L!�mL!]�}�c@���ж���\��%���:����%K��o�`���*�*�|3�*]I˰��@��uXK {��(|I|�~�_� hq���%� A_&A%D̠ڍ��ޠ-hCxB>�Y����3�=��8�:Y�7bzS8?%,���S���/�ҋ^$(3H�ݝ��H� 201 | ��$��#�BL�*��f@��p��O ���UF����ٳ \��@ݟ����� ��e 202 | � 203 | E��H����q���uA�o=���S��g���DQ.����b�&.�{���f�׋�w Z���%���0���.7�s�?��?���~���u�?s�Ȋ� �'D�;F�F�����El��188:����UgFͯ_6�m �0c��YV7w�U֜��'70�6L6�rh��+F�Z�|T��~����815��5ipM���V���OKZ�۲s6���ž���b����D 204 | ��K�읁;����!�f I5k�%��f��poZNK�$p�܉����7&�x8"~�����}���3c@�qL4����GK2m� L��5�� T�N�y���#4��I���� <1�BD��,5X 205 | a���y���$y�R��c����T��P��YL�єP��� ��Z�Wfj��z�A�3��*S��Us(�go����.K�Z�!���Jڊ&A�� 0���%Έ��-B:�)NゝKg ��u\6��߸~��-o��_��wSg�+��g���g�C�.�f�$����]H�x �G�h�c 206 | �n���@d���V�`����2���]z��uܸV�J� h�s��UW���+�w��,W�D���}�n���O���Ӥ т�f�}́R�j5��Nͧ���y�O8�<lH�.�6�N;@{ � �È^x]8!�D�h"=�eN ��2�3�x,> 207 | I����$�,>�扵��pB��]41�����+�R���KH���)'!G��,�~%!�z��}���< A��� 208 | ��&�d!�t2�B� ��&Jd4�1Q���4y�A�I@6d=c��2��/c����~�{V̢4� ������Wwv��Ñ@�������|'�]_41�z�J������qKOtT����)��j$4�+���ӎ0�K��Q�1��sm|�~2���k����5�oZ�DnH�����g 1���,��:/X9c^��k4y�UzK�q�j�No6�y����u�4vg(�t����N')&]�tjJC!�S�F4�!�H!C3�Ą'$O={�b���j6i���A�9C�N��@������q�z�|jP���8uMn�˦{��n�2�z$aF/�K�17~��;��D�1c��A����2�=��|�ɪ��x��\T�>�m�:��V�����b̗����o�}Y��n��[�7�����}_Yj/��c ���������7N\��v�u؆-5\�ƭ�I�~�ĩ �/��,H]>|xq"�v��JϠ�� 214 | |� .(D߼��*+��੧R�\���N�?��h�p��;�$�O�UU��Ӂz�Y��������&�7uj^�c`+)��4�������U��3ұ�sX&�:���t�q�{,8�q�d>�I�M�L]��Z�� 215 | �E�M��1�V�� �C9eV� H꙾r�J XE�E �֣o_��r�Uxv��|0�'�5�#G��T�O�|x\��.��P������ި��D�K�8�ć���GK��g�d,�Xo�3.A �5 $@���k3�7_� ��c%ByN�;I�p�M����h��Z��UT�M6 ��;�$��=��=<�RI��R�5�c��X6IQ���!3�;*��j���� 216 | n^��JC��C���Y���z�A�H����El��E�z@.�Y!��ᩡl�I����%�����Y�@Գ2��+����^�����D*��ԿV"�� �h��2-0�e򽻴2.��tKUr�]������U��т�@�@]����������b��ҿk�5���ԥ���-�:�TB����� 217 | �nz��҈܄� 218 | �n"������(E�.VX��䫋\I^X�+�PM2q��2$��� E��)�2����(O\"�DO}Q��� 219 | ���:Z ��B�"g�[?�kDQ3[]����Ь�,e�R��*��7���j w킗��Ƥ�w��FF�P^A}AA=�pQdrע�ļ�ڲ��3�3<�KZ5(���p���iE�UeR�<�Y�PSy�Emֺ���فl�[�ոD:�F�]��\�%��t��e��=���겒����nEix�ܹ}���v�de"<���j��y��Ԙ'�VB � +�ͤ��~p���c��2�D`J[����f����^��D�^b������zw'�V[1:k6������Q8�4�W��9ii{�t�s1p΁��WKZ���9�Z��ْZ�]v�>)�w��gys&�p߷W���7�z��0 ��D{�s�a�tD���� �]3jA��%����������S VW-80�{��Wt�N�B�D�����[�����|�D�`��-�� �BU��0�?1�D�ɠ�X�T�Fv�K�R�8�������|dO�2i�M�A�<�xaC<��2FI��ϑ��(���� 223 | �^?K�&p�\1m�G��^����^ u�4�98�r�l�P�DŽ�Bڜ�'������Ȑ ��N����^;� �L��h�]�D5#�47�2uպ�'�u}O��� ��/k�[Z�5�Vk��ֺ�Ys$Ԥ��q���L8�>9 224 | 6���ز�4�O��Iw��������I~�y���~4=�:"`h��0*� �6���4`� �F��)b�r���#��!�f��"G#jS1�s2�_F8���t�r}��������]Fs���u9��b�W�������&S���e!��n�%~����g�!��a�������?F�D��[�&����N��תM8�!� 225 | !P�+�:lb�mV�������̯�ֶ�s�Y����[�cD󂼊%t��H�@`������u* za-�N2T_⾗�����+��Z�R���>�Y-�{���=MA�<�ɭ���;�����S�;xށ��>\�23 ��[�'��4�'��͝y6�d��F�[Ha���,��rTH�*��OQW/J��UZ�<�֋�p�uB�L!�LH����Q�X��P���u�%!�]��D��kա�m["��)���\0$��R.w��`б�s�Z"e�bEVŸ�]��ӭ��(���8�&t���{�+s�^7{lyEN����K�5c�5�*���.J���`s�����Z�ϙmW�'|���������/w��;.��Ѯ������x�`�m������i3._�#������,�9�bn�Vw�~�6�(����b#0֟��d�D�0T�پ�0)�H �-^�L��*K��l��D?t�0̹�Ep��|��e ,��u��O 226 | �=���k�v� g8b#+�6��B��'G�|b�Lzp�ӓ �ʜ%���?����ϔ�O�����3���1d�~r������Q�|ϻ~���!*L�G�Z<�C-�%< 2ɴ�x��X�n��W��<{�;dmKQ�U�&!h9W!s�Dߣ7���#�w_@ �'��|�Ļ����_�������o����P�����F����>�K ��*��5D"ђ��b2x8��@������ Yx 227 | �">�!���~�S�&�����J��Z4O���>ˑ�!��ټ��;�֗�� eM�kd�#�+���M�O��#@ 228 | *�)���T���=/���9�N��W 229 | �� ����1ń��A�)������_���$7���"���>s�Z�̔�����JS���rm��X�ē��`����;o�]5'��\��G] O�3`T�D�����.ķҕ�'13��0#�n�CX��o���a�.&� 230 | ��aH% �& � )���!i�-{��`D6� �P �f�ӌ���xI��;RRw%cÆŒ�N�^^n[^Y�� ��օ+p��� [�����0-�XE=J0#���,��!�1@Q����8T���� <��OF��z$�����ܗC��5��{<��=d��L�.Bl���9`iĿI��}���?��ӟ%��q���9��?���6Enj��#���z��Lx�C߀;���w��>���#~!�?؄~<!v���C���q�_&`��f} 󆂭t~5��d&{ZpNM�Wd]��i�V\WB�Q��F��ID�$��#N�$���5L�� ��]q�PXT�M�jV�DI�h��>�d�]�2t��x�9>��>]��rհ"�0|�f�ڜ� 231 | ��; �۬�n��-{�w*EXP*sǎ�pj9�V�8��j�h�J��G�;���H[K�·���%�';VW9���h���J 232 | ���w�TO��oϢ��1�������Ҿ�vi�r�e/g���}}?�\cS[ڲڧ��ѭ�5���^s�Z��1��8x��<�w�L��+����J(? 233 | 9ul��^O�r�N��p|b�Z[��z���>3��N�]��3�L�5i�'O�݅���$� ����#럍� 8��\�|�Տ,t�����' 234 | z�������"`�Հ�4,�{K}��;?}͍��^g��e5r[<4�����L�Lu���B� �Н/�8��ԭ�kG�V�$��ʗ�͒<��p�X֢c \�?SP{���z����mZ��hH��� Z�x��*�Rkj�JZ��;o�R%U�YOV�V�*_�_?M��̺�v�vqR��c =8���0���j�Y�3��}B�-�Ӎ��a{��- ���VTD�8h�{�}� 235 | e���9�$!��[N��;��#�g�V�[�eɲ$W�Ȓl�e٘bl��f�馛N���$@BO�@�R)��0�KB 236 | �A�8�4�\��Kli���J�l��}������������̛7o���D�NO�Ŧt�^��'��`���H�T.M�ҀF�� �-'� �=I$��ݨP�Wش�Y0V3V"�ར�����4h=sF�1\�U� ��l�?|�U��'EX^*��Փb�h�V� 242 | |�(��S1�6�mZ��y|�^�v��'�`K�€� ,,,�/�_>�_G�_��?���)e�gΌ�������1�(��;�� �xϯ��Mϯ��}�����Bh�*�������� ���!��(�0�zO�ެG��vJJ<{cy K1�qA| ��^t��@K9� #�����72����e����|�:�?\}c��` �G�0%S ��в��O?���\0�=C}%7�6� 243 | O�uL:{g���p�1`]��L��K��X��c���r��,��w�'c�AL�� �����/?d�$�����{mX����3x���9O�C��&~����Ϝ�bϞ/N� �����W �{��C�{�m߾�7[5�Ƽs��O�?��ӧ�,\������x�]�!.�g��R�ښY�:*�d���oarrs�3[�{VE�y����>����v�[���ˡo��XM@Z!�� 244 | �+V�x����V�4Fx��an�wud<�����,�>8d��7�[���1���j�:pBZ�����<��p �"�}���C�}���7��� ~���?��*�LamI�FP$��~� �S���jˣ 245 | )UJ�S�T_��塈2���#�<��MͧQ˨��BoDz;��{���1�"X��$G�݀��L=���.�������� ��[��q���Xi�����ԧ"���o4y^��ȵ����� ��>�~f�3��B5S��~VrnV �����n��#� �~0,���/�x��聞�?^ԙ�3�e� /�]����wuow�$3��gbj�����4�ר7�!�*�Fyj�gQ�;����9� ?�2�~~�hў�������tO:�)��t�=�'݃���=��=��Cu�Y4$�[�����:�����, t�BoE�Ԙ����LoHMe@��-5��� ,B�o;�{���q^̍,f4&��v�p��h�Ȼv)��"<�� 246 | �'�*�|�0Nز�0[��JnEE.W���� :���LD�.��D��8�ߵ?O���DP�I1����We�s��烏�8�ba���v���zig��������k6~���[~��΍�����q�D� �>M����f��U��^OM8�R�����u�����6.x~���j��T�A��k����Mg�z�և�:j崉a�U�����3�iP�R��t��LU�xY���`�(��@|R��*� ��EDzgcg�@� 247 | ��'uA`�2+���,vЋ�ć/ D�t�U�wm���Kb��I"��et�'��&�d���{��b���D�r�RINf��$U`�>��[�2ThӌN�Յk��-��z�*�FO<����(��:s��X��v7b2u����Tt�\k�.��7�ǻt(����?���GC�߱7N9�5C�t����%��igC��̉g�S`/�@χ�U0>���`;lc�(���������|0��v0���:Җi#!5�a�� �*:���0,����O <R�|M���YJ���)llj*������S��nE�뇀`�O��Do�k��ͨC�b ��+��z%089�fx���1Æi��a�P��p�_�?�=/!U���z2,l�OZ��t�9���@`�������~��m�nC�N�NPf.���l/�I���M���l��LX��\ܗKj)E�u�%u*bN �c� 7��kg1(  �;�p{1��-�g1�@�\����2t�� 7D� P4-�oo�'�)%z�2���9�L�5)2<:�B&�)�:O�¤������T��]�E�ݶK����~�M� [�uN�9�\[F_���)6T��V��p�H��tK�u4�ӬV����6_W����ʧU�;�(+��4%ɤfei�^o�H���$S���;�C�!; ��竭�>��N�5)D{ʎ!� K�}� �rљ��y�V��Ќ�w�1�H�d�����e�;����N \��D�FC�hW��vπw�;ty���9rӹ�p� �\;�>#�~��`�)��a��h��Z�b��iz�Y�jq�;~���\l��ЛS ����+�rjB���k���oPl��� 249 | �)^���NA]'ޮ�h�}��f�"�c����.�!��ok岭�o<���PB��{?L�'�Eԗ� 250 | �D�� �=���]*�.�g�����J�Ŷ��}Bo�t��&�&�� 251 | e��\��E^׭{��/�NK޽��DX9#^4x�C_ 252 | jK"���w���C��j�M{��.��(,����ր���+M�sQD� Q��c�T�P^/4�y5���@^+/��'w��4} ����Zsũ���"�`W%�� �y��GIpC�����0��:E?kݺY��Ɏ+ U"���5U�@��Sx�W������.�0p���Ka����X}�����:���]z����I��nN�6����C�̦�߾uQ'�|䘔U��V�є���N���=�?��v7� 9l�&m�O�N�b��{#p���G^]/�� �SJV�������N\�*��T-�@vf���V���O��!h�4Rh�t��LaH\d�,�Ӏ"F�'aKDP��o�(�z� p�=��c��wd7b]Z�8p`�"2����X��:�"�ŋ��׃��'��H�����-2����s֯�{�/�Ǿh{�ThrĐ��!CT0b����/��b� ����� Ԝ[�9�>�(^���0a�tv�av؀ńQ1�So4�V�x� �E 253 | �Nl�n=��˜z�x�ϒ��Œ;�ؼ��Ѥ�$����. )����_$��1(��}�5$ӊE��P۔��&�~F̩��8���ޫ�`(1����E(ѻ��&�G"�T��¹|���b,i��(��(��1��8��W����0w#BS��GX��K�{_g�S�.�ф6��g?{i�֛���뷛��⥶�v=�vlTRa ���dځӖ�Ȕ 254 | ��\v��힁���U�U7V͋ ����*5}�$2��uC0w�҇A�å�ήC�v��E���L�SY��>{�4&���~�MjF %ۇt�_��O\�'�,}�%�l)��h� z�%ۺZ����y�I�F��]݂�Շ_�'���7~�U�) ��<2N(�;h-��P�q�]�aV%�?y�y�N���M�� ��َ��y[�{[�h�1r�#�}B+:>̮�ׅ�� �N �" 255 | �� ܖ����7A�q0������t�#I�$O*}~��������T��w���D�E� 7^� ���ٝ�#D�(�%��M�*�6X>$�@p^ ��� ��") zA��G���% b�>�>�T�^}��;� �O��ǘQ��;c-/ 256 | ^��#7w�Vt s&��G'*�-#�צ�����Q%��^M'p�c��"��-�W��+*m9z�LԎ�p�������힒�{ɑ]�}}��(�b��0}��;ax]����t�[)��Q��@��]�g�Д� ���vÉ7g�㮆�'fToJ�fȬ��"�R���ۚ�˫DŽ* 257 | S?u�=95�j�U�!9F�9��j.��4�p|��P�{wΔ���"Nz(m�W`���yخ����`Ű���Kf�?~F��m(ȑX�0���s�r���6��D#�P2 �='�����H���BL"�-0j�0d�NG����̏r�F=/�t��u�?�"J�u*���/�^]2Q.U�����ԩ�\��|�O�Y�w�/^����p�9�ߡ�%�Ԟ���v��%���( �-��FʋkB��e�Nk�=vuP37g����,�� �}��Q�įK L� ���Z��>��:M���N�⏆���/�"[I}II}{R…�w�u 258 | �R�_����Kn��x�RFmX`HS]��}G�ŝ�-g(�K�qA��M�"�����qpn� �8o|�5R�g�����1:?M 259 | �N��� 260 | <�/@����U=��x���oZ�N?䞧���m�Yq����o~Z�7�Z\�Cѝ���-�:�O����4��u����y�� ��=Q�  �W\A�F[%2|���� �BbE�6RM�|u������B)�~]�T� ��u:�L�*| <��YR-fgg}����L�b�u�}�aLW�W�ЈR��1a�%O0�<�;�,�A[w��*� X �'����!(�=��i��}��&?��#�^$ ^�2)�m4��sD��E|g�P�b�2�Dq>�����n.*�?�W̸x��(Ļ8�s�D���SD<\��"�5�3PsA90�7�@�R��� F�q 1x�od�YХ&���]�b�nʁ�db��zy�a(r�j�~���}@��8�� �� >���>4��J�.]���R��RŨ���� 2��*F 264 | A�6�r���]��eH}KK۔��J��ҡ�ObƆ�������L� 265 | G� hN'%+Sx�̒jU�,�V/�}�2�D5�NwY8�G���,�Je���A�h*c�幔‚�����wޡ�.���0���{D�x��Sf�Ѣ��2�w�$�F�-�:W�Y\���D,o�Iy�ך��nN�I�� �,i��)�m�#Y�Ǫ���j�U�-3���Y$v�%%3�Z��p��V򒲗.#�cNf.�5 ��d�$���C}���,�KSצIX�$fX�͊D��M�^uV�J�0R���s0=t�@k�T�o��RZ$��b�X��*e�V�E��W��ϕ�5��T0��T��nk���ޑ 266 | ��7&�$2�iy�ThF7�����u�bqe��y�#l�R�*[)I������M��k\���a�#��u[�N^��3Vq�אnL��(v�\���f�T�GQ�I7p��=3?��קw�(sn�Y�IS��M�g''g���aFm�L*1��J�J�2U,��O����}}���]�&k9-��D�����i-%�}jS*0������XX���W��b%��c��R�LR)��$M�����NK�,N����c�إ�Udf��I��$�D�Ģ�*$R�� f�LM�Mu�LձK�7�)lJeh�Z%�V1՛ 267 | �ڒS��.u��4e��l�J=�RS�j>��r�l��ڮ��b���4����%ǎ-Y ]�#�,E�J� ���؈�]?��S�gz-K���=��:�b������+ 4�A|h��FCR�(��"���F'ch�)���= 268 | Ejj�����R��7�﫧��W*J�o��J����L2�lX�����B��a ��a��r���:���Z�cůM��?�'�-�V��� ���x��n� ���]m�P��Q�Y�� 5eS��0� ��Ư_?^�:w.rMP ToܞL"�ʛ_��b^��GS�7e�ZUd���� 270 | l�X�������>�ͧAGM1 ������0�B�ǖ�c(B�0lEguK P��pl 271 | G��»v��h[!A�9�v qo9����b\����#�}v�@�0�4>��� 272 | B4ZQ)�?ݘ�:>�u��X� vn�(��z�HE�~���Jń�s�(��7Pz� Xx��@�?n;����E)҃�4�E�J��ACuJ�yc>,Fu�U��i���Z: ^�����{��P?��cY�ոOB�k����3Xt�5�P��T�Er�ׁn�*~)pD��� ��M�0��;bMA�폨p�[인�ւ�� 4��]�Lv�ky��4a.�YB\��UE/5lbK2#M%P��J����vW�θ��n�p�����k����'`�@��ɴ�`iʌP�W��8Ġl�%�t� %ʌ�SQ~V����pj*���$�w��^#G���1i��6��}��"vw�"��b����zrMZښ�]�].����?+;�z�����#��#J����z������~:���vv��ۻ������$�����3�1�~e�����ݹ�+t��J�G;�I ���mW�y�ؤ�q�k�*�dƜ^VX_<:7''wtq}aY��a#�����TH� �3:��#C�y�V��Z�Wj��U֕�?��;A�Y|�.d�7�R]���&�ODh<*z@�� i݉Aw�N�A�%L 275 | @�v�I0�c���*�T����.3����9R[�VJЩ���,��՜�b��M1W�R �߫�>EƉ�N,� `õ����>U8�z����/{��2�3Y��h�확b��^�āpQ����{�/�RX��_߲d8Ȭ��6e;���зk�� }�B 276 | r�fq� � �Hˠf�ŬD �ζ��%�,�Ĭ��m 277 | ?sx\��j\�W�W�UqC�S�~����m�lY��3M�>�q�������s3`ػo���SL�4.\剶�jl��u�[��I��77쵥�������������S4�m3�23��ȧ�ꑳ�����lg���@�� ͢��؏1��W��%`T�;�����ω� 278 | �ExC�t�#�8*g��3�0Gx{�!w>滢x�i$�pl�ɣ�` ;f��7kA����fy���h�3>>��G�U�4V��O-����H�M֌o�K����<'���)m��?�� ��%�{[2p������;��>κ��K���>�e}��}����ڸ�0�D���2`�TIH�nP(�A!6�Ƣ��2�h��k}�U�3��Y��ެș�t#d}s��|����'��s�|�\�P_���ξGփ�$��į8;���Bh�Q�",Ƙ���{ 5�k'Z�Uָߚ8��~�)��A�^�R��-����-�.fG��W�ԋZ�G�E*�.F��zӘP��������.$-J�}�&��\�V��T�Tnv�������?a�/'�n��-{4�yʐ����`ʡ5���e�9<�4��e�U斕d�T��� U6��?��AX&�튨Řf�5?M���A����6�eb�$�d��`�t��%Q��p3�`��s�b3��N����n�MSp��U�5�G [�6C�n���q���Ҁ� �0y��"�U�(t�K\�SR�*1�S$AW~��g�S��v���t�QR[������ ��%�������Z��ԛg��X�o���3c(|�:c�(����s�V�l��`� n�����Hz���*_��~�uz�P5���X"�ݫ�~P���]����#jDy���%K�j� �$��-v!��F�~3�2ܪQ�5`.|�ap���>nw���/y��#?X�##J�w�5��( 285 | �����Nx�4슩q�V���^������=~�R�'Ҫe,�ҧX����M�}�j�J-�)T�:�א��w�3r�T�'������x�}scF�y��7k� 286 | �V0�\���S�M�(�2@��u�:-YzǮS8���W���[4;0���q��Ʒr6�SBIX��qL���t&t�&��#M� �����G�#�&t ڠ�4�7�0݆���I���p�X2���M Lu��w��Do2�` 287 | �%\��7߳��g� 288 | ^mlm�W�)s�X��7a�o`B���f�b�nQ��1J�)�?F�T�7ѣ���;��C6���XV}EBq��:��ٗ�zh��W���*S/�'��W 289 | I��~F,��앀� �Ud� �A:�ɫ�+�z:�b��4'�Ŵ���؉�szk��ܮ�.08q/8���k�Y��H���E��>��Qv��ŋ����g�O�~aժ ��b��x.��쨽���'��T�Y�&7(�w^;������[�Ս��$�\0w/��6p'�"�>@��'�w.XHZɋ����(���j�����X��yc\X���{'Dy�>z-�z�x�y�>xm˔���ۜS���^��O]Ђ���{��E�&`��`�w)�+��ySL��>c���u�a=$+�h)V,��7�R�H�֯a=�U���<��35@f���F��9N��i@6�݅�L�D�Q�s��-�cr�졂 z ��� 290 | ��W^׏�~���чS�2���5�$��Z}�݊#q~��d{VF^�ުԚY��l�&'��Jk~O�� �V���{��W��|šG&�$��d�]���8���/�v�Dj��&����7��x��Ҥ�U떦���ʐ3� ��{W��(1�O-����T���}2�����k@N�H�:e �i|�}�,N���j��$}^�\�����X��,_+V�r{-���s�v�7d/�zk�ux�C4�9�9/���%���V���<��S���[ƅ�����ٷ��_��:<�}3�^;[��l�z��A�)���d���}����-���U��������}�����sQ������H���:�z��3 291 | \D��_�+B��3F� xh�&��>����ϕ����4�]� ����j3�=/�#���T�Q��c�ϱͫH��Bw� �_��Ee�^f�[�џ�3�� �76N3�w���\�"�R���1��v�/}}�"�O{<��Z���@!�g�(��E��= 292 | 5�uW� ���n��&�iK�$j!�jw%P<��T�<�N=���Q��Z�UA�nŀ82�+�^Ra>?�1 �E>��9�|�.�mV� � 293 | 40 ����l����K�҇k�|2A?���g��`��f.�}�W�F�\���[XQ:�J1�D��~�NN�*(|C^�&�@���G���j��1:�;kN�\� 0�ƅf�Ө��p?����$��0����o�G�G�߽�0���Cは/�������z������F�4X�~�d�IE���[��.�����9љw�I����`� 샧�'�a�����b��$~�+�/�m��`��.-�� Q�b��'͛�"+6�XJ̓n+�fA0�����H+�l�_��sʴ��!�-Td�ؿ�O����dɜiL�j�����N�q��J��ɘe����O�;;%G�'o����;"),=�K�� 295 | �][��� g<�F�h�.��~�[�?� u��}r�����f�2h^�3���s�j��ƾ���5��q0f� 8���u�Ĕ�,'���5�D�k��)@ ?\��a��^�=M��Z_1�&����c���M�Ͳ�k���׏��>��|���M�o<�< 296 | ���4/�c遷�<�l�ٛ��,�v�߾={{��5���Y�{~�'��= ,�\k����^&�'0�tX���Dl}�F��G*��QT?���.�ZۂK� 297 | �u-Z���Rhu���0 ��!$7@d~X��ɢŎ���xx��+x����4����V^�Vu��P��i�f ���w�z��9i�{V<� �ї�Kw��#=��`�������~ёޏ��_���ф3,1&W->�xj��~����ܱj��a>�t�x�k���la^�3�qn��i�i�З�1M��Ɏ�H�͌�و������ KQ�j�1$a�g2g#��K|�!�y�eD��Q�Lx�X��{i�4�{{V�����N��l� ��Ѩr��|�_I�G�$iu,���N�?TW�߂bt*x������A��u���t�A�Տ�7���Ѐ �\84�d��ه&��I~�Xsu��l����0eZ��~�rsUJ�kG���� 298 | )�2S~�m���Vy��n#�~�c�hV��A+�c%�YY�� Z!���W1������t���A�1y51�+A�E��8���ICo.��V�3��[ '��1�;��S�v2Q��:p�ؽ{�/f��b/�����vܽ1��l��^:����f����������y%�����6?a2Gy������8�r�mng�ô��0.�ׂ~�X�nj����cpD1�N70%��p{��� �UWܥ�҄�oS�(آ � �v-6=�C=s"�n��"^�D�͐8'��ݿ�� �ڊE�BTPAE��U!�DwU�I�O�e��p$�F���Zo��|놪��'܈s!}��q�"T���P��d�����(le��+����� 299 | V���W^�Dl�Y��s��:�a�����h�I�`�X��k�����Uq&HI�R�&� 300 | �����5 �R � �r#�F������-���M����>/?�}�D��Le��J�����{L��'����:�y��!��=l��g�w��K�sC�8��3�j�wV˩}.� ����'v 301 | c���U� ���Q)I�{W��-Ly�}0W�_훰���S%� ���� YIV١g�D��7�;���;Z�X�4vh��H��;��n}5���>J1�3��U!�P�3�xd��}�?1mډ��w����E��R`*�A �36��?M~h����Ix�Y= 2��8L��q,�6�h=΅��P�t����{k0f���7?��rF��R�����8`�vG<����ؔk TzgL+V����aL�wp 302 | �#� 303 | ��&�ɼS,Y�~>��o~3b��!w�cE.�� k����,��)���O��>�������e �1z<���g�T%5"����<��aIŽRZ�P3C�y(�Q��0SrO�� yI#l�YeRivff�T*M��I$E���F�"}�� Z�2j�,}2x 304 | k:ح ����~�(����a�� 305 | �/P���{���7w3��߮��l�g������J�-8���h�|���W��yw��?���W�m���x���@�_�~�>��� �V*1�����'�_�n��F�BQ���X 306 | �!�I'��P��!q`3�Q���ltS���tb‚����� ���/��<�;ɖ��?��&%�yD,eOp8jb�>�� 307 | �@T�����ᄊc�η歿Z��y��w~?��z����E���g�Z��sq �s��n��ݴŖ'���2��;������͹�����G�z�,>���#Q�Q��?_���bN��Ɇ���Ӎ����i���v��njj��~���w`�GS�^`�=�O3c��M#�!��ȧt�xۄ��~������.k:��D!�,茮�?�:�A���t�$6p9�*�> bi(�[�nϠ�A#�鰺I��h*~��[��Dqt珓�j`���my.� ��7���e5/����6u�_T BXa ��?��-t :������U��fr�4R�J��J��o��E-���-j��#髳,��*v����>�&�$Q?㰗.;Q���� ]'��׬=f͚S�'� ��3rx�W�˯�f8�{����)VLo0�床��|`��;& ޱ~Riqì�^OMN�T�u�G��:���I.A���R(��_�M����o�=p��Nt�M�j�7���#�~��s��&#�K( �=q0:]��p�N�8D�G^>��HY4���׻�]�F�#�� 312 | ÷,F��h�L��u�O�'zܴ��%���*����cvv�d E��lg���:�1h�r3�5kg��Fa�t�u~��ˆ�����m�>џ�z�9q�L�I)U��<�g�x� 313 | _�ifm����љ �`��.���l��8 �s��dg����鶍yX�Wx�6ݴ �e}�ư_("�/�[0:�ӻ��އ��6:� ��l�6%��P�,4��� 314 | P8�u��,:��N/6�Ƿ�7����.A�ߎ��gd 6{�r0x���؋LF"\b�6(����%D��"`�F��v�p�g!b` �_ ��J*eK83|q(�Ԧ�J���>W�����R��!&)A��|r�*�2��H�8���%ݠ�Je[|MojP?�C[�8����ra�9�3{c��bqo�5&��0� 315 | 4���%�e��ٳw���<<�`��� [�S7�߇�?�����C��Ӟ�̶�{"��yP�����n����)�hAc���W�z���Z*����y�b.u��rܚ�[�%Xq��Ꮳ605����n���'N�y'ND����~ ^���%s�%��藂]ML� �c��B��uJ�D�O��_D~��_�8��;U�\W��#'��s�o���MgC=P���9���NWǐ�u0-�ת׶�Nn�k9tz9M�F̍��(�"���QIS�?��E�@!&O�"��>H@!�����}Z%? �����?� ��q�x�6r�D.�L0"��*r �8"���GO5E7�� 9���?Е)A�ֆ��u)�~Q}@l���� Lrz�\�'��I���,�\z�ӷy���M��ڞ�0�`�����V�+����έxFGO�_�C?ҭm� �2h0���~����|l��C��l�q槇�L?����d�n��O�u���D��`�mp�t����GD������Vf�롷G3�H�� >F`��h㖋mp��M6�\.f/�ђ�E8��� :|12ؑ92�^ 316 | ����ԍ5k F?��p�A�� ��Иwd�<� ����w=6���J��@l�^�������}SCG�mr��� ����f��%[ϧg�����i��\ �[�x�����,�ރ u ��*�Ժ�0: |W�l�rJ��i���6���}�w �,�i2�ִ�i& ׈��y|�[��I�0�������C�^ym�r򑯎�i���&�"H����m$��ۖOv���y�x��t)�^��F��( 317 | �buroQ ���i7��c#����R�s��M��a�v���)����)f�DjL�(s�b�&[��s��d�Tb1��s_7�牀��:�U�������_��UX ��/ϭXqX@ ��Й[�F���AQJq��#?������)��ߺ|�V}+-H6���a�Gt��S�x�Yq~�ㅰ�Vjh��W#��r���#1�!���w�48Q{�n/��������i=( 318 | �U�-�z�FnU5�˖g���R�qw`�c���4�����g�e����j+�6C��9 e�in�33�Ѭ1[w���c�⭽�ҿ�ˏ^�.L�\�x��K��1m��s��\�rG���U5�^4�Z��!�Oѷz�h3Φ���w��ye��ƹ;�R=}�&��z���(��6�It���} |������ZieݲNˇdK��ۊ�8�'�slj��� 9I�!���R �j�p�%�p�%�H�Z�޶�(���h���ʎ�Ҿ���~ߗX;;�������<���<�4�kA`��6KTV2�^4���"��?K/�A��nyܵE!��JbG��*/����J�Z�X���?���3ҹO�;��OCBp�`����D8o�r[Lf����5��~���V;�������>Qq�����J������D>�C\K7���]�A-�a�oy�@] " ;�v�sHH��'����&����!�zX��X5���g�ԞNpCM�N���14�^4���x��F���~Fe2��1����)�^p?�#fJZRԙ���1]�����顕j3�R�%��i5��!���̐�?�������B{��WJ-�sv���a����{>� Zi�9O?��W�������'+�Ӽ�Q� J0]z�L�BVQ= > �J�}FS*)ƉFZ5�˨Vj� �p4����]��!n s��Ds4���3�Q:�pӞ#� 319 | ���'��N%;g_��=� �.�2I_Y-,V��H���>{L�Bg6��ep�;k��J���W��"u.#| 320 | ��]H�������(Pڰ��������F�����t�oQ���,�V�XST�fA�ápuN�\[;o�������l��BME��hZ���ة>g �6 %�ؑY�$h�0g��gyX$�^�T���D�V��Å� �b��$R�rIh���;�,J�>`���i9�� P�*N����J���}�׌����.G��Be���i:㳙���CB0�1�Z[-O�L��|9���uG�̘1G�\~��;�]k�L�C�S�Y��bz� ɪ�:���Q��R�����n���NH_�X�>�����҇B�B�)�,l}�U�1ƙ[ jV�]Ҥ]/��?�ϝ8i ��~%���I7モ����l�4U��b��5��˨5��Q7Sߣ�;{��ȅ0N��|�v4�-�]������$������e�q�����2\Ni�%b�d�.�3�]��@�8m@�n�|7��\9+�إ2�9�e�9���?�G-���n@�@��R�H���T�lI[���RV w=b�C������A9MVꐗ#�bPƝ� ���&�b��f.A���@�c5I����ؚ �=����>,�/�eM|ဌ����b7dI~Ќ��Ӧ^���@�5p��|��n��`LZ�A�Ŧ���*�C���}d��.y��<5P��U=kR,��5D��«2 +g�/ G�3�2� 321 | �S�}r ���.q���nƬ�(^��*p���ٍ���9=\�<����,�Q?"�|��p�)�+F�kr��x���o>.�����|4߅�A��d 322 | )S:�ƦI|*���Έ�� q�Gs�6;^O�~+r.�uD� �뻐�%WC���A�QTیu��ր�W�3��e�gչ+��H��D)����)0:&��p �L� N��t��~�N��m���yF�yOs�[ 323 | ���`\k���y;�h_���e��0�@�.ӿx�9�? f`�/�Z^����}�W�BHR��o7z�`��@�Q�4��Άб�����L��w�l_7�^=t�=�SU���Z7HGq���g�E�G�J}9�R��c�jB<�T��M��B�>=)Ĝl 324 | #=�v�~�����x�q�vwo������D��k(���k��.� �@���@ºk!��}��!��HZ;wg_8�}V��ܯ�pt��>���׵>x4G�;r�>�p<8"���d4\:~F�B���/�P�Gb�fU�ޓ��J�i8�ۆݹ��uM�5|35��.a��xn�o��X�0f�1K��������4?��szRG|���{G�gjC��B��*���:����m�6H�}�W�u{ˁ�6���֒B��-�yC=�Jۼ�;&[8��ի���4�|r�q^��9������pH�/U�`mP<=�c�x�O����A����X^�kC��]M�I��h'����P?�Lq�A�C�`�S6ħR�_�h fA ��tL2�jX�BZ����`�͘�p��iDl��JA�Lx�f�ˮ����Ѻ���������ԘUА1� ���3�CO�9�Ka��|�{۾��T���z�%��E"˫T*��7C�xvi2V�d�9'�a=�z�ˣ�VI���x��F���:��x-� �i 325 | !p����;�m/�Y���p|x(��~���B%��W��~�FA)�1S�~�����?E4����=K�R���0j*^F�R0*9GH�g �PR� �Ar��X㲁�xk ҽ��쯎����[��q���-E%�C!P �L�4"�z��ڲ��\̛���_�L�#e"�ք���D�WT�SҁP)ǥ��� `�Uo~گ�9,O�`g ��^O��&����W��K5�0��<�0�Ħ�����������]o�G���p� ���+��� 326 | *��H��EL��� �b�5�pd�L�_Rӥ�J`wD��c�C�l �� <�lV�s'`a�bpH���������؃���Y��" ⺽�~p��.��|�T0�?�(�CҌ��Y��d�T�c���ؙ�kMC�ba�2x�GM�x��ؚ��6�HF"�"���v G�h��]~l�K���$n(L�bn$E�-��ѐ�po��aT��3�'�f��r�I�a�l���4�;�%�Ն���WE��Qj�+i�"\�6�u�2 O�����,�G�>n�%-u�'�w8_iJ�qX�����l0kD��>��%����K�>��g���g^Қ�(a ��󬬔���H���΂�l#�*�~������)���e�,�3L]�,�.p��`v:�W62|����]�����ţ��^J+���q�XrJ�Ű�/�a��b� 327 | ��`�ݰZ�<��TVb�;o�ßv������ ^���Ї�@�IoCe�W���\�c7 /����-��dǶ�.���}���.GK�w�����������e����O?}pr�60�����l�zo���v���>|�t�y�ֵ��B׭�Tup���m_��%�m�z�c���NE�(�O�D}�˹ �8%ٛ� �/V���a�M�r��8NJ �,�3R,����w_V^�Xk����� ��a���'VZ,��CL{�TpU"2vh{^�scS�*1�b#�O�QCm�xf����.{@(*��Fz孷A6/V����f����p���'�wG��`�)gI� %[� ?�hN�}��Do.�ۇ�̡c��ܴ�m}��J'cy�� � 328 | ��*2u��=/6�u��X8h��k ll��eT��ŏ���P�7h:�xX�hxQƯKh :����a׈�~RF����% 329 | 6�.����x��0����F�s�u.V��l��t���Oa.`Epv�:���V�v����q�dE&�;HpYs�`P�k��3��$7�L�X�ʎ&�x9ݾ��J�R�35�\���zMp�hg��>�0[��Ġ�[����JN�M�y����F�Y�������ԏ�O�� f�N�ȼ���믨Z��w��b!��;;��kԜ�9_]Բ�?R�pD�,�V��]�Z�n �6yA;S���k�����Wi`���� ��@]�!t�e�Km&N��̈� tpT� ڄ�?D��!~mR��+�u���& �Z�9"�O� 330 | "��FB�M&�A �J&�PD��zP_�N"��ce��`���:P��K�'�  `. 331 | c Y�D��D��g��:1�Jj��rQ�U ��yH�"6_zH���7c� �aO��2�i�s+�����sz�Dm���^��uK~� 332 | ���I�\J ��lذ����S�G�8ӧQW}���{��J����ޠ��9Q-r�y�!pF}F�KA P�}%#��2m�W�2�cMK~??X͈g�f�63F�{��/��C�xU���~hx���_�D���0 D/�(�g�[���~����=�jG�օF�t�Z���.;�NX8�)˞9�3Dk��k��pHα�6���A ���#}�w�{{�N��ޚ�@�gDvYv��,[��a�%���ģ5� �;�nP��s�;sZ(x�pѐ���+�� u�G4�߇s�����>=%�s8V�o~��Q:Ot?����5'��f=tg�t�%���_���4�-�9� ��\��G�p�Oϒ�E��7�s�0H��u�L�c�W��@B��T�]��n�����yK���fm-���1�����V�|���u+�f�Ï��'�����7��6g#�w����v��7�� /������F�)ˇ/��N����w�'�gH���\��Ǩ^_�9]>3�O�P�h4\J��n��x���I���A4�]:2�p97�i4T�z��YS��FMa,�qXK����AJ��9%��+dDF���������ر��DBF�t(LF_2��d���u"�ၝ���E9����*���D\���5����A�5�Ќ����o��a��Zwm�ۛF��^w��L��ꛆ��S��c�X6K+5gff�g��U�ߛ�vK��sn��1Qδ��ƚ*�L'S]�+ �~��)�WOK%W ��'�-�3� Y�P- 333 | Vh�U�<�į����V�-"��aO��_�����*��}3n���Ƚ�]\���g����=tr�� ?|���[s*������Z9�� �7ݶ�wͥ�p|��xb�h�d�}����-��P�*�vsӋ+�I�4d���ʢ�|ciS;<�|��ʊ����}帤�F�9}4d^v ��dy֨��A������2�� 334 | -�d8ߒ�S���80De�D���o�[�Ā=��9i�o4�g�pìi5�߾������L^�d)�L�X�&�s���7�ts���X��5KI�Ճ�<7s�e���ajE�o��9'��F^1#� �L9�����>�k��G��Y�ܝ�f�^L�MR_g����S��du��v�mySgOOg�r[S�FL����������8��J�FQ�x 335 | u6ʆe��z��>z�7Ʊ����1ɰ]5��Cքя�ҡLؤMf)7�&\ Cʓ'ky�D�=X!.�M�Xuutpsر��^o��S�*�qT�8�l{%�zT� 336 | �TOmػ��j:�D.[>*V���Rn�BU~Q����{ڞ�y�&W���(�Z�� ɮ�v�k�: (R,P���(������ 5�\��T:%�E���5�� k2�U�::f�g�R���޳�!Г�d8m�/S�����t=���Z `���I��;�B����������VUaft���e������� �0)/p��������!cU����JƧ7ŀ=d���!]�3iu�+*4ƀ��3��s$\�(��R�g ��E��������m�p���X7��y���LC�ZQgin^�Rvzi{U{|*�����͖:�:�+�w�iEHaW�q9�U���u�O�Q�Q����=>���mLi��\�@���W�icU��u����`��̶��V^eL����?�U��IT�ch|58��rTVRmS��TQ�+Ř�~��cՎ%p����������"�覫!V��S�`D/��\d������߄[ �Vy!��UE��d…�[�[F�ص�¨�A�C���V<4����m,�i���)C;�w���f��\�N����r�������+�K\ �֊�lm��N�����}W͠�޸���0Ӯr��a�#2u��SǼT���!z�؊�?����n���+�k�s��~�����W�V���_��W�w>ҁɅRS���I?�;�|Tɢqj5"#k U+�+A�14�r�F�t�y+IN�y�����0�MYcX������p���dW>��q++Zb�m�bilˊ]m`A� Z^�L���ޒ�|X�b"ku�~p�t8Bf�x>[�&�cf��0{ 337 | ����]�����3 �̟y~&�H�3P���|m][`7T�GY�rfn��,������k��f�x�/oK�_� �� ��*{����t����@������2��#g��=��/���{��Lg�5S?��(�lK?òc���!_0��3� �γ%�� � �ɰRO׎��- S������m �r��;��<� ���ɪ)��1X��ɫ��l� ̊%�"a ��� ΘG՞���v'b�X�����Z���ȝ�܉�������l� fm�"&�}GPX9{ΰ&ߐ�R��asfW��1�^|���q�4���t��؍�Dӻ'w��'�wTRE�dj���i����}�GU7�c.�.}�!.zs�Em��j��1��ݐ=�0Z�,S��qK�+��J,q����&ʹ�V� 338 | �)A{���0�7�Ы.B�,=�1yd�q޼��΅mIƣ�*�?���� 2�|��*�0����V�B'G!�$�h�B��Va{�(�H���e��Rz�q�#.O��b��{�o�2E�+�RGqaaa����l��ZR�J���-[~�����[�ٗ��V�-T��l"���C"�,zw0�gѬJƩ7+�f������g<�Džo�����*p���RG�oҟ&���%c^�~[�$��[⑩.wػ�<�G�wą�u  ���a���D�Z.n����&E�uF����C~����L_��3��ϐ��v�5䙾���/�\�!��� ̫zB���kh�y�8!�� ��G��JR�^ό�*�_���4>��S�k6� A ��\��6��n�Lz��#��UC�ر-�Ww����a �HI�I?�� �� �2P���j�&����%v �sh1[M ћ��r����%݈$wH���d��~A�����7�ś? Wa�º�G~�*|�M�����^��nY�R���o^�zz�j=��#[ۀC^�W��b�H�Ro�0� sd�y46~ZC��7�{�Ɨ�����sݳǟ�n �8d]�I��U��֝{6N���Jgnys�]���7��,�m�9�F7�� ���|s�湟3�i/�峹7���fe 6ʏ�z��&1>�+a��K;��i� 339 | c*��k�پ��m۞Ρѕ���s��0���HzBτ =�gW��V�OR>����#9��~��Vs#�y� �nIUM�R��<��}H$���ո��6����K��.^�P������}M�̓�X�O__ ,��!�0�r��I���]��^�H@���L�d���\LӤ�����)5mb<��O��J����D�F:ya�������/,%�׿���v�#�!�oS���� ؋��Kn��biBq}����c�׈丣���&�v龖�V�^p���%�Bڹ�L�YL��LH|��F��N� ��F� ;9d��3Y� o�#A����b玲I$^9J ^�o�����Z*E_�|D$�_��k56�����2�Ʃ��Lmȟ�x����m��n_�ɱ;'�.6���~�ģJ�%�E�g�/�E5�E.Ì��sn��8ڗv �t���Dx�r������礟/j��;�QR�nʋ$�;��O�6�^G ��Ez���Y���g��&��UuB�����W����Y{o���3A����c5�Y�Y"q�.��SF�/��Meg�H����4��N�^��3��\�m:���������.��z��69lP�P�i}���Vi�D����Ty��7`�k�(�\fs9�H�&Rv�Pi�*��@�h^ ߼N�5�kpW�V>IV-��ZP+�B�3�5p�%��oN�����ਟ�q��o��D� 6q�+���uVh�Y�ᔅ��ё�BVӊ���*��b� K���h�.8���̲�6���_�^�d�dy�ԠԘ]B"ђ)���,��i��37�ܿM:�_��i��~�X�@����,�-�Ѭ��,}�pa���<2� ���8����<�|{����ޝʰ��~�Ő�;,j^-�@��d.��=���4�cj�� 340 | u 341 | V%]��8���})��Ϸ���$'*���K�� �X1��l8HH̛J����41��E!gy��,�U=U�=M5账��z�GV��!�=G�?l�^3�B_n�evM����IY�dkۖg����5��:�ñl�fp�l\C l���;�>��m�����J������_�����$�\������?�7��wj=zŊ��q� }Lx� {�o�FQ�.j.��ZM]Im�n�vQ{e���W`�el�|cΑJJ�b�L�sI���R���0)����-���� 342 | �;U��M*��C�*.T��]��<��� �z��]ʗu��@V��ޗSޕ5����3J'�Grd �)��,���ꁪaWw�iְ] �"Fs�-aאb�J:D�r�1I�����'.J ]��-[�|����:�j�6"y�F�vju/��c�Y���x��|�P�/���A�ޡ\(��.�]V��H���!��O6q���r�����q�Gv�X?$K ���q3̘�&����丣߹|d:dnI&�.���B�Zz�b@� &�[1�㹞��~�_��OG�>����բ��h��^��Q�|��w4]���`��]��w`増��s��^toǿL��ψu)VB�l�N��u�x$�V� �6�����}y�q�c�<$^�G�VM�)$���U�e_y�[��ń�$�`xK)J�_Sn@�6z�D霘�1���-��=F]` P�{����7�>0����!Mz�m��)��?���������7?�y����i 343 | ��XyUUê�Vl9�U5Q�y,4(�/��5\}�?o�&,{w�)3�]:�~@}.m�@k��&�^I��'%���ŏ�q���i�%O�(5L��A١���z�j�q�� ~�������q 344 | U�@�J��X�� ��g[��_�RE�J�rb����r�ֿ�|��v���� �e4L�E�Cލ��f ?��_^r9�-R��7~��'�rfna����@S4�S`�@4z��9� ��Me�`(x$������ �[vrQ��� 345 | �p������ 346 | AW�_v����.L��1@!��Cd/;)̡�X��?x��{;T��?V�v�a�vՠ8������m�rqF�ߦt����>��_�A��?���P5(~N{�'\:o_\z���ʬ�c<�% �}[��J�5��<<� ��_����yR6$��k�j�~F���Lt���ɦq�N���DrÄ{��� ����x!E��:��0���r ��D�8���ҡ��hWaY[�p���q.�p�Qr�Fv: 347 | �:&!=Q�Ί�PXǠ&e":�آ}0���hԺ�A���� 348 | oU�{��6����:��+D�޷3�2-m�y���,ͿH[�>�`�P�P���tQ�Z8�f����� :g�A Q�V�*)�Bȃ��&����1�^o)*� ��k�V�y,Z��/X��V˸E���J?m��N+���g�jGl�����ч| }���kC_��s&`4��l�-�B!�W;�ZmH���5��ƿ�+qJ�(�l�9��@ gQY��9O2�]:�jXڠUPRb��Ty�q[T|�,1�%�g2�WZ�B�����bh����u�aI,�{b�A�1٪D�P놜�z�|$X>�t��B������wʞ�N���j�a��Nn��6~, ��Kڠ��uX�h�}y=HЂ�h$�����A�T��g��wLa엪�͏�1a��x�r� �J���t�<��&5Q���)`���6/4M��%���go��oj, 349 | Z cM��Z����p����Lh��֩gGdW��a����75Ł"�֨VFm ���:jYh�ڴ�i����6�͛�q4e�Mݰn�1�Bt\�T1U�x�;$��1��H�kh�b�Ą�Џ��H��� �����1�S�[.�s�� �Kګ�d:�I����J����, �~�~=8�p�Ӭٻ�ddx�� &�%b�(�Ns�� 350 | �ZF�sE=����X��x�-9��FTx ʡ�6��u���sJ�n����Ԭ� xO*���(��^��F��fа4JH�۷����}wI�@-m���R�硢��'��,����(1&^�D 351 | +1��/������������J_�i�^F"������5<�M�ҍ�œ�KѾ���0�5J�@��c�����"f �j�W.Z�1�mҴ�m^�d������ oJ��)�m�[_s���E 352 | � � }�/�of��+�~��`P��]�q)��H����׾x�Ego��륾ᝁ F�i���� <���]4d+ �>�P0�c#ۜ�z�w/���]�=�s@+ܳ�<4���-���#�H�w�4�f�EEi�xk��!���+T�- m5�_Vq��&[�A)�f�����ӆ�5��,�(���>�,_mW�` 353 | Ђ���v��9t�͛ �Eo�s84*O��{����l�ӧo� ��LjF�/x^ý�����^��&�S�P8��>��A&���::�ف V�7C3�!D6d���!X�|y:E��_%7���gk]�&Tm�c���VO�#P_�3k�*�"��_�/�o>| ������������1�r�'���X>�ҧ�/��%�H���yӳ�>����Z�j4һ�T@h����n�u����/~��L�y�C�a��aU�4�Wi���@~�d���y��G������Z�qi�$ݥ9p�C�@����&�sr��<>K1�ѿK�;J�����D���,~�t����&�<��g��OvL���;^��I�C��J=��^FmB}d�C�,~�P�xG�2�?���XVD~��h"^�?�]n(5����2?�(8w�L�3�1��[H����E��l�7�?���+�G(����6}�[0�)��ư4 354 | �A�k߄b�؝��k�Ŋ��uX��U�#�)V����7Ń��D��e��t� [���ٙ�>�@����84�� �-9����Z�.n}:���Ε�z���#��dh�!�� ǥ����k�O[�:����!�]Y�) � 355 | �t��dO��r�����rv��P2�+�2�*T����EڄUj��PB�wK�Θ 356 | =�����|�Ǥ<��3��n魠*ڿ�fMh�s�X>W�gO����N'$�u7��tAұ�A�������q��h�͌̇��D0��'�*��&4�0< BXFF�V�}�o�q|���߻�Gg�^��ä�kש�G������NrJ��w��s`Ϗ���U�L��:��J���^�� ��c�k@�� }ߓ��M�$�?���t�^"�Y���S�N[yļ�+��]p}�L���FY>�HCA���qp��y��M?�x�� MzA��� �>Dm�7�r)y��蒾V�͍�������l�1ύ�"wm�_\s �ɬ�?�=OM�fR��5�U�C�� ԫ�{�G�����eHa[�y���� 357 | �=sD� R�U�W%Rd1�'�=�uR�(/_� �9�ַܺI�� 358 | �"�%����;�0��ݎ������b�+M���G`�p�\ �{��?sX΁R�K����V7��M3��y��>�� 359 | ��s���h�)wd���c�� �yt�\��̌m��7�x���5~ng��l4mp‰�Ѩ�!k ԣI�dBG�4CB�s�5C�OYb�jo���۰8=vMa�.��/l�n������M�q�f���J��,�i��a��s2�`0:�{�Y�),fs~v�A�t� �T��1����2?�+E1�V��h���cO=��B@����U� X��y$c9��h��� ����h�ׂU 360 | ��ׇL_�CAkHq�>� � �����yJ-���-?��I'��<��TJ#�2v��$d��1��h0 �Y!}=��n�b�J0�d��N݊�T�l_9V9��Jk����m���{\n.ӡ�>A�B0��f�s�f�X 361 | |,c�:��k;�u>Cv����F�ގ�sZL���W�T �x�c`d```a<=�|Ed<��Wnv�b|�F������� ��``b�d# �x�c`d``c�������8�"Ȁi+{ 362 | �x��VKkA�y�<��,�5VIL�,���E��� �"�E"�'sj�����J��U3U=ߴ��K>�����Փ��g�_��(�ET��u���=O�'{?�Law��]+t�w���^��nD.�}k��zՇ ���쯍U}ɩ�o9�:�΋���;����FШ����O��;��XS�B�[x���e#2U�o�ا�C��������??✼ 9�Xz{w�>� O3��E��*���De�[�=픖wE�:s�e�I5o�ÞR݇�G����=SB�P�s�|W�+�Ⱥ� ����}[0��l�]�1V�����~�ٴ�F�o����M���r������;�'�����O^gL���y�h�o������l7��/����ӌr�q3}=vC����C��HF=�ǡv�� �@�i�lr�.�r�4�C���үV����ldV¬�L�[�e��N���0WԿ�o�ϓ�iosW�wz:�z���Q��Y��Y��3���R�y��K �>?��+#�B����|�J���zj�����6�]@�UD-�P�v�>n໌u�;���W����O���MeFY�г���\�l@���*�!����u?�'�m������ �'��18 ���>�w��C�Ú\f�M��c}���~5���l���mo,.�}��Y��r�[�K����f\�y���B�G�y���o����C[����� ����|�E�E@ 363 | ����\}�d<�z��/� 364 | |�x���{T�g����N.��i�B�d�b!���3�i�M��e�$׹4��M�=�'4r���i�!�e�������������}Nҿ�1��H6dH��A�T8T*� 365 | �H�GJ%��K�^� ������2 RY����HY��Ryr*УB�Tq"(�*ѯ��T���D�S�Tu�T-�I����z �jp�E/�N��:�R]ɕW�� ��gKn�l7w��S�G�G�{�o�x���D��J�=é =���Ż7����,5�w�0@N386C�����&�9^5��;�J-�H~�i >��j�^+z���O��P�u/�/��w�R+�����=q��� �v@G�S�LLgr��� <����IR�B��]�<�1���ug�����fO|�E����_�P; �ap�K\?��G�������ǁ�\����Ti5��s܇�}8�A�p �O�?�������Ͽ���R� �Kr�Q'�s�?�YO�w���1��IN���0��EQ 366 | �S�9�?�'���0��i�O��do91�1��ٜ�X�Ų �X�b9�s�?��84�Q+����q>�_��:K�ຈ��L�����zK�[�w˘Y<����r4/G� 367 | f��+��*�$p�V�{"��r �kr���Z��u�1 nI���x���c�7�l��Fzmd���f��L�-�ڂ[9�[�L�6��i{�[�G 368 | �w�o:wSo3܇��j?�R镊���:�g& >��u�:��s�GXK�˟���Qt�����8�;����S�g�9�^г�o��/���/�� 370 | ͯX{]\Fe�l�)�H�X�L� �eJ� dJ9�8+eJ{Ȕ�*.-��o�x���2|@6�t�L%7@l�^�@���(��ce�E�T�q>%S��IN-��bυ����!�.�ꎔqeϕ��ʸ�ȸ�xP�!�Fލ��4�I2^ 2ެ7%��� w�i$��<���_�L+8�;�гu�L�X�-��@��2A<;��� @c'8��3�tAC�.3���=P&��p�(ۓ��1������o������ ���O��)2�� ye�e0ڇd� eN��d��gF�{ u�B��p��o��� �q�D��>�*3�� �s3������=��6��(���T~G�7�����7��L4���Y�C�ٜ�9��񜋮��z���]�����%�q ��� ϖ1��T���e�W�e}�(�=��dr��w���s�oWs�e \����迎�$�H�} nEc2�pϘ��o�����K�S 371 | }w�o����Z{�/��o?9��w*z�� ��% އ�a�a/�G�|���<�lO0��!����� ��r���Q&��<�/P3 \�w��D��p����ˆ� �n��܂�-���?�3u�>w�y��wᘋ��ɀ���u}�є��<��m�󐼇����O�~�p���)>���k�y�g���{ü�,��Ǜ��u���β�(Mx����jAƿݤMk�`�R��AD��ݴ��7�?�Mhb�W�6;I�&�av��k_@��+@���U�o'c�BMH�7g�������<��������d�E �,p?-QvZ^��S��J��r /�g��p�}oyw�/��x�����G��Y��:w�LƜl�e��>[.�1�[.b�q-�� u�y��זK�輵��mwfy����x�~������b�b�Ї��1BL I���vQ��� �K^��I��k��&���LŽ���D��0�fb����`0�(JfRMdD��I/��DK1�Z��`*�t�M��Ƭ d.�do<U���ڨ��U�ڴ��Mr�;�g�zpXm�k'�F�}���FUF��]�=j;௲��K��i"���bD�.x�B$�d��y�&��_j����Q�>��º\ՒO���-�9"Z��mW���j��\DI�滎��Sid�IΩ+�Щ�})��dG�»�2']�Z����J�Z��rl�$��;2��V���z���n�M�"�L4�R�+�_� ���e�k=��~^^8�����D�9�yW�y�1�E&��� ϋ�x�}Wt�ȲuU�b'X��̔ؖ�,O`����ݶ5�-� 0����̏��1�}�̰�����L��s~N�$ݾ�}oW))L��?����nJ]��.uc�ԭ�R��n�4d 9����0�� �� 372 | X �ư l 373 | ���l [�ְ � ���`{�v��`g�v��`w����`o���1����P� ���`8���`8V�L� �¡pG��p ���p'��p� ���p�g��p� ���P����zj4�Fj�-hClX ]p�}p��5�C!D0���· �B�.�K�R� .�+�J� 374 | ��k�Z����F� n�[�V� n�;�N� �{�^���Ax�G�Qx �'�Ix 375 | ��g�Yx���Ex ^�W�Ux3�� 376 | o���;���.x7�� ������!�0�������� �$| 377 | > ���������"�_�/�W��5�:|� ߂o�w��=�>�~?��O��3�9�~ ��_�o���~�?Ÿ����+� ���¿����/��0��b�p X�a�Q\��q�čpc�7��ps��ĭpk�߄��v�=�;�N�3�n�;�{�^�7����c �XAM��N�~�?��Ax0��p 378 | �qg�P< �#�H< 379 | ��c�X<���D<)�:����x��g��x����X����:6�� 380 | [��ڸ��`�袇k��C�p�qq-����x^���x^�W��x^���x^�7��xތ��xގw��xލ��xޏ���>����>�O���>����>�/��������f| �߆o�w�;�]�n|�߇����C�a| ?�ŏ����I�~?������� �E|��_Ư�W�k�u�~������w�{�}���?Ɵ�O�g�s�������o� �����?��/�W��������?�_JQ�2���i� 381 | T�a�QZF�i���hcڄ6��hsڂ���hkچ�D��v�=�@;�N�3�B��n�;�A{�^�7�C���S��T!�L��M�~�?@�At0B�h��i�f�P:��#�H:���c�X:����D:�N�S�T:�N�3�L:�Φs�\��ydQ��$E-jS�lZM]r�G}rɣ5�S@!E4G�@���Χ �B��.�K�R��.�+�J����k�Z�����F��n�[�V��n�;�N���{�^����Az��G�Qz��'�Iz���g�Yz����Ez�^�W�����cA�v#(�ot�?��S���tZ~A���y�b: 382 | ��n�N/vj������� D���UϝS���۫��|\�QHn�� �v�r��3�o�t���<Ϧj��C��Ҿk5���|�� ��l�I���uw��9�b�a� G1���0竖��N^�O踍n��X�o��uܾ 383 | 384 | s��T��S�M!���ˮ�nS��V\Sh�������Kѳ�n���~�mX=�[������ڡ�؍b��ZG��NX���v3��Y�_sT+N� ��_L:��>��WGAh�Ӳ���o�{ N��wG[VCɩ���rs��#_e=�o�N�gy5Y��VS&��u��f���L����D�� T^�n5���iY|��^~�Hˡg<�M��p�\��e|8~}Љgҝ�Z��0���n��A'��DAM�Q��}�,&&��9��#k"�G�8� ��������T?�ሆ%�b`�*ԭ��i��;���4�U�v���#�#�r{���"����g9�r��p���nY��b�)��w�Wy��Fc5���p�@ ���~;~=���W���~���o��\���X�l�j�UX�W�;GY�=�W*�{�L�� ;�b*?!+�,a�^���C�W�~����l_�b���$��C�er�b2�}�N_crߥ�ZL�m�z��H؉z���*�L�d���I�rZ�8�$1%'�r�q�~�͙e΋�ok�o��9l��qB�~�ɽ�b�m3C=�A�&��p�c�'D��˛t � ��p~��l2s6�K )�����7��4�R�����r�bC����B�e��\܊�dDdE���zG��`$�`�C��!H����Uv��;�ɄV� �Qy3Cu�V����87�'���F^Z�2���ٺ�8BP# 385 | YJ�O��b��^:��TAΧVg�v�q��~��A����]vx�vg(����PwT��k78�G�������;�����y7�b@q�@�5T�>s�;�'M��I#��I3>+�7��A:p}��=�[|y�-N*��y�.���orJ���qQ�Y�X;�(�C�k�8����>koqD�Wpd5�E=�q�un����k� 6�t��$��z�"cÎ��|١(�S c���J)�0.Geɔq:�-�#���� �$� Y=f�� ���f��-Y��V�t�y�����XK�h�Q]�ԗ����H� ���e_����`~�(�5�TA��Fֱ<�b���=�.��o��w�š� ��I3љw���f�w3���ł|0˗��8 - ��/�Ona�. �%�e�/$��է�����<���0�"/���h܈C ����3��e9i�b�į9���;�8�$�"���G�!�H��J�aW�k��dqIf)�H���Ƕ��I�_�({�ڵrv�j(N�2����f-�����i�M����j�&�Pd>Q����ij�hr���&|���`D��C����� {��nA9���YH��61G&Ύ��m/��% iź�A�J��c���O��� �wt��C�����ŗ^l�4b�&��ψ8��W�V/��g��|�%�%Y����]%�Ԯ{M��>��ɏ����6�3Y �����8Tcx��7�V.M�\7r8�G� 386 | 6��C����p�WlЋcS�\�Ha /r6��z#��^`����ޑ��5�,�Q�!�����������^��ߴ]��&�����h�����#���*Z�L�>K�,�G�ҧ��K�����\w>��5�]���-�2��䖠��qRs#?X�b�9�Vq�-ˎJK! <�= 387 | "��4s�ύ=���q���Wv�����/TK���k���Xe�dI���$9G��M7\�@�&���S��J�5����H��⁚+C%)�R�V��U)&���E}���Uc|��8�L 388 | h�,]M 389 | hR@����d�V�ui��(KQIf���)EU� )4>&�<и��+RRb\��k�ӵ�J�+ �$���J�+ �$��0���,�� ʂ(���� g�u�!в��1tm�Z&��a�kEX+��V4tV� !6dZC@�� 2dȐ���0a 390 | ����zh�L@f�ϻ?PUTTPUT��*4US^nHKh���Ą ��EE|Q_T��EE|Q�Ĥ &!��L 391 | b��n�b�܊BLa�)���$EY����U)&����)��K2�!�0��X�Kb C,a� IIHJ�3bC�`� 1�!f0� ���3bC�`� _FYeA�!0ʂ��"�� DzC�7DzC�7DzC�7*�0!���!���!���!���!���!���!�� LA��)S,z��.��sK"�!�UAT!�"�!�"�!�"�!�"�!�"�!�"�!�"�!�"�1)��DC"����JU۴41�kƙ"�)қ:�& ]�2X�bB 392 | �3�K��o����o����o����o����o����o����o����o����o��f)���Uz���u]�uY�z���RW����zB׃�V�zJ�Ӻ���lROi�)�;�y�4��ҼS�wJ�Ni�)�;�y�4��ҼS�W�Ҵ�ּӚwZ�Nk�i�;�y�5��ּӚwZ�Nk�iͫckI��Ҍ�Ѽ3�WGؒ����;�yg4��Ѽ3�wF��h�Y�;�yg5��ռ��wV�ΊS&5�&�դ��tV��j����� � -------------------------------------------------------------------------------- /export/markdown.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Bullet-Proofing 5 | ## Patterns & Practices 6 | #### Survivable Advanced Functions and Scripts 7 | https://github.com/Jaykul/DevOps2019 8 | 9 | Joel "Jaykul" Bennett 10 | 11 | Battle Faction 12 | 13 | 14 | 15 | note: 16 | 17 | Welcome everyone to "Bullet-proofing: Patterns and practices for survivable advanced functions and scripts" ... a presentation for the PowerShell + DevOps Global Summit, 2019. I am, of course, Joel Bennett 18 | 19 | You may know me as "Jaykul" on Twitter or on the PowerShell Slack or Discord or IRC. I've been running that online chat community for about 12 years, and I am a ten-time PowerShell MVP. 20 | 21 | Before we get started today I want to tell you something about myself: Occupationally I'm a programmer. My business cards (if I had any) would say "Senior DevOps Engineer" or sometimes just "Senior Software Engineer" or "Software Architect" but at the end of the day, I'm a Battle faction hacker. It's important that you understand that as we get into our subject for today, because we're going to be talking a lot about design, but I want you to keep in mind that the only reason we're putting this much thought into our design is to make sure that our modules are usable by _other people_, and that they will survive first contact with a newbie. 22 | 23 | 24 | --- 25 | 26 | 27 | 28 | # Disclaimer 29 | 30 | My code may not actually be bullet-proof 31 | 32 | note: 33 | 34 | I want to be clear about one thing: I can promise you, up front, not all of my own code is bullet-proof. As a battle faction hacker, the truth is that in my public code, I only rarely write things that really **need** to be bullet-proof, and as a result, if you look me up on github, you're not going to find all of these patterns followed, and you may find a lot of commands that are missing exception handling. That tends to be a side-effect of the types of modules I write, where errors are unlikely, and not critical. ;) 35 | 36 | At work, it's quite different -- we write infrastructure automation and software deployment scripts. There, I have to be much more vigilant, and we prioritize logging and error handling, and so on. 37 | 38 | --- 39 | 40 | 41 | 42 | # Survivable Code 43 | 44 | - Errors are handled appropriately 45 | - Commands make sense & work together 46 | 47 | note: 48 | 49 | To me, survivable code means two things: it's about design and about error handling. Of the two, error handling is the easiest, so we're going to talk about that right up front and get it out of the way. 50 | 51 | 52 | --- 53 | 54 | 55 | 56 | # Error Handling 57 | ## What's Appropriate? 58 | - Sometimes that means not handling 59 | - Usually that means catch and release 60 | - Normal use shouldn't produce errors 61 | - Wrap **everything** in try/catch 62 | 63 | note: 64 | 65 | Obviously in PowerShell it's relatively acceptable to let errors flow from your output, but you should always do so by catching and re-throwing, not by just ignoring. There are a lot of explanations I could get into about why, and how sometimes exception only show up when there's a try/catch, but this is not an error-handling talk, it's a patterns and practices talk so I can just say: 66 | 67 | Follow this template, and add custom handling inside it when you want to suppress errors, turn them into warnings, or convert terminating exceptions into non-terminating errors or vice-versa. 68 | 69 | -- 70 | 71 | 72 | 73 | ## Code Template 74 | 75 | ```PowerShell 76 | function Test-Function { 77 | <# help here #> 78 | [CmdletBinding()]param() 79 | process { 80 | try { 81 | <# code here #> 82 | } catch { 83 | throw $_ 84 | } 85 | } 86 | } 87 | 88 | ``` 89 | note: 90 | 91 | There could be more to this template (and there will be, later), but for the moment, the point is to start with a try/catch wrapped around the inside of your process block (and your begin and end blocks too, if you need them) 92 | 93 | At a bare minimum, you're going to be rethrowing, to make sure that you don't get surprised by exceptions if someone wraps your code. I actually encourage you to test your code with `-ErrorAction Stop`, to help you identify potential problems. 94 | 95 | Remember that you can add additional try/catch statements inside, to wrap specific lines or handle particular errors. You can _of course_ handle particular errors even here, if you just need to customize the error message, or whatever, but this is meant to be the last stand, so you can't really do much to _recover_ here. 96 | 97 | Ok, let's look a real-world example: What happens if something in your `prompt` function has an error or throws an exception? 98 | 99 | -- 100 | 101 | 102 | 103 | ## Demo 1 104 | #### Not handling errors appropriately 105 | 106 | ```PowerShell 107 | function prompt { 108 | Write-Error "Typo" 109 | "$pwd> " 110 | } 111 | 112 | function prompt { 113 | Write-Error "Typo" 114 | "$pwd> " 115 | throw "grenade" 116 | } 117 | ``` 118 | 119 | What happens if something in your `prompt` function has an error or throws an exception? 120 | 121 | note: 122 | 123 | If we run these ... 124 | 1. we can see that _errors are ignored_, 125 | 2. but when the prompt throws an exception, PowerShell tosses any output it's _already gotten_ and gives you the minimalist prompt. 126 | 3. You're expected to know that this prompt means you should look in `$Error` and figure out what happened (oh, someone threw a grenade, classic). 127 | 128 | -- 129 | 130 | 131 | 132 | ## Demo 2 133 | #### Handling errors appropriately 134 | 135 | 136 | ```PowerShell 137 | Set-PowerLinePrompt 138 | $prompt 139 | $prompt += { Write-Error "Typo"} 140 | $prompt += { throw "grenades" } 141 | $PromptErrors 142 | $PromptErrors[1] | Select * 143 | $prompt = $prompt[0,1] 144 | ``` 145 | 146 | 147 | note: 148 | 149 | Let me show you what PowerLine does in that situation. PowerLine is my prompt module, and in it, your prompt is `$prompt`, a collection of script blocks. Here's an equivalent PowerLinePrompt, and let's see what happens when you add an exception ... 150 | 151 | You can see I actually still got my prompt! But I also got a warning and we can see that it's telling me how to _hide_ the error if I really want to do that... 152 | 153 | Of course, I don't really want to hide the errors. 154 | 155 | If I throw an exception, it gets logged right along with the error, and we can look at both of them in `$PromptErrors`. Notice that it tells us which block cause each problem, and of course, in this case, we can just remove those blocks. 156 | 157 | -- 158 | 159 | 160 | 161 | ## Friends log everything 162 | 163 | ```PowerShell 164 | try { 165 | Write-Information "Enter Process Import-Configuration" -Tag Trace 166 | <# code here #> 167 | } catch { 168 | Write-Information $_ -Tag Exception 169 | throw $_ 170 | } 171 | ``` 172 | 173 | Invoke it with `-Iv drip` 174 | 175 | ```PowerShell 176 | $drip | 177 | Where Tag -Contains Exception | 178 | Export-CliXml exception.logx 179 | ``` 180 | 181 | note: 182 | 183 | I want to encourage you to _log_ everything. When we're trying to track down a problem, it's extremely helpful if there are logable statements for each logic block -- you know what I mean, right? Within each branch of an `if`, or each statement of a `switch`, etc. 184 | 185 | There are a lot of **better** ways to log than what I'm showing you here, but if you don't have a logging solution, you could do a lot worse than writing it to the Information stream. 186 | 187 | The information stream is timestamped and sourced, and it's full of objects, so you can capture it with the `-InformationVariable` parameter and use Export-CliXml to dump it to a file. It's pretty straight-forward, and can even be used across remoting. 188 | 189 | -- 190 | 191 | 192 | 193 | ## In summary 194 | 195 | - Always try/catch 196 | - Rethrow by default 197 | - Only handle specific exceptions 198 | - Always log 199 | - Especially exceptions 200 | - Even Verbose output counts 201 | 202 | note: 203 | 204 | OK, before we go back to design, I want to just summarize this a little: the point here is that you should always try/catch, even if you're just rethrowing. 205 | 206 | And (especially if you're supressing exceptions), you should log the path of execution, so when something unexpected happens, you have the ability to say: look, this is what happened... 207 | 208 | OK, Now, let's improve the design... 209 | 210 | --- 211 | 212 | 213 | 214 | 215 | # Usable Commands 216 | 217 | - Intuitive and discoverable 218 | - Play well with others 219 | - **It's about good interfaces** 220 | 221 | Let's talking about design, 222 | this is my favorite part. 223 | 224 | note: 225 | 226 | So. I told you that survivable code was about writing commands that make sense, and work together. 227 | 228 | What that means is that it's about designing good interfaces 229 | 230 | - commands people can use even without reading the help, and 231 | - commands which work well _with other commands_, 232 | 233 | Let's talk about the process. 234 | 235 | I know I said I was Battle Faction ... but the truth is I'm really never quite happy with a module until the commands can pipe into each other, and the number of nouns has been reduced as far as is comfortable. I don't worry too much about total newbies, but I want to write commands that people with some PowerShell experience can pick up and use intuitively. 236 | 237 | To design commands correctly, we have to think about how they'll be used 238 | 239 | -- 240 | 241 | 242 | 243 | ## How will it be used? 244 | 245 | - How do you want to call it 246 | - What parameters do you want to pass 247 | - Where will you get those values 248 | - What are you doing with the output 249 | 250 | note: 251 | 252 | You're going to brainstorm, in a sense: How do you want to use it, or how do you think other people will use it. What commands exist which people might want to use it _with_. Where are you getting the values for your parameters? What are you doing with the output? Are you passing it to another command, formatting it for display? 253 | 254 | Now, our goal is to design the command to make these scenarios that you come up with easier. 255 | 256 | It's a good practice to start by writing down concrete examples of your answers to these questions, in pseudo code. It will help you get a feel for how you expect the command to work. When you do that, write them like this ... 257 | 258 | 259 | -- 260 | 261 | 262 | 263 | ### Write down your examples ... 264 | 265 | ```PowerShell 266 | function Import-Configuration { 267 | <# .SYNOPSIS 268 | A command to load configuration for a module 269 | .EXAMPLE 270 | $Config = Import-Configuration 271 | Load THIS module's configuration from a command 272 | .EXAMPLE 273 | $Config = Import-Configuration 274 | $Config.AuthToken = $ShaToken 275 | $Config | Export-Configuration 276 | 277 | Update a single setting in the configuration 278 | #> 279 | ``` 280 | 281 | note: 282 | 283 | When you start writing out the concrete examples, write them like this ... 284 | 285 | Hopefully, you recognize this as comment-based help for the command -- and I'm very serious. The first thing you should do when you start writing a command, is write the help. 286 | 287 | --- 288 | 289 | 290 | 291 | # First, write help 292 | 293 | We really require three things in the help: 294 | 295 | 1. A Synopsis and/or a short description 296 | 2. Examples -- for every parameter set 297 | 3. Documentation for each parameter 298 | 299 | note: 300 | 301 | I'm not suggesting you can write all of the help before you write the command, but ... 302 | 303 | When you start writing down your ideas about how you're going to use the command, it can help you to visualize what you're going to be doing with the command, and that helps you think about the necessary parameters, what the output needs to be, etc. 304 | 305 | I like to talk about the help you can't not write. That's three things: 306 | 307 | 1. A Synopsis 308 | 309 | First we need a synopsis or short description of the command. That's all it takes for the help system to engage, but describing it in a sentence can also help you to start thinking about the command: what it's job is, and what it's job is not. 310 | 311 | I encourage you to also write a full description, but for now, just write a synopsis (you'd probably get the description wrong anyway at this point). The synopsis is enough to get started. 312 | 313 | 2. An example -- for each parameter set 314 | 315 | Then we can write down our examples. At this stage, it's important that your examples aren't contrived. They should be the result of your brainstorming for how you want to use it. Each example should have an explanation of the purpose of using the command this way. 316 | 317 | In the simplest case, you can provide a single example (with no parameters), and a sentence explaining that this runs it with the default values (and explain what those are), and then explain what happens in that case. 318 | 319 | You don't need an example of every parameter, but you do need an example showing all of the _mandatory_ parameters for each parameter set. 320 | 321 | Now, maybe you don't know what those are yet, but these examples are long-lived, and you can update these and add more as you progress. 322 | 323 | It's might be worth saying that if you can't think of a real example for a parameter set -- you probably don't need that parameter set 😉. 324 | 325 | Long term, more examples are better, but only if they have significantly different _outcomes_. Examples showing parameters which just set properties on the output aren't necessary, because we're also going to write... 326 | 327 | 3. Parameter Documentation 328 | 329 | Documentation for each parameter. You can write this as you add parameters, by simply putting a comment above each one. In fact, I strongly recommend you do it that way (rather than using the `.PARAMETER` marker) because it's harder to forget to write and update! 330 | 331 | The next thing we're going to do is ... 332 | 333 | --- 334 | 335 | 336 | 337 | # Then write tests 338 | 339 | ## Remember this is design 340 | - Write tests as documentation 341 | - Document your intent and design 342 | - Prove your implementation works 343 | 344 | note: 345 | 346 | We're going to mostly skip over testing, because that's an entirely different talk (or two or three), but let me say this: 347 | 348 | You should approach tests as documentation. Think of them as documenting your intent, your design, and your examples, and ensuring that you don't break one of your own use cases at some point in the future. 349 | 350 | Listen: If you're not writing tests, start. Grab Pester. Write some _acceptance tests_, and read a little about behavior-driven development. Have a look at Gherkin syntax. 351 | 352 | But the bottom line is: make sure you have tests for each of the examples that we wrote above. 353 | 354 | --- 355 | 356 | 357 | 358 | # Pick good names 359 | 360 | Once you have some help and some tests in place, stop and think _again_ about naming things. 361 | 362 | This really is the most crucial part of your design. 363 | 364 | Parameter names define your user interface, but also your programming interface, affecting pipeline binding as well as discoverability. 365 | 366 | note: 367 | 368 | I know most of you spend some time thinking about what to name your commands right? What to name your functions or scripts. It's inevitable, because there are rules in PowerShell about naming. 369 | 370 | But you _should_ be spending even more time thinking about the names of your parameters, because parameter names are not just about users discovering how to use your command, they're also the interface by which commands interact with each other. 371 | 372 | -- 373 | 374 | 375 | 376 | ## Remember our example 377 | 378 | - So far we have one parameter 379 | - What should I call it? 380 | - Module 381 | - ModuleInfo 382 | - PSModuleInfo 383 | - Maybe `ArgumentTransformation` for strings 384 | - What about Get-Command & Get-Module 385 | 386 | note: 387 | 388 | Show the Import-Configuration code 389 | 390 | So far we have one parameter. What should it's name be? 391 | 392 | Personally, I'm leaning toward ModuleInfo, because I think the "PS" looks like a module prefix that I should not use, and ModuleInfo makes it clear that I'm not just looking for a module _name_. 393 | 394 | However, I'm considering three things: 395 | 396 | 1. Perhaps I could write a TypeAdapter for ModuleInfo to call get-module if you pass a string name. That would mean "Module" would be a good name anyway. 397 | 2. What sorts of objects exist in PowerShell that might have a ModuleInfo as a property? CommandInfo! It turns out that the output of Get-Command has a `Module` property which would work for this -- so even if I name it "ModuleInfo", I'll need to alias it as "Module" for that to work. 398 | 3. The command that returns `PSModuleInfo` is `Get-Module` and most people probably don't know the type of object it returns. 399 | 400 | -- 401 | 402 | 403 | 404 | ## Good parameter names 405 | 406 | - Recognizable and specific 407 | - Implicitly typed 408 | - Distinct 409 | - Consistent 410 | 411 | note: 412 | 413 | So what makes a good parameter name? 414 | 415 | Obviously, it's a good name if users can tell what you want! Specifically, if a user can tell what information they need to pass to each parameter --and what form the data should take-- without needing to read the help. 416 | 417 | So here are some guidelines for picking parameter names. Sometimes, these are going to cause conflicts in terms of not being able to meet all of them, but they are in priority order, and also -- you can use aliases to meet some of these goals. 418 | 419 | Parameters should be: 420 | 421 | -- 422 | 423 | 424 | 425 | ### Recognizable and Specific 426 | 427 | | Good | Better | 428 | | ---- | ------ | 429 | | `$Path` | `$FilePath` or `$DirectoryPath` 430 | | `$Name` | `$FirstName` or `$FullName` 431 | 432 | 433 | Users should know which value you actually want 434 | 435 | note: 436 | 437 | Users should be able to guess what you actually want. I put some examples here -- the idea is that more specific parameter names help people know what to pass in. 438 | 439 | -- 440 | 441 | 442 | 443 | ### Implicitly Typed 444 | 445 | | Good | Better | 446 | | ---- | ------ | 447 | | `$File` | `$FilePath` | 448 | | `$TimeOut` | `$TimeOutSeconds` | 449 | | `$Color` | `$ColorName` | 450 | 451 | Users should know what types they can pass 452 | 453 | note: 454 | 455 | Users should be able to guess about what type of object is needed, or what the unit of measurement is, and what format the data should take (that is, you know "Red" not the css hex value #FF0000) 456 | 457 | -- 458 | 459 | 460 | 461 | ### Distinct 462 | 463 | - Save typing by reducing common prefixes 464 | - Avoid uncommon terms 465 | - Avoid similarity 466 | - Avoid duplication 467 | 468 | | Good | Better | 469 | | ---- | ------ | 470 | | `$AllowClobber`, `$AllowPreRelease` | `$IgnoreCommandName`, `$AllowPrerelease` | 471 | 472 | 473 | note: 474 | 475 | Consider what happens if I use PSReadLine's `Ctrl+Space` to list parameters (look at Install-Package as a bad example!) 476 | 477 | Multiple parameters that accept similar information in different ways might seem desireable for flexibility, but it will confuse users -- even if you put them in different parameter sets. 478 | 479 | Ideally, each parameter would start with a different letter, and be a unique way to pass a specific piece of information. Less typing is better. 480 | 481 | Here's another example: if you need a username and password, don't ask for `$UserName` and `$Password` -- ask for a `$Credential`. Don't offer both options either (that is: Credential _and_ UserName/Password). More is not better, it's just more. 482 | 483 | It's ok to limit the ways a user can invoke your command (even if it means forcing them to create a credential), if it results in a dramatically clearer interface where there's only one representation of each piece of information, and it's more obvious. 484 | 485 | -- 486 | 487 | 488 | 489 | ### Consistent 490 | 491 | - Reuse parameter names ... 492 | - Match properties on output objects 493 | - Match properties on pipeline input 494 | 495 | note: 496 | 497 | Being consistent with parameter names across your module, or even parameter names on common PowerShell commands, will make it easier for users to learn and to guess based on their previous experience. 498 | 499 | Also, when we're using parameter values as output properties, try to make the names match. Your users may be already familiar with the output object, but even if they're not, they'll learn your conventions faster if the name repeats consistently. 500 | 501 | Finally, the same consideration applies to the names of properties which you want to use as input. Not only is consistecy important, it allows pipelining. 502 | 503 | Don't forget that while you _can_ use aliases to resolve pipeline inputs and even handle user expectations, but when there are too many aliases, it can lead to confusion too -- it's a lot easier for users to follow if the names match up exactly... 504 | 505 | --- 506 | 507 | 508 | 509 | # process first 510 | #### Improve performance by reducing calls 511 | 512 | - Most commands could participate in a pipeline 513 | - Use `ValueFromPipelineByPropertyName` 514 | - Or `ValueFromPipeline` (one parameter per set) 515 | 516 | This improves performance! The overhead of initializing a command is substantial. 517 | 518 | note: 519 | 520 | Once you've written your help and tests, and put some thought into parameter names, it's time to start implementing. 521 | 522 | You should start with the process block. 523 | 524 | The reality is that initializing a command is expensive (commands are objects), so it's faster to pipe multiple things to a command than to call the command multiple times. 525 | 526 | Obviously getting that improvement depends on your users calling your command that way, but you want to be able to do that. 527 | 528 | I believe most commands should be able to participate in a pipeline -- and in order for you to write commands that can, you need to put some or most of the work in the process block, and make sure that any parameters you need to use there have the `ValueFromPipelineByPropertyName` (or `ValueFromPipeline`) in their attributes. 529 | 530 | Basically, my position is that you should start by putting everything in the process block, and decorate all your parameters with `ValueFromPipelineByPropertyName`, and then remove logic from the process block as a performance optimization. 531 | 532 | 533 | -- 534 | 535 | 536 | 537 | # Optimize process 538 | 539 | What can we remove from process? 540 | 541 | - Don't pre-optimize 542 | - Begin and End blocks only run once 543 | - Code there can't use pipeline parameters 544 | - Setup and teardown code 545 | - Test and validation code 546 | 547 | note: 548 | 549 | It's tempting to just leave everything in the process block, because that pretty much guarantees that the command will work the same way regardless of how it's called (with parameters or on the pipeline). 550 | 551 | However, you should always look over your code before you're ready to share it and consider whether you can move code to the `Begin` or `End` block -- anything you can do once instead of every time will improve the performance of your command when it's in the pipeline! 552 | 553 | Some obvious examples include setup and teardown code which doesn't need to be re-run each time, and which doesn't use values from your pipeline parameters can obviously be moved, but in general: re-examine your use cases! Look for parameters which you anticipate passing only as parameters, and never as pipeline values (for example, consider `-Destination` on a `Move` command), and see if you're doing anything with _just those parameters_ that could be moved to the `begin` or `end` blocks. 554 | 555 | Remember: you can't _safely_ refer to any parameter that's set as `ValueFromPipelineByPropertyName` or `ValueFromPipeline` in the `begin` block -- but you _can_ collect those values for use in the `end` block. 556 | 557 | --- 558 | 559 | 560 | 561 | # Customizing Types 562 | 563 | Consider writing Classes or setting the `PSTypeName` on your outputs. 564 | 565 | - Parameters bind to properties by name _and type_ 566 | - Formatting is customized by type 567 | - Piping objects can communicate _a lot_ of data 568 | 569 | 570 | note: 571 | 572 | I want to leave you with some thoughts on custom objects. 573 | 574 | In PowerShell, everything is an object, and the [Type] of a object is fundamental to the formatting of objects on screen. I don't have time to get into the intricacies of format files and so on, but I'll make the time to say: 575 | 576 | When you're designing a set of commands that work together, you need to think beyond the function itself and think about your output objects as well. Consider what properties you need on the output, and which ones you really need to be visible by default. Consider what information you have available within each command that you might want to pass to other commands. 577 | 578 | -- 579 | 580 | 581 | 582 | ## What Type of Object? 583 | 584 | - Built-in, Dynamic, Custom 585 | - Write PowerShell Classes 586 | - Write PowerShell Enums 587 | - Constrain with `[PSTypeName(...)]` 588 | 589 | note: 590 | 591 | In PowerShell we deal in three general categories of objects: the built-in objects which are part of the .NET framework, such as the FileInfo, dynamic objects (i.e. "PSCustomObject") such as those created by PowerShell when you use `Select-Object`, and custom objects defined by the functions and 592 | 593 | However, there are lots of very good reasons that you should define your own object types. 594 | 595 | 1. When you want to customize formatting, your output will need a type name 596 | 2. When you need to pass a lot of data between commands, you'll want a name for a parameter type 597 | 3. When you want interactive objects, you'll want a custom type 598 | 599 | A lof of the time, you can get away with just specifying a custom `PSTypeName` -- it's enough to let you format and even contrain inputs. However, it doesn't help users who are trying to tab-complete properties of your output objects, nor is it easy for users to create the objects to pass them as input. 600 | 601 | Why do we care about types? 602 | 603 | Probably the best interaction between functions is to take the output of one command as input to another -- but the best user experience is not necessarily an `InputObject` parameter of the specific type, sometimes it's better to accept the properties of the object as parameters. For one thing, it means that a `PSObject` will give you enough structure for pipelining. For another, it allows users to just pass values for each parameter. one much easier for users who do _not_ have the object to call your function, while still preserving the ease of use 604 | 605 | -- 606 | 607 | 608 | 609 | ## Getting parameter values from the pipeline 610 | 611 | - ValueFromPipeline 612 | - Input from specific other commands 613 | - Easy custom objects 614 | - ValueFromPipelineByPropertyName 615 | - Properties from other commands 616 | - Speculatively allowed in-line 617 | 618 | note: 619 | 620 | Hopefully, you've already encountered the `[Parameter()]` attribute, and it's many switches. Two of them allow you to collect the value of the parameter from pipeline input: 621 | 622 | - ValueFromPipeline allows you to create an `$InputObject` sort of parameter to collect each object. It's a good fit for when you only want to accept the output from one of your other functions, or when your objects are easy to construct (e.g have default constructors so you can easily build them from hashtables). 623 | 624 | - ValueFromPipelineByPropertyName allows you to collect the value of a single property from each object. Of course, you can set up multiple parameters like this to collect multiple properties. This is a good fit when you don't have a specific object in mind, or when you only need the key identifier from it (e.g. `PSPath` for files). 625 | 626 | --- 627 | 628 | 629 | 630 | # Thank You 631 | Please use the event app to submit a session rating 632 | 633 |   634 | 635 | https://github.com/Jaykul/DevOps2019 636 | 637 | If you have good things to say, 638 | I'm Joel Bennett 639 | 640 | Otherwise, I'm Kirk Munro 😉 641 | 642 | 643 | 644 | 645 | -------------------------------------------------------------------------------- /export/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/images/bg.png -------------------------------------------------------------------------------- /images/cc-by-nc-sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/images/cc-by-nc-sa.png -------------------------------------------------------------------------------- /images/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/images/header.png -------------------------------------------------------------------------------- /images/prompt-exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaykul/DevOps2019/b371706c12c6fcc589385ed60d0647a90a889a49/images/prompt-exception.png -------------------------------------------------------------------------------- /should-have-been-a-book/00. abstract.md: -------------------------------------------------------------------------------- 1 | # Bullet-proofing: Patterns & Practices for survivable advanced functions and scripts. 2 | 3 | We will start with a pair of related scripts and put them together into a module - discussing what our options are, and the motivation for each change, we'll improve the functions by actually applying a list of best practices and code snippets including: 4 | 5 | - the help you can't not write 6 | - picking good parameter names 7 | - validating input values 8 | - outputting objects that are predictable and identifiable 9 | - binding parameters from the pipeline 10 | - why to avoid a single InputObject 11 | - finding work that can go outside the process block 12 | - outputting errors that are unrecoverable 13 | - recovering from errors when possible 14 | 15 | At the end of our time you'll have a series of reproducible steps, and a few code snippets and the knowledge to apply them to make your functions and even your modules more robust and more intuitive for users. 16 | 17 | I'll introduce attributes including [CmdletBinding()], [Parameter()] and [OutputType()] and we'll go over the difference between Write-Error and throw (and maybe even $PSCmdlet.WriteError()) and talk briefly about the difference between a PSCustomObject with PSTypeNames and an object with a PowerShell class (and how to write parameters that accept both). 18 | 19 | # An Introduction 20 | 21 | This talk is on writing survivable code, which to me means three things: 22 | 23 | 1. Designing up front. Writing commands which make sense and work together 24 | 2. Handling errors and exceptions 25 | 3. Logging what you can't handle 26 | 27 | I want to be clear about one thing: I can promise you, up front, that not all of my own code is bullet-proof. 28 | 29 | The truth is that in my public code, I only rarely write things that really **need** to be bullet-proof, and as a result, if you look me up on github, you're not going to find all of these exception handling and logging practices followed. That tends to be a side-effect of writing modules for colors and prompts, where errors are unlikely, and not critical in any case. ;) 30 | 31 | To be clear: at work, it's quite different -- we write deployment scripts which frequently have to handle errors, and always have to be much more vigilant about logging than what I do on github. 32 | 33 | ## Let's start by talking about design, which is my favorite part 34 | 35 | In fact, I just want to remind you (although I'm not going to get into it), an important part of design is thinking about how your command will be used, so it's a good idea to write some help first, and then some tests, before you ever start implementing anything. -------------------------------------------------------------------------------- /should-have-been-a-book/01. Help You Must Write.md: -------------------------------------------------------------------------------- 1 | # Let's start with Help 2 | 3 | For a good command, we really require just three things in the help: 4 | 5 | 1. A Synopsis 6 | 7 | A short description of the command is mandatory for the help system to even engage. 8 | 9 | 2. An example -- for each parameter set 10 | 11 | In the simplest case, you can simply provide a single example with no parameters, and explain that this runs it with the defaults -- document in the example what happens in that case. 12 | 13 | If you can't think of an example for a parameter set -- consider removing that parameter set 😉. 14 | 15 | Make sure you have at least one example for each parameter set that _correctly_ shows an example of how to provide the values which are necessary to invoke that parameter set. 16 | 17 | More examples are better, but only if they have significantly different _outcomes_. 18 | 19 | 3. Documentation of every parameter 20 | 21 | You can write this as you add parameters, by simply putting a comment above each one. I strongly recommend you do it that way (rather than use the `.PARAMETER` marker) because it simplifies it, making it _harder to mess up_, and _harder to forget_ to update. 22 | 23 | 24 | # We're going to skip right over testing 25 | 26 | That's a whole different talk. If you're not writing tests, I strongly recommend you start using Pester, write acceptance tests at a minumum --have a look at Gherkin syntax-- and read a little about behavior-driven development. -------------------------------------------------------------------------------- /should-have-been-a-book/02. Naming Conventions.md: -------------------------------------------------------------------------------- 1 | # Naming Conventions 2 | 3 | Obviously when we talk about naming conventions, we're talkgin about what you name your command, it's parameters, and also the variables you use in it -- but I think parameters are the ones we need to focus on. With variables, naming isn't as important (since only maintainers care), and the fact is that most developers already spend time thinking about their command names, because the limited set of approved verbs, and mandate to use singular nouns forces the issue. 4 | 5 | Command names matter for discoverability, but the truth is, parameter names may be **the most important part** of your programming interface, because they are affect _usability_ in several ways. Specifically, they affect your user's ability to figure out what to pass, and getting their names _and attributes_ right affects your users ability to pipeline input to your function. 6 | 7 | ## What makes a good parameter name? 8 | 9 | It's a good name if users can tell what you want! 10 | 11 | Specifically, if users can tell what information they need to pass to each parameter --and what form the data should take-- without reading the help. 12 | 13 | Sometimes, one of these goals will make others impossible. That's ok. Prioritize. But also remember that you _can_ use aliases to meet your goals. In any case, there are a few things which help your parameters be easier to understand. They should be: 14 | 15 | - Recognizable and Specific 16 | 17 | `$FirstName` or `$FullName` would be better than `$Name` 18 | 19 | - Implicitly Typed 20 | 21 | Remember that we want users to know what they can pass without reading the help. 22 | 23 | - `$FilePath` is better than `$File` or `$Path` 24 | - `$TimoutSeconds` is better than `$Timeout` 25 | 26 | - Distinct 27 | 28 | Consider what happens if I use PSReadLine's `Ctrl+Space` to list parameters. 29 | 30 | Although multiple parameters that accept similar information in different ways might be desireable for flexibility, it can confuse users even if you put them in parameter sets. 31 | 32 | Ideally, each parameter would start with a different letter, and be a unique way to pass a specific piece of information. 33 | 34 | For example, use `$Credential` alone, rather than having _both_ `$Credential` and `$UserName` and `$Password`. It limits the way a user can invoke your command (and might force them to manually create a credential on a separate line), but it's dramatically clearer what a user needs to do when there's only one representation. 35 | 36 | - Match properties on output types 37 | 38 | If you're passing through some of the input as properties on the output, consider what the property names will be when naming your parameters. Sometimes it's worth breaking all the other rules in order to match up with the property on an output type you don't control. 39 | 40 | - Match properties on pipeline input types 41 | 42 | In order to set parameters using the properties of pipeline input objects, you need to match the property name. You can use aliases to do this, but it's a lot easier for users to follow if the names match up exactly... -------------------------------------------------------------------------------- /should-have-been-a-book/03. Inputs and Outputs -- Types Of Objects.md: -------------------------------------------------------------------------------- 1 | # Output Types and Parameter names 2 | 3 | For background: 4 | 5 | - PowerShell is based on .NET, an object oriented framework 6 | - Everything we output is an object 7 | - Everything we pass as parameters are objects 8 | - Each object is a specific `type` of object 9 | - The definition of a specific type is called a `class`. 10 | 11 | Objects are fundamental to the formatting of output in PowerShell, but also to the way pipeline input works. A parameter may be defined to take the whole pipeline object as a value, or it to take a single property from it which it matches the parameter type and name. 12 | 13 | This means that designing a _set_ of commands that work together flawlessly is about more than just designing the parameters of the functions -- you should include designing the output types. 14 | 15 | ## What Type of Object? 16 | 17 | In PowerShell we deal in three general categories of objects: the built-in objects which are part of the .NET framework, such as the FileInfo, dynamic objects (i.e. "PSCustomObject") such as those created by PowerShell when you use `Select-Object`, and custom objects defined by the functions and 18 | 19 | However, there are lots of very good reasons that you should define your own object types. 20 | 21 | 1. When you want to customize formatting, your output will need a type name 22 | 2. When you need to pass a lot of data between commands, you'll want a name for a parameter type 23 | 3. When you want interactive objects, you'll want a custom type 24 | 25 | Most of the time, you can get away with just specifying a custom `PSTypeName` -- it's enough to let you format and even contrain inputs. However, it doesn't help users who are trying to tab-complete properties of your output objects, nor make it easy for users to create the objects to pass them as input. 26 | 27 | ## Why do we care about types? 28 | 29 | Probably the best interaction between functions is to take the output of one command as input to another -- but the best user experience is not necessarily an `InputObject` parameter of the specific type, sometimes it's better to accept the properties of the object as parameters. For one thing, it means that a `PSObject` will give you enough structure for pipelining. For another, it allows users to just pass values for each parameter. one much easier for users who do _not_ have the object to call your function, while still preserving the ease of use 30 | -------------------------------------------------------------------------------- /should-have-been-a-book/03.5 History of classes.md: -------------------------------------------------------------------------------- 1 | ## A History Lesson of Custom Classes in PowerShell 2 | 3 | ### Prior to PowerShell 3 4 | 5 | PowerShell's Extensible Type System didn't originally let you create new concrete types. If you wanted an actual type that you can cast to or type-check with, as in your example script ... you needed to define it in a compiled language (C# or VB.net). 6 | 7 | In PowerShell 2, you could use the "Add-Type" command to compile the code in-line, but the definition still had to be in one of those languages: 8 | 9 | ```PowerShell 10 | Add-Type @" 11 | public struct contact { 12 | public string First; 13 | public string Last; 14 | public string Phone; 15 | } 16 | "@ 17 | ``` 18 | 19 | In PowerShell 1, you would have had to manually use CodeDom, there is a very old function [new-struct](http://poshcode.org/scripts/190) script on PoshCode.org which will help. Our example becomes: 20 | 21 | ```PowerShell 22 | New-Struct Contact @{ 23 | First=[string]; 24 | Last=[string]; 25 | Phone=[string]; 26 | } 27 | ``` 28 | 29 | ### In PowerShell 3 30 | 31 | In PowerShell 3, we got the ability to use the `PSCustomObject` accelerator to add a (fake) type name, and an attribute we could use on parameters to test for it, so that this: 32 | 33 | ```PowerShell 34 | [PSCustomObject]@{ 35 | PSTypeName = "Contact" 36 | First = $First 37 | Last = $Last 38 | Phone = $Phone 39 | } 40 | ``` 41 | 42 | Could be sort-of required by this: 43 | 44 | ```PowerShell 45 | function PrintContact 46 | { 47 | param( [PSTypeName("Contact")]$contact ) 48 | "Customer Name is " + $contact.First + " " + $contact.Last 49 | "Customer Phone is " + $contact.Phone 50 | } 51 | ``` 52 | 53 | ### In PowerShell 5 54 | 55 | In PowerShell 5 everything changes, and we finally got `class` and `enum` as language keywords for defining types. 56 | 57 | ```PowerShell 58 | class Contact 59 | { 60 | # Optionally, add attributes to prevent invalid values 61 | [ValidateNotNullOrEmpty()][string]$First 62 | [ValidateNotNullOrEmpty()][string]$Last 63 | [ValidateNotNullOrEmpty()][string]$Phone 64 | } 65 | ``` 66 | 67 | We could optionally add constructors and methods, etc., and we can create these with `New-Object` or by calling the constructor like `[Contact]::new()` or even by casting a hashtable: 68 | 69 | ```PowerShell 70 | $C = [Contact]@{ 71 | First = "Joel" 72 | Last = "Bennett" 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /should-have-been-a-book/04. UsingTypesForParameters.md: -------------------------------------------------------------------------------- 1 | ## How can we validate input values? 2 | 3 | The first way you can validate input is to specify a type. Ideally, simple types like `[int]` or `[string]` or built-in types like `System.IO.FileInfo`. 4 | 5 | The second way you can validate input is to add validation attributes. There are several built in, and even more in PowerShell 6: ValidateCount, ValidateDrive, ValidateLength, ValidateNotNullOrEmpty, ValidatePattern (note there's now an error message property), ValidateRange, ValidateSet, and more, including of course, ValidateScript -- for all your other needs. 6 | 7 | The third way is to create your own types and even argument transformation attributes and type converters. This gives you a lot of flexibility and limitless ability to check property values as they're being set on the object -- to enforce your rules before the objects are even passed to the function. Argument transformation attributes can let you convert parameters from one type to another, and even prompt the user for more information, etc. 8 | 9 | ## Output types and promises 10 | 11 | When you write a function, you should always decorate it with an `[OutputType()]` attribute indicating the type(s) of the objects it may output. This lights up tab-expansion in other commands in the pipeline, and can help tools tell you which commands work together. 12 | 13 | -------------------------------------------------------------------------------- /should-have-been-a-book/05. ValueFromPipelineByPropertyName.md: -------------------------------------------------------------------------------- 1 | # Getting parameter values from the pipeline 2 | 3 | Hopefully, you've already encountered the `[Parameter()]` attribute, and it's many switches. Two of them allow you to collect the value of the parameter from pipeline input: 4 | 5 | - ValueFromPipeline allows you to create an `$InputObject` parameter to collect each object. It's a good fit for when you only want to accept the output from one of your other functions, and when your objects are easy to construct (or have default constructors so you can easily build them from hashtables). 6 | 7 | - ValueFromPipelineByPropertyValue allows you to collect the value of a single property from each object. Of course, you can set up multiple parameters like this to collect multiple properties. This is a good fit when you don't have a specific object in mind, or when you only need the key identifier from it (e.g. `PSPath` for files). 8 | 9 | Now, the key thing to remember with pipeline input is that it means the `Process` part of your command is going to run over and over for each input. You can't always allow every parameter to be pipeline input -- and frequently, it doesn't make any sense to have every parameter passed in that way. 10 | 11 | However, when you can support it, pipeline input gives users of a function much greater flexibility! For the sake of flexibility, I strongly recommend that you design your commands starting with a `Process` block, and let every parameter that can be assigned within that loop be a `ValueFromPipelineByPropertyValue` parameter. Remember that you can only have _one_ `ValueFromPipeline` parameter ... 12 | 13 | There are a few caveats. First, when you design commands for pipeline input, think ahead about naming and aliases that could help someone bind the property from common objects or output of other commands in your module (as I talked about in the naming conventions). Second, make sure that you write some examples and plenty of test cases using the command that way, so that you actually cover the combinations of ways input can be passed during testing. -------------------------------------------------------------------------------- /should-have-been-a-book/06. Starting from Process.md: -------------------------------------------------------------------------------- 1 | # Starting From the `Process` Block 2 | 3 | To write functions (or Cmdlets) that work well in the pipeline, we need to start by putting most of the work in the `process` block (or the `ProcessObject` method). Any reference to parameters which are set with `ValueFromPipelineByPropertyName` (or `ValueFromPipeline`), or variables which are set from those parameters, obviously _has_ to stay in the `process` block, but otherwise... 4 | 5 | ## Don't leave everthing in the process block 6 | 7 | It's tempting to just write everything in the process block, because that pretty much guarantees that the command will work the same way regardless of how it's called (with parameters or on the pipeline). 8 | 9 | However, you should always look over your code before you're ready to share it and consider whether you can move code to the `Begin` or `End` block -- anything you can do once instead of every time will improve the performance of your command when it's in the pipeline! 10 | 11 | Some obvious examples include setup and teardown code which doesn't need to be re-run each time, and which doesn't use values from your pipeline parameters can obviously be moved, but in general: re-examine your use cases! Look for parameters which you anticipate passing only as parameters, and never as pipeline values (for example, consider `-Destination` on a `Move` command), and see if you're doing anything with _just those parameters_ that could be moved to the `begin` or `end` blocks. 12 | 13 | Remember: you can't _safely_ refer to any parameter that's set as `ValueFromPipelineByPropertyName` or `ValueFromPipeline` in the `begin` or `end` blocks. -------------------------------------------------------------------------------- /should-have-been-a-book/07. Outputting errors that are unrecoverable.md: -------------------------------------------------------------------------------- 1 | # When you can't handle an error 2 | 3 | Obviously in PowerShell it's relatively acceptable to let errors flow from your output, but some times you absolutely _have_ to handle them, suppress them, turn them into warnings, or convert terminating exceptions into non-terminating errors. 4 | 5 | The simple story for error-handling is that you should always make sure that anything which could be thrown is caught and thrown. We could get into this a lot more (talking about why sometimes ErrorActionPreference can cause exceptions to not be thrown until there's a `try/catch` wrapped around them), but the simple thing is to just follow a pattern: 6 | 7 | Wrap each script block in a try/catch and re-throw: 8 | 9 | ```PowerShell 10 | 11 | function Test-Function { 12 | [CmdletBinding()] 13 | param() 14 | begin { 15 | try { 16 | 17 | } catch { throw $_ } 18 | } 19 | process { 20 | try { 21 | 22 | } catch { throw $_ } 23 | } 24 | end { 25 | try { 26 | 27 | } catch { throw $_ } 28 | } 29 | 30 | } 31 | ``` 32 | 33 | Once you've done that, you should, of course ... 34 | 35 | ## Handle the errors you can handle 36 | 37 | Add additional `catch` statements to handle the exceptions you want to handle. 38 | 39 | Add logging to get your exception messages, stack trace, etc. --------------------------------------------------------------------------------