diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 000000000..de25ce32a --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,13 @@ +--- +exclude_paths: + - roles/elliotweiser.osx-command-line-tools + +skip_list: + - schema[meta] + - role-name + - experimental + - fqcn + - name[missing] + - no-changed-when + - risky-file-permissions + - yaml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..386190298 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +--- +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + updates: + applies-to: version-updates + patterns: + - "*" + security-updates: + applies-to: security-updates + patterns: + - "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..ac4061090 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,81 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 5 * * 4" + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v5 + + - name: Set up Python 3. + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint ansible ansible-lint + + - name: Lint code. + run: | + yamllint . + ansible-lint + + integration: + name: Integration + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + - macos-15 + - macos-14 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v5 + + - name: Uninstall GitHub Actions' built-in Homebrew. + run: tests/uninstall-homebrew.sh + + - name: Uninstall GitHub Actions' built-in browser installs. + run: | + sudo rm -rf /Applications/Firefox.app + sudo rm -rf /Applications/Google\ Chrome.app + sudo rm -rf /usr/local/bin/firefox + + - name: Install test dependencies. + run: | + sudo pip3 install --upgrade pip + sudo pip3 install ansible + + - name: Set up the test environment. + run: | + cp tests/ansible.cfg ./ansible.cfg + cp tests/inventory ./inventory + cp tests/config.yml ./config.yml + ansible-galaxy install -r requirements.yml + + - name: Test the playbook's syntax. + run: ansible-playbook main.yml --syntax-check + + - name: Test the playbook. + run: ansible-playbook main.yml + env: + ANSIBLE_FORCE_COLOR: '1' + + - name: Idempotence check. + run: | + idempotence=$(mktemp) + ansible-playbook main.yml | tee -a ${idempotence} + tail ${idempotence} | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) + env: + ANSIBLE_FORCE_COLOR: '1' diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..22ac0548d --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,34 @@ +--- +name: Close inactive issues +'on': + schedule: + - cron: "55 18 * * 4" # semi-random time + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v9 + with: + days-before-stale: 120 + days-before-close: 60 + exempt-issue-labels: bug,pinned,security,planned + exempt-pr-labels: bug,pinned,security,planned + stale-issue-label: "stale" + stale-pr-label: "stale" + stale-issue-message: | + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + close-issue-message: | + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. + stale-pr-message: | + This pr has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + close-pr-message: | + This pr has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index a97f7a52f..795c74ded 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.vagrant .DS_Store +.ansible *.retry roles* config.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dc520a12d..000000000 --- a/.travis.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- -sudo: required -language: objective-c -# 10.13 (see https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version) -osx_image: xcode9.3 - -before_install: - # Uninstall existing Homebrew installation. - - curl -sLO https://raw.githubusercontent.com/Homebrew/install/master/uninstall - - chmod +x ./uninstall - - ./uninstall --force - - sudo rm -rf /usr/local/Homebrew - - sudo rm -rf /usr/local/Caskroom - - sudo rm -rf /usr/local/bin/brew - -install: - # Install pip. - - sudo easy_install pip - - # Install Ansible. - - sudo pip install ansible - - # Add ansible.cfg to pick up roles path. - - "{ echo '[defaults]'; echo 'roles_path = ../'; } >> ansible.cfg" - - # Add a hosts file. - - sudo mkdir -p /etc/ansible - - sudo touch /etc/ansible/hosts - - "echo -e '[local]\nlocalhost ansible_connection=local' | sudo tee -a /etc/ansible/hosts > /dev/null" - -script: - # Install dependencies. - - "ansible-galaxy install -r requirements.yml" - - # Check the role/playbook's syntax. - - "ansible-playbook main.yml --syntax-check" - - # Copy test config.yml into place. - - "cp tests/config.yml config.yml" - - # Test the playbook. - - "travis_wait 30 ansible-playbook --extra-vars '{\"configure_sudoers\":\"false\"}' main.yml" - - # Test the playbook's idempotence. - - idempotence=$(mktemp) - - "ansible-playbook --extra-vars '{\"configure_sudoers\":\"false\"}' main.yml | tee -a ${idempotence}" - - > - tail ${idempotence} - | grep -q 'changed=0.*failed=0' - && (echo 'Idempotence test: pass' && exit 0) - || (echo 'Idempotence test: fail' && exit 1) diff --git a/.yamllint b/.yamllint new file mode 100644 index 000000000..71f676422 --- /dev/null +++ b/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 180 + level: warning + +ignore: | + .github/workflows/stale.yml diff --git a/README.md b/README.md index 1b3768f25..6fd53878a 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,50 @@ -# Mac Development Ansible Playbook - -[![Build Status](https://travis-ci.org/geerlingguy/mac-dev-playbook.svg?branch=master)](https://travis-ci.org/geerlingguy/mac-dev-playbook) - -This playbook installs and configures most of the software I use on my Mac for web and software development. Some things in macOS are slightly difficult to automate, so I still have some manual installation steps, but at least it's all documented here. +Mac Dev Playbook Logo -This is a work in progress, and is mostly a means for me to document my current Mac's setup. I'll be evolving this set of playbooks over time. +# Mac Development Ansible Playbook -*See also*: +[![CI][badge-gh-actions]][link-gh-actions] - - [Boxen](https://github.com/boxen) - - [Battleschool](http://spencer.gibb.us/blog/2014/02/03/introducing-battleschool) - - [osxc](https://github.com/osxc) - - [MWGriffin/ansible-playbooks](https://github.com/MWGriffin/ansible-playbooks) (the original inspiration for this project) +This playbook installs and configures most of the software I use on my Mac for web and software development. Some things in macOS are slightly difficult to automate, so I still have a few manual installation steps, but at least it's all documented here. ## Installation 1. Ensure Apple's command line tools are installed (`xcode-select --install` to launch the installer). - 2. [Install Ansible](http://docs.ansible.com/intro_installation.html). - 3. Clone this repository to your local drive. - 4. Run `$ ansible-galaxy install -r requirements.yml` inside this directory to install required Ansible roles. - 5. Run `ansible-playbook main.yml -i inventory -K` inside this directory. Enter your account password when prompted. + 2. [Install Ansible](https://docs.ansible.com/ansible/latest/installation_guide/index.html): + + 1. Run the following command to add Python 3 to your $PATH: `export PATH="$HOME/Library/Python/3.9/bin:/opt/homebrew/bin:$PATH"` + 2. Upgrade Pip: `sudo pip3 install --upgrade pip` + 3. Install Ansible: `pip3 install ansible` + + 3. Clone or download this repository to your local drive. + 4. Run `ansible-galaxy install -r requirements.yml` inside this directory to install required Ansible roles. + 5. Run `ansible-playbook main.yml --ask-become-pass` inside this directory. Enter your macOS account password when prompted for the 'BECOME' password. > Note: If some Homebrew commands fail, you might need to agree to Xcode's license or fix some other Brew issue. Run `brew doctor` to see if this is the case. +### Use with a remote Mac + +You can use this playbook to manage other Macs as well; the playbook doesn't even need to be run from a Mac at all! If you want to manage a remote Mac, either another Mac on your network, or a hosted Mac like the ones from [MacStadium](https://www.macstadium.com), you just need to make sure you can connect to it with SSH: + + 1. (On the Mac you want to connect to:) Go to System Preferences > Sharing. + 2. Enable 'Remote Login'. + +> You can also enable remote login on the command line: +> +> sudo systemsetup -setremotelogin on + +Then edit the `inventory` file in this repository and change the line that starts with `127.0.0.1` to: + +``` +[ip address or hostname of mac] ansible_user=[mac ssh username] +``` + +If you need to supply an SSH password (if you don't use SSH keys), make sure to pass the `--ask-pass` parameter to the `ansible-playbook` command. + ### Running a specific set of tagged tasks You can filter which part of the provisioning process to run by specifying a set of tags using `ansible-playbook`'s `--tags` flag. The tags available are `dotfiles`, `homebrew`, `mas`, `extra-packages` and `osx`. - ansible-playbook main.yml -i inventory -K --tags "dotfiles,homebrew" + ansible-playbook main.yml -K --tags "dotfiles,homebrew" ## Overriding Defaults @@ -35,31 +52,41 @@ Not everyone's development environment and preferred software configuration is t You can override any of the defaults configured in `default.config.yml` by creating a `config.yml` file and setting the overrides in that file. For example, you can customize the installed packages and apps with something like: - homebrew_installed_packages: - - cowsay - - git - - go - - mas_installed_apps: - - { id: 443987910, name: "1Password" } - - { id: 498486288, name: "Quick Resizer" } - - { id: 557168941, name: "Tweetbot" } - - { id: 497799835, name: "Xcode" } - - composer_packages: - - name: hirak/prestissimo - - name: drush/drush - version: '^8.1' - - gem_packages: - - name: bundler - state: latest - - npm_packages: - - name: webpack - - pip_packages: - - name: mkdocs +```yaml +homebrew_installed_packages: + - git + - go + +mas_installed_apps: + - { id: 443987910, name: "1Password" } + - { id: 498486288, name: "Quick Resizer" } + - { id: 557168941, name: "Tweetbot" } + - { id: 497799835, name: "Xcode" } + +composer_packages: + - name: hirak/prestissimo + - name: drush/drush + version: '^8.1' + +gem_packages: + - name: bundler + state: latest + +npm_packages: + - name: webpack + +pip_packages: + - name: mkdocs + +configure_dock: true +dockitems_remove: + - Launchpad + - TV +dockitems_persist: + - name: "Sublime Text" + path: "/Applications/Sublime Text.app/" + pos: 5 +``` Any variable can be overridden in `config.yml`; see the supporting roles' documentation for a complete list of available variables. @@ -67,7 +94,7 @@ Any variable can be overridden in `config.yml`; see the supporting roles' docume Applications (installed with Homebrew Cask): - - [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) + - [ChromeDriver](https://sites.google.com/chromium.org/driver/) - [Docker](https://www.docker.com/) - [Dropbox](https://www.dropbox.com/) - [Firefox](https://www.mozilla.org/en-US/firefox/new/) @@ -75,15 +102,11 @@ Applications (installed with Homebrew Cask): - [Handbrake](https://handbrake.fr/) - [Homebrew](http://brew.sh/) - [LICEcap](http://www.cockos.com/licecap/) - - [LimeChat](http://limechat.net/mac/) - - [MacVim](http://macvim-dev.github.io/macvim/) - [nvALT](http://brettterpstra.com/projects/nvalt/) - - [Sequel Pro](https://www.sequelpro.com/) (MySQL client) - - [Skitch](https://evernote.com/skitch/) + - [Sequel Ace](https://sequel-ace.com) (MySQL client) - [Slack](https://slack.com/) - [Sublime Text](https://www.sublimetext.com/) - [Transmit](https://panic.com/transmit/) (S/FTP client) - - [Vagrant](https://www.vagrantup.com/) Packages (installed with Homebrew): @@ -93,68 +116,43 @@ Packages (installed with Homebrew): - gettext - gifsicle - git + - gh - go - gpg - - hub - httpie - iperf - libevent - sqlite - - mcrypt - nmap - node - nvm - php - ssh-copy-id - - cowsay - readline - openssl - pv - wget - wrk + - zsh-history-substring-search My [dotfiles](https://github.com/geerlingguy/dotfiles) are also installed into the current user's home directory, including the `.osx` dotfile for configuring many aspects of macOS for better performance and ease of use. You can disable dotfiles management by setting `configure_dotfiles: no` in your configuration. Finally, there are a few other preferences and settings added on for various apps and services. -## Future additions - -### Things that still need to be done manually - -It's my hope that I can get the rest of these things wrapped up into Ansible playbooks soon, but for now, these steps need to be completed manually (assuming you already have Xcode and Ansible installed, and have run this playbook). +## Full / From-scratch setup guide - 1. Set JJG-Term as the default Terminal theme (it's installed, but not set as default automatically). - 2. Install [Sublime Package Manager](http://sublime.wbond.net/installation). - 3. Install all the apps that aren't yet in this setup (see below). - 4. Remap Caps Lock to Escape (requires macOS Sierra 10.12.1+). - 5. Set trackpad tracking rate. - 6. Set mouse tracking rate. - 7. Configure extra Mail and/or Calendar accounts (e.g. Google, Exchange, etc.). +Since I've used this playbook to set up something like 20 different Macs, I decided to write up a full 100% from-scratch install for my own reference (everyone's particular install will be slightly different). -### Applications/packages to be added: - -These are mostly direct download links, some are more difficult to install because of custom installers or other nonstandard install quirks: - - - [iShowU HD](http://www.shinywhitebox.com/downloads/iShowU_HD_2.3.20.dmg) - - [Adobe Creative Cloud](http://www.adobe.com/creativecloud.html) - -### Configuration to be added: - - - I have vim configuration in the repo, but I still need to add the actual installation: - ``` - mkdir -p ~/.vim/autoload - mkdir -p ~/.vim/bundle - cd ~/.vim/autoload - curl https://raw.githubusercontent.com/tpope/vim-pathogen/master/autoload/pathogen.vim > pathogen.vim - cd ~/.vim/bundle - git clone git://github.com/scrooloose/nerdtree.git - ``` +You can see my full from-scratch setup document here: [full-mac-setup.md](full-mac-setup.md). ## Testing the Playbook -Many people have asked me if I often wipe my entire workstation and start from scratch just to test changes to the playbook. Nope! Instead, I posted instructions for how I build a [Mac OS X VirtualBox VM](https://github.com/geerlingguy/mac-osx-virtualbox-vm), on which I can continually run and re-run this playbook to test changes and make sure things work correctly. +Many people have asked me if I often wipe my entire workstation and start from scratch just to test changes to the playbook. Nope! This project is [continuously tested on GitHub Actions' macOS infrastructure](https://github.com/geerlingguy/mac-dev-playbook/actions?query=workflow%3ACI). + +You can also run macOS itself inside a VM, for at least some of the required testing (App Store apps and some proprietary software might not install properly). I currently recommend: -Additionally, this project is [continuously tested on Travis CI's macOS infrastructure](https://travis-ci.org/geerlingguy/mac-dev-playbook). + - [UTM](https://mac.getutm.app) + - [Tart](https://github.com/cirruslabs/tart) ## Ansible for DevOps @@ -162,4 +160,7 @@ Check out [Ansible for DevOps](https://www.ansiblefordevops.com/), which teaches ## Author -[Jeff Geerling](https://www.jeffgeerling.com/), 2014 (originally inspired by [MWGriffin/ansible-playbooks](https://github.com/MWGriffin/ansible-playbooks)). +This project was created by [Jeff Geerling](https://www.jeffgeerling.com/) (originally inspired by [MWGriffin/ansible-playbooks](https://github.com/MWGriffin/ansible-playbooks)). + +[badge-gh-actions]: https://github.com/geerlingguy/mac-dev-playbook/actions/workflows/ci.yml/badge.svg +[link-gh-actions]: https://github.com/geerlingguy/mac-dev-playbook/actions/workflows/ci.yml diff --git a/ansible.cfg b/ansible.cfg index e3954851e..532d6335d 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,6 +1,6 @@ [defaults] +nocows = True roles_path = ./roles:/etc/ansible/roles - -[ssh_connection] -pipelining = True -control_path = /tmp/ansible-ssh-%%h-%%p-%%r +inventory = inventory +become = true +stdout_callback = yaml diff --git a/default.config.yml b/default.config.yml index 1757e5999..35aca2970 100644 --- a/default.config.yml +++ b/default.config.yml @@ -1,16 +1,33 @@ --- -downloads: ~/.ansible-downloads/ +configure_dotfiles: true +configure_terminal: true +configure_osx: true -configure_dotfiles: yes -configure_sudoers: yes -configure_terminal: yes -configure_osx: yes +# Set to 'true' to configure the Dock via dockutil. +configure_dock: false +dockitems_remove: [] +# - Launchpad +# - TV +# - Podcasts +# - 'App Store' +dockitems_persist: [] +# - name: "Sublime Text" +# path: "/Applications/Sublime Text.app/" +# pos: 5 + +configure_sudoers: false +sudoers_custom_config: "" +# Example: +# sudoers_custom_config: | +# # Allow users in admin group to use sudo with no password. +# %admin ALL=(ALL) NOPASSWD: ALL dotfiles_repo: https://github.com/geerlingguy/dotfiles.git -dotfiles_repo_accept_hostkey: yes -dotfiles_repo_local_destination: ~/Dropbox/Development/GitHub/dotfiles +dotfiles_repo_accept_hostkey: true +dotfiles_repo_local_destination: ~/Development/GitHub/dotfiles +dotfiles_repo_version: master # Replace with your default branch dotfiles_files: - - .bash_profile + - .zshrc - .gitignore - .inputrc - .osx @@ -24,29 +41,27 @@ homebrew_installed_packages: - gettext - gifsicle - git + - gh - go - gpg - - hub - httpie - iperf - libevent - sqlite - - mcrypt - nmap - node - nvm - php + - pngpaste - ssh-copy-id - - cowsay - readline - openssl - pv - wget - wrk + - zsh-history-substring-search -homebrew_taps: - - homebrew/core - - homebrew/cask +homebrew_taps: [] homebrew_cask_appdir: /Applications homebrew_cask_apps: @@ -57,15 +72,12 @@ homebrew_cask_apps: - google-chrome - handbrake - licecap - - macvim - - sequel-pro - - skitch + - sequel-ace - slack - sublime-text - transmit - - vagrant -# See `geerlingguy.mas` role documentation for usage instructions. +# See `geerlingguy.mac.mas` role documentation for usage instructions. mas_installed_apps: [] mas_email: "" mas_password: "" @@ -76,21 +88,39 @@ osx_script: "~/.osx --no-restart" # Note: You are responsible for making sure the required package managers are # installed, eg. through homebrew. composer_packages: [] - # - name: drush - # state: present # present/absent, default: present - # version: "^8.1" # default: N/A +# - name: drush +# state: present # present/absent, default: present +# version: "^8.1" # default: N/A gem_packages: [] - # - name: bundler - # state: present # present/absent/latest, default: present - # version: "~> 1.15.1" # default: N/A +# - name: bundler +# state: present # present/absent/latest, default: present +# version: "~> 1.15.1" # default: N/A npm_packages: [] - # - name: webpack - # state: present # present/absent/latest, default: present - # version: "^2.6" # default: N/A +# - name: webpack +# state: present # present/absent/latest, default: present +# version: "^2.6" # default: N/A pip_packages: [] - # - name: mkdocs - # state: present # present/absent/latest, default: present - # version: "0.16.3" # default: N/A +# - name: mkdocs +# state: present # present/absent/latest, default: present +# version: "0.16.3" # default: N/A + +# Set to 'true' to configure Sublime Text. +configure_sublime: false +sublime_base_path: "~/Library/Application Support/Sublime Text" +sublime_config_path: "Packages/User" +sublime_package_control: + - "DocBlockr" + - "Dockerfile Syntax Highlighting" + - "FileDiffs" + - "GitHub Flavored Markdown Preview" + - "Jinja2" + - "Package Control" + - "Pretty JSON" + - "SublimeLinter" + - "SublimeLinter-contrib-yamllint" + - "Theme - Cobalt2" + - "TrailingSpaces" + - "WordingStatus" # Glob pattern to ansible task files to run after all other tasks are finished. post_provision_tasks: [] diff --git a/files/Mac-Dev-Playbook-Logo.png b/files/Mac-Dev-Playbook-Logo.png new file mode 100644 index 000000000..e08e64675 Binary files /dev/null and b/files/Mac-Dev-Playbook-Logo.png differ diff --git a/files/sublime/Library/Packages/User/DashDoc.sublime-settings b/files/sublime/Library/Packages/User/DashDoc.sublime-settings deleted file mode 100644 index d7a97fc2a..000000000 --- a/files/sublime/Library/Packages/User/DashDoc.sublime-settings +++ /dev/null @@ -1,25 +0,0 @@ -{ - "syntax_sensitive_as_default": true, - "syntax_docset_map": - { - "CSS" : ["css", "bootstrap", "foundation", "less", "cordova", "phonegap"], - "Go" : ["go"], - "GoSublime" : ["go"], - "GoSublime-Go" : ["go"], - "HTML" : ["php", "html"], - "Java" : ["java", "javafx", "grails", "groovy", "playjava", "spring", "cvj", "processing"], - "JavaScript" : ["javascript", "jquery", "jqueryui", "jquerym", "backbone", "marionette", "meteor", "sproutcore", "moo", "prototype", "bootstrap", "foundation", "lodash", "underscore", "ember", "sencha", "extjs", "knockout", "zepto", "yui", "d3", "svg", "dojo", "coffee", "nodejs", "express", "mongoose", "grunt", "chai", "html", "css", "cordova", "phonegap", "unity3d", "titanium"], - "Markdown" : ["markdown"], - "Objective-C" : ["iphoneos", "macosx", "appledoc", "cocos2d", "cocos3d", "kobold2d", "sparrow", "c", "manpages"], - "PHP" : ["drupal", "php", "drupal", "symfony", "twig", "html", "mysql"], - "Puppet" : ["puppet"], - "Python" : ["python", "django", "twisted", "sphinx", "flask", "cvp"], - "Ruby" : ["ruby", "rubygems", "rails"], - "Ruby on Rails" : ["ruby", "rubygems", "rails"], - "Sass" : ["sass", "compass", "bourbon", "neat", "css"], - "Shell-Unix-Generic" : ["bash", "manpages"], - "SQL" : ["mysql", "sqlite", "psql"], - "TCL" : ["tcl"], - "YAML" : ["ansible", "yaml", "drupal"], - } -} diff --git a/files/sublime/Library/Packages/User/Package Control.sublime-settings b/files/sublime/Library/Packages/User/Package Control.sublime-settings deleted file mode 100644 index a0de2f98e..000000000 --- a/files/sublime/Library/Packages/User/Package Control.sublime-settings +++ /dev/null @@ -1,23 +0,0 @@ -{ - "auto_upgrade_last_run": null, - "installed_packages": - [ - "DashDoc", - "DocBlockr", - "Dockerfile Syntax Highlighting", - "Drupal Snippets", - "FileDiffs", - "GitHub Flavored Markdown Preview", - "Jinja2", - "MarkAndMove", - "Markdown Preview", - "Package Control", - "Puppet", - "RegReplace", - "Sass", - "SublimeCodeIntel", - "SublimeLinter", - "TrailingSpaces", - "Xdebug Client" - ] -} diff --git a/files/sublime/Library/Packages/User/Preferences.sublime-settings b/files/sublime/Library/Packages/User/Preferences.sublime-settings deleted file mode 100644 index 812fd296a..000000000 --- a/files/sublime/Library/Packages/User/Preferences.sublime-settings +++ /dev/null @@ -1,37 +0,0 @@ -{ - "color_scheme": "Packages/Color Scheme - Default/Cobalt.tmTheme", - "font_size": 12.0, - "ignored_packages": - [ - "Vintage" - ], - "rulers": - [ - 80 - ], - "line_numbers": true, - "gutter": true, - "margin": 4, - "fold_buttons": true, - "fade_fold_buttons": true, - "spell_check": false, - "tab_size": 2, - "translate_tabs_to_spaces": true, - "detect_indentation": true, - "auto_indent": true, - "smart_indent": true, - "trim_automatic_white_space": false, - "auto_match_enabled": true, - "draw_minimap_border": false, - "highlight_line": true, - "match_brackets": true, - "match_selection": true, - "draw_white_space": "selection", - "trim_trailing_white_space_on_save": false, - "ensure_newline_at_eof_on_save": false, - "folder_exclude_patterns": ["node_modules", ".svn", ".git", ".hg", "CVS", "vendor", ".bundle", ".vagrant"], - "file_exclude_patterns": ["*.pyc", "*.pyo", "*.exe", "*.dll", "*.obj","*.o", "*.a", "*.lib", "*.so", "*.dylib", "*.ncb", "*.sdf", "*.suo", "*.pdb", "*.idb", ".DS_Store", "*.class", "*.psd", "*.db", "*.sublime-workspace"], - "binary_file_patterns": ["generated/*", "*.tbz2", "*.gzip", "*.jpg", "*.jpeg", "*.png", "*.gif", "*.ttf", "*.tga", "*.dds", "*.ico", "*.eot", "*.pdf", "*.swf", "*.jar", "*.zip"] - "auto_complete": false, - "auto_complete_commit_on_tab": true, -} diff --git a/files/sublime/Markdown.sublime-settings b/files/sublime/Markdown.sublime-settings new file mode 100644 index 000000000..c6c9b9459 --- /dev/null +++ b/files/sublime/Markdown.sublime-settings @@ -0,0 +1,7 @@ +{ + "auto_complete": false, + "extensions": + [ + "txt" + ] +} diff --git a/files/sublime/Plain text.sublime-settings b/files/sublime/Plain text.sublime-settings new file mode 100644 index 000000000..c9fb4e6e2 --- /dev/null +++ b/files/sublime/Plain text.sublime-settings @@ -0,0 +1,5 @@ +{ + "extensions": + [ + ] +} diff --git a/files/sublime/Preferences.sublime-settings b/files/sublime/Preferences.sublime-settings new file mode 100644 index 000000000..c169b6114 --- /dev/null +++ b/files/sublime/Preferences.sublime-settings @@ -0,0 +1,414 @@ +{ + "added_words": + [ + "Kubernetes", + "Ansible", + "Mesos", + "de", + "K8s", + "stateful", + "filesystem", + "cron", + "kubeadm", + "kops", + "Terraform", + "geerlingguy", + "kubernetes", + "playbooks", + "Vagrantfile", + "lang", + "config", + "debian9", + "vm", + "virtualbox", + "cpus", + "ip", + "hostname", + "k8s", + "ansible", + "playbook", + "yml", + "terabyte", + "plugin", + "kube", + "pre", + "kubelet", + "playbook's", + "dev", + "debian", + "ce", + "amd64", + "src", + "cidr", + "kubectl", + "sudo", + "su", + "v1", + "etcd", + "Ansible's", + "openshift", + "nginx", + "metadata", + "apps", + "app", + "namespace", + "a4d", + "yaml", + "linenos", + "3m", + "inline", + "http", + "api", + "ok", + "init", + "rbac", + "gz", + "linux", + "v2", + "https", + "unarchive", + "usr", + "dest", + "tmp", + "cp", + "stdout", + "admin", + "io", + "dns", + "phpmyadmin", + "wordpress", + "jenkins", + "drupal", + "Ceph", + "Gluster", + "Dramble", + "Plugins", + "Jinja", + "templating", + "Dockerfiles", + "Dockerfile", + "Geerling", + "busybox", + "rmi", + "ps", + "localhost", + "python2", + "ubuntu1604", + "angstwad", + "Ubuntu", + "Angstwad's", + "www", + "mysql", + "env", + "py", + "mkdir", + "Werkzeug", + "sqlalchemy", + "html", + "Jinja2", + "libmysqlclient", + "j2", + "ubuntu16", + "awk", + "sbin", + "everything's", + "cd", + "plugins", + "winrm", + "saltstack", + "Hubot", + "hubot", + "args", + "js", + "npm", + "chdir", + "lineinfile", + "json", + "regexp", + "redis", + "heroku", + "a4dbot", + "Slack's", + "bot's", + "lifecycle", + "microservices", + "wildcard", + "Encrypt's", + "crypto", + "ssl", + "privkey", + "pem", + "csr", + "fullchain", + "selfsigned", + "pyopenssl", + "libssl", + "distros", + "iptables", + "cfg", + "tcp", + "python3", + "distro", + "vhosts", + "docroot", + "dir", + "refactor", + "idempotently", + "conf", + "Keychain", + "webservers", + "xyz", + "dbservers", + "httpd", + "rgb", + "dict", + "jinja", + "blog", + "Mazer's", + "Cisco", + "mv", + "endif", + "plugin's", + "versioning", + "namespaced", + "md", + "ruleset", + "ntp", + "parseable", + "foo", + "apache2", + "Diff", + "diffing", + "drush", + "php", + "url", + "multiline", + "nocows", + "java", + "workflows", + "devops", + "username", + "online", + "github", + "awx", + "cowsay", + "workflow", + "Rackspace", + "Uninstalling", + "uninstall", + "walkthrough", + "webhooks", + "Grafana", + "Rundeck", + "Drupal's", + "Symfony", + "Laravel", + "Joomla", + "idempotence", + "Drush's", + "Solr", + "solr", + "sha512", + "Solr's", + "openjdk", + "jdk", + "Ubuntu's", + "org", + "lucene", + "tgz", + "wget", + "txt", + "Andretti", + "devel", + "chkconfig", + "dicts", + "atl", + "subdomains", + "janedoe", + "vvvv", + "Vagrantfiles", + "admins", + "Remi", + "repo", + "epel", + "remi", + "rpms", + "remirepo", + "pki", + "gpg", + "enablerepo", + "nogpgcheck", + "firewalld", + "Remi's", + "disablerepo", + "req", + "scp", + "rsync", + "stderr", + "Forever's", + "nohup", + "app's", + "nodejs", + "pycurl", + "acl", + "ondrej", + "ppa", + "sendmail", + "php7", + "cli", + "gd", + "opcache", + "xml", + "mbstring", + "pdo", + "apcu", + "libpcre3", + "libapache2", + "mysqldb", + "ufw", + "a2enmod", + "virtualhost", + "a2ensite", + "a2dissite", + "symlinking", + "webmaster", + "ini", + "codebase", + "priv", + "cnf", + "phar" + ], + "auto_complete_commit_on_tab": true, + "auto_complete_delay": 200, + "auto_indent": true, + "auto_match_enabled": true, + "binary_file_patterns": + [ + "generated/*", + "*.tbz2", + "*.gzip", + "*.jpg", + "*.jpeg", + "*.png", + "*.gif", + "*.ttf", + "*.tga", + "*.dds", + "*.ico", + "*.eot", + "*.pdf", + "*.swf", + "*.jar", + "*.zip" + ], + "close_windows_when_empty": true, + "color_scheme": "Packages/Theme - Cobalt2/cobalt2.tmTheme", + "create_window_at_startup": false, + "detect_indentation": true, + "draw_minimap_border": false, + "draw_white_space": "selection", + "ensure_newline_at_eof_on_save": false, + "fade_fold_buttons": true, + "file_exclude_patterns": + [ + "*.pyc", + "*.pyo", + "*.exe", + "*.dll", + "*.obj", + "*.o", + "*.a", + "*.lib", + "*.so", + "*.dylib", + "*.ncb", + "*.sdf", + "*.suo", + "*.pdb", + "*.idb", + ".DS_Store", + "*.class", + "*.psd", + "*.db", + "*.sublime-workspace" + ], + "fold_buttons": true, + "folder_exclude_patterns": + [ + "node_modules", + ".svn", + ".git", + ".hg", + "CVS", + "vendor", + ".bundle", + ".vagrant" + ], + "font_size": 15.0, + "gpu_window_buffer": false, + "gutter": true, + "highlight_line": true, + "ignored_packages": + [ + "Vintage", + ], + "ignored_words": + [ + "0000ff", + "00f", + "12m", + "13m", + "5d", + "5m", + "6d", + "Phergie", + "Sutcliffe's", + "Uvh", + "ansicolor", + "awxcompose", + "configfile", + "examplenodeapp", + "getcomposer", + "googleapis", + "johndoe", + "johndoe1234", + "modifyvm", + "modulename", + "msg", + "node1", + "node2", + "oo", + "phergie", + "rf", + "rolename", + "si", + "v1beta1", + "var1", + "var2", + "varname", + "vg" + ], + "indent_guide_options": ["draw_normal", "draw_active"], + "hide_tab_scrolling_buttons": true, + "highlight_modified_tabs": true, + "line_padding_bottom": 1, + "line_padding_top": 1, + "caret_style": "blink", + "bold_folder_labels": false, + "line_numbers": true, + "margin": 4, + "match_brackets": true, + "match_selection": true, + "rulers": + [ + 80 + ], + "smart_indent": true, + "spell_check": false, + "tab_size": 2, + "theme": "Cobalt2.sublime-theme", + "translate_tabs_to_spaces": true, + "trim_automatic_white_space": false, + "trim_trailing_white_space_on_save": false, + "index_files": true, +} diff --git a/files/sublime/WordCount.sublime-settings b/files/sublime/WordCount.sublime-settings new file mode 100644 index 000000000..921d2b845 --- /dev/null +++ b/files/sublime/WordCount.sublime-settings @@ -0,0 +1,3 @@ +{ + "whitelist_syntaxes": ["Plain text", "Markdown"] +} diff --git a/files/terminal/JJG-Term.terminal b/files/terminal/JJG-Term.terminal index 288886d6a..d10f0ccd0 100644 --- a/files/terminal/JJG-Term.terminal +++ b/files/terminal/JJG-Term.terminal @@ -4,155 +4,151 @@ ANSIBlackColor - YnBsaXN0MDDUAQIDBAUGKyxYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKcHCBMZHSQoVSRudWxs1QkKCwwNDg8QERJcTlNDb21wb25lbnRzVU5TUkdCXE5T - Q29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29sb3JTcGFjZVYkY2xhc3NPECgwLjM4NDE0MzI4 - NDQgMC4zOTIzMTY1NDU4IDAuMzkyMzE2NTQ1OCAxTxAmMC4zMTA5OTExNjggMC4zMTg2 - NzQ4NjI0IDAuMzE4NTE0MDQ5MQAQAYACgAbTFBUNFhcYVE5TSURVTlNJQ0MQB4ADgAXS - Gg0bHFdOUy5kYXRhTxEMSAAADEhMaW5vAhAAAG1udHJSR0IgWFlaIAfOAAIACQAGADEA - AGFjc3BNU0ZUAAAAAElFQyBzUkdCAAAAAAAAAAAAAAAAAAD21gABAAAAANMtSFAgIAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWNwcnQA - AAFQAAAAM2Rlc2MAAAGEAAAAbHd0cHQAAAHwAAAAFGJrcHQAAAIEAAAAFHJYWVoAAAIY - AAAAFGdYWVoAAAIsAAAAFGJYWVoAAAJAAAAAFGRtbmQAAAJUAAAAcGRtZGQAAALEAAAA - iHZ1ZWQAAANMAAAAhnZpZXcAAAPUAAAAJGx1bWkAAAP4AAAAFG1lYXMAAAQMAAAAJHRl - Y2gAAAQwAAAADHJUUkMAAAQ8AAAIDGdUUkMAAAQ8AAAIDGJUUkMAAAQ8AAAIDHRleHQA - AAAAQ29weXJpZ2h0IChjKSAxOTk4IEhld2xldHQtUGFja2FyZCBDb21wYW55AABkZXNj - AAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAEnNSR0IgSUVDNjE5NjYt - Mi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAA - AG+iAAA49QAAA5BYWVogAAAAAAAAYpkAALeFAAAY2lhZWiAAAAAAAAAkoAAAD4QAALbP - ZGVzYwAAAAAAAAAWSUVDIGh0dHA6Ly93d3cuaWVjLmNoAAAAAAAAAAAAAAAWSUVDIGh0 - dHA6Ly93d3cuaWVjLmNoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAGRlc2MAAAAAAAAALklFQyA2MTk2Ni0yLjEgRGVmYXVsdCBSR0IgY29s - b3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAALklFQyA2MTk2Ni0yLjEgRGVmYXVsdCBS - R0IgY29sb3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAA - AAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVDNjE5NjYtMi4xAAAA - AAAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9uIGluIElFQzYxOTY2LTIu - MQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdmlldwAAAAAAE6T+ABRfLgAQzxQAA+3M - AAQTCwADXJ4AAAABWFlaIAAAAAAATAlWAFAAAABXH+dtZWFzAAAAAAAAAAEAAAAAAAAA - AAAAAAAAAAAAAAACjwAAAAJzaWcgAAAAAENSVCBjdXJ2AAAAAAAABAAAAAAFAAoADwAU - ABkAHgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAA - lQCaAJ8ApACpAK4AsgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZ - AR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB - 0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2 - AsECywLVAuAC6wL1AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD - 4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6 - BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoGewaMBp0GrwbABtEG - 4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+ - CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK - 8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1a - DXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQ - JhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMj - E0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwW - jxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoq - GlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYe - QB5qHpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKC - Iq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgn - SSd6J6sn3CgNKD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5 - LG4soizXLQwtQS12Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIx - ujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdg - N5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9 - oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQD - REdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRL - DEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIx - UnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbha - B1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1 - YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNpmmnxakhq - n2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNd - c7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF8 - 4X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZy - hteHO4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q - 1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtC - m6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqm - i6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHW - skuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++ - Cr6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4 - yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjX - XNfg2GTY6Nls2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz - 5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/y - jPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//4AE - 0h4fICFaJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhoyAiI1ZOU0RhdGFY - TlNPYmplY3TSHh8lJlxOU0NvbG9yU3BhY2WiJyNcTlNDb2xvclNwYWNl0h4fKSpXTlND - b2xvcqIpI18QD05TS2V5ZWRBcmNoaXZlctEtLlRyb290gAEACAARABoAIwAtADIANwA/ - AEUAUABdAGMAcACFAIwAtwDgAOIA5ADmAO0A8gD4APoA/AD+AQMBCw1XDVkNXg1pDXIN - gA2EDYsNlA2ZDaYNqQ22DbsNww3GDdgN2w3gAAAAAAAAAgEAAAAAAAAALwAAAAAAAAAA - AAAAAAAADeI= + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGmCwwXHR4lVSRudWxs1Q0ODxAR + EhMUFRZcTlNDb21wb25lbnRzVU5TUkdCXE5TQ29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29s + b3JTcGFjZVYkY2xhc3NPECgwLjM4NDE0MzI4NDQgMC4zOTIzMTY1NDU4IDAuMzkyMzE2 + NTQ1OCAxTxAmMC4zMTA5OTExNjggMC4zMTg2NzQ4NjI0IDAuMzE4NTE0MDQ5MQAQAYAC + gAXTGBkRGhscVE5TSURVTlNJQ0MQB4ADgARPEQxIAAAMSExpbm8CEAAAbW50clJHQiBY + WVogB84AAgAJAAYAMQAAYWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAAAAAAAPbW + AAEAAAAA0y1IUCAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAARY3BydAAAAVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAA + AgQAAAAUclhZWgAAAhgAAAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQA + AABwZG1kZAAAAsQAAACIdnVlZAAAA0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gAAAAU + bWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAABDwAAAgMZ1RSQwAABDwAAAgMYlRS + QwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTggSGV3bGV0dC1QYWNrYXJk + IENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAS + c1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAAARbMWFlaIAAAAAAAAAAAAAAA + AAAAAABYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAA + AAAAACSgAAAPhAAAts9kZXNjAAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAA + AAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAuSUVDIDYxOTY2LTIuMSBE + ZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAuSUVDIDYxOTY2 + LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAGRlc2MAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJ + RUM2MTk2Ni0yLjEAAAAAAAAAAAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24g + aW4gSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2aWV3AAAAAAAT + pP4AFF8uABDPFAAD7cwABBMLAANcngAAAAFYWVogAAAAAABMCVYAUAAAAFcf521lYXMA + AAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAKPAAAAAnNpZyAAAAAAQ1JUIGN1cnYAAAAA + AAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0A + cgB3AHwAgQCGAIsAkACVAJoAnwCkAKkArgCyALcAvADBAMYAywDQANUA2wDgAOUA6wDw + APYA+wEBAQcBDQETARkBHwElASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIB + mgGhAakBsQG5AcEByQHRAdkB4QHpAfIB+gIDAgwCFAIdAiYCLwI4AkECSwJUAl0CZwJx + AnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAMLAxYDIQMtAzgDQwNPA1oDZgNyA34D + igOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+BIwEmgSoBLYExATT + BOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZIBlkG + agZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgy + CEYIWghuCIIIlgiqCL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0K + VApqCoEKmAquCsUK3ArzCwsLIgs5C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgyn + DMAM2QzzDQ0NJg1ADVoNdA2ODakNww3eDfgOEw4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EP + Xg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExExEU8RbRGMEaoRyRHoEgcSJhJF + EmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIVNBVWFXgV + mxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkg + GUUZaxmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUd + Hh1HHXAdmR3DHeweFh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFI + IXUhoSHOIfsiJyJVIoIiryLdIwojOCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl + 9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhxKKIo1CkGKTgpaymdKdAqAio1KmgqmyrP + KwIrNitpK50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6CLrcu7i8kL1ovkS/HL/4w + NTBsMKQw2zESMUoxgjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01hzXC + Nf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o7 + 6DwnPGU8pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/iQCNAZECmQOdBKUFqQaxB7kIw + QnJCtUL3QzpDfUPARANER0SKRM5FEkVVRZpF3kYiRmdGq0bwRzVHe0fASAVIS0iRSNdJ + HUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAn + UHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSPVNtVKFV1VcJWD1ZcVqlW91dEV5JX + 4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3JXhpebF69Xw9fYV+z + YAVgV2CqYPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+lo + P2iWaOxpQ2maafFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDg + cTpxlXHwcktypnMBc11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6 + RnqlewR7Y3vCfCF8gXzhfUF9oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6 + hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZif6KZIrKizCLlov8jGOMyo0xjZiN + /45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSVX5XJljSWn5cKl3WX4JhM + mLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFHobaiJqKWowaj + dqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6h + rxavi7AAsHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6 + tbsuu6e8IbybvRW9j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbD + x0HHv8g9yLzJOsm5yjjKt8s2y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TT + xtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp22vvbgNwF3IrdEN2W3hzeot8p36/gNuC9 + 4UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp0Opb6uXrcOv77IbtEe2c7iju + tO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY + /Sn9uv5L/tz/bf//0h8gISJaJGNsYXNzbmFtZVgkY2xhc3Nlc1xOU0NvbG9yU3BhY2Wi + IyRcTlNDb2xvclNwYWNlWE5TT2JqZWN00h8gJidXTlNDb2xvcqImJAAIABEAGgAkACkA + MgA3AEkATABRAFMAWgBgAGsAeAB+AIsAoACnANIA+wD9AP8BAQEIAQ0BEwEVARcBGQ1l + DWoNdQ1+DYsNjg2bDaQNqQ2xAAAAAAAAAgEAAAAAAAAAKAAAAAAAAAAAAAAAAAAADbQ= ANSIBrightBlackColor - YnBsaXN0MDDUAQIDBAUGKyxYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKcHCBMZHSQoVSRudWxs1QkKCwwNDg8QERJcTlNDb21wb25lbnRzVU5TUkdCXE5T - Q29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29sb3JTcGFjZVYkY2xhc3NPECgwLjU5MjQ0MjEw - MzggMC41OTI0NDIxMDM4IDAuNTkyNDQyMTAzOCAxTxAnMC41MjE1MTQ1OTQ2IDAuNTIx - NDk5MDM3NyAwLjUyMTUwNzc5OTYAEAGAAoAG0xQVDRYXGFROU0lEVU5TSUNDEAeAA4AF - 0hoNGxxXTlMuZGF0YU8RDEgAAAxITGlubwIQAABtbnRyUkdCIFhZWiAHzgACAAkABgAx - AABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLUhQICAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFjcHJ0 - AAABUAAAADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAAABRyWFlaAAAC - GAAAABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRkAAACxAAA - AIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAAACR0 - ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0 - AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29tcGFueQAAZGVz - YwAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJzUkdCIElFQzYxOTY2 - LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAWFlaIAAAAAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAA - AABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2 - z2Rlc2MAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBo - dHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAABkZXNjAAAAAAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNv - bG91ciBzcGFjZSAtIHNSR0IAAAAAAAAAAAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQg - UkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAA - AAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9uIGluIElFQzYxOTY2LTIuMQAA - AAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0y - LjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAAABOk/gAUXy4AEM8UAAPt - zAAEEwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAAAAAAAAABAAAAAAAA - AAAAAAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQAAAAABQAKAA8A - FAAZAB4AIwAoAC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACBAIYAiwCQ - AJUAmgCfAKQAqQCuALIAtwC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwENARMB - GQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFuAXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJ - AdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJnAnECegKEAo4CmAKiAqwC - tgLBAssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNmA3IDfgOKA5YDogOuA7oDxwPT - A+AD7AP5BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME4QTwBP4FDQUcBSsF - OgVJBVgFZwV3BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAadBq8GwAbR - BuMG9QcHBxkHKwc9B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoI - vgjSCOcI+wkQCSUJOglPCWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrc - CvMLCwsiCzkLUQtpC4ALmAuwC8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUAN - Wg10DY4NqQ3DDd4N+A4TDi4OSQ5kDn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJ - ECYQQxBhEH4QmxC5ENcQ9RETETERTxFtEYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMT - IxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsUrRTOFPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZs - Fo8WshbWFvoXHRdBF2UXiReuF9IX9xgbGEAYZRiKGK8Y1Rj6GSAZRRlrGZEZtxndGgQa - KhpRGncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyjHMwc9R0eHUcdcB2ZHcMd7B4W - HkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEcIUghdSGhIc4h+yInIlUi - giKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3JicmVyaHJrcm6CcY - J0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2K2krnSvRLAUs - OSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDbMRIxSjGC - Mbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbpNyQ3 - YDecN9c4FDhQOIw4yDkFOUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1h - PaE94D4gPmA+oD7gPyE/YT+iP+JAI0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BE - A0RHRIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrE - SwxLU0uaS+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lPk0/dUCdQcVC7UQZRUFGbUeZS - MVJ8UsdTE1NfU6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfgWC9YfVjLWRpZaVm4 - WgdaVlqmWvVbRVuVW+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh - 9WJJYpxi8GNDY5dj62RAZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpI - ap9q92tPa6dr/2xXbK9tCG1gbbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFz - XXO4dBR0cHTMdSh1hXXhdj52m3b4d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyB - fOF9QX2hfgF+Yn7CfyN/hH/lgEeAqIEKgWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6G - cobXhzuHn4gEiGmIzokziZmJ/opkisqLMIuWi/yMY4zKjTGNmI3/jmaOzo82j56QBpBu - kNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaflwqXdZfgmEyYuJkkmZCZ/JpomtWb - QpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqImopajBqN2o+akVqTHpTilqaYa - poum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4trqGvFq+LsACwdbDqsWCx - 1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1uy67p7whvJu9Fb2P - vgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZGxsPHQce/yD3IvMk6ybnK - OMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnUy9VO1dHWVdbY - 11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj4+vk - c+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/ - 8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t//+A - BNIeHyAhWiRjbGFzc25hbWVYJGNsYXNzZXNdTlNNdXRhYmxlRGF0YaMgIiNWTlNEYXRh - WE5TT2JqZWN00h4fJSZcTlNDb2xvclNwYWNloicjXE5TQ29sb3JTcGFjZdIeHykqV05T - Q29sb3KiKSNfEA9OU0tleWVkQXJjaGl2ZXLRLS5Ucm9vdIABAAgAEQAaACMALQAyADcA - PwBFAFAAXQBjAHAAhQCMALcA4QDjAOUA5wDuAPMA+QD7AP0A/wEEAQwNWA1aDV8Nag1z - DYENhQ2MDZUNmg2nDaoNtw28DcQNxw3ZDdwN4QAAAAAAAAIBAAAAAAAAAC8AAAAAAAAA - AAAAAAAAAA3j + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGmCwwXHR4lVSRudWxs1Q0ODxAR + EhMUFRZcTlNDb21wb25lbnRzVU5TUkdCXE5TQ29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29s + b3JTcGFjZVYkY2xhc3NPECgwLjU5MjQ0MjEwMzggMC41OTI0NDIxMDM4IDAuNTkyNDQy + MTAzOCAxTxAnMC41MjE1MTQ1OTQ2IDAuNTIxNDk5MDM3NyAwLjUyMTUwNzc5OTYAEAGA + AoAF0xgZERobHFROU0lEVU5TSUNDEAeAA4AETxEMSAAADEhMaW5vAhAAAG1udHJSR0Ig + WFlaIAfOAAIACQAGADEAAGFjc3BNU0ZUAAAAAElFQyBzUkdCAAAAAAAAAAAAAAAAAAD2 + 1gABAAAAANMtSFAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAEWNwcnQAAAFQAAAAM2Rlc2MAAAGEAAAAbHd0cHQAAAHwAAAAFGJrcHQA + AAIEAAAAFHJYWVoAAAIYAAAAFGdYWVoAAAIsAAAAFGJYWVoAAAJAAAAAFGRtbmQAAAJU + AAAAcGRtZGQAAALEAAAAiHZ1ZWQAAANMAAAAhnZpZXcAAAPUAAAAJGx1bWkAAAP4AAAA + FG1lYXMAAAQMAAAAJHRlY2gAAAQwAAAADHJUUkMAAAQ8AAAIDGdUUkMAAAQ8AAAIDGJU + UkMAAAQ8AAAIDHRleHQAAAAAQ29weXJpZ2h0IChjKSAxOTk4IEhld2xldHQtUGFja2Fy + ZCBDb21wYW55AABkZXNjAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAA + EnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAAAAAAAA + AAAAAAAAWFlaIAAAAAAAAG+iAAA49QAAA5BYWVogAAAAAAAAYpkAALeFAAAY2lhZWiAA + AAAAAAAkoAAAD4QAALbPZGVzYwAAAAAAAAAWSUVDIGh0dHA6Ly93d3cuaWVjLmNoAAAA + AAAAAAAAAAAWSUVDIGh0dHA6Ly93d3cuaWVjLmNoAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRlc2MAAAAAAAAALklFQyA2MTk2Ni0yLjEg + RGVmYXVsdCBSR0IgY29sb3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAALklFQyA2MTk2 + Ni0yLjEgRGVmYXVsdCBSR0IgY29sb3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAAAAAA + AAAAAAAAAABkZXNjAAAAAAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4g + SUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9u + IGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdmlldwAAAAAA + E6T+ABRfLgAQzxQAA+3MAAQTCwADXJ4AAAABWFlaIAAAAAAATAlWAFAAAABXH+dtZWFz + AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAACjwAAAAJzaWcgAAAAAENSVCBjdXJ2AAAA + AAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABt + AHIAdwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4AsgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA + 8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGS + AZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcC + cQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+ + A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE + 0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZ + BmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8I + MghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9 + ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4M + pwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9B + D14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYS + RRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4 + FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZ + IBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1 + HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwh + SCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXH + JfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsq + zysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwugi63Lu4vJC9aL5Evxy/+ + MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1 + wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuq + O+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlBakGsQe5C + MEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjX + SR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91Q + J1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFapVvdXRFeS + V+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ff + s2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fp + aD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw + 4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnn + ekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eD + uoQdhICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Y + jf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CY + TJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMG + o3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2u + oa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7 + urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbG + w8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE + 08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4Dbg + veFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o + 7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8 + mP0p/br+S/7c/23//9IfICEiWiRjbGFzc25hbWVYJGNsYXNzZXNcTlNDb2xvclNwYWNl + oiMkXE5TQ29sb3JTcGFjZVhOU09iamVjdNIfICYnV05TQ29sb3KiJiQACAARABoAJAAp + ADIANwBJAEwAUQBTAFoAYABrAHgAfgCLAKAApwDSAPwA/gEAAQIBCQEOARQBFgEYARoN + Zg1rDXYNfw2MDY8NnA2lDaoNsgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAA21 BackgroundAlphaInactive 0.73865855823863635 @@ -162,31 +158,31 @@ 0.50397283380681823 BackgroundColor - YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPEDcw - LjA3ODcxOTQyOTM1IDAuMDc4NzE5NDI5MzUgMC4wNzg3MTk0MjkzNSAwLjg5OTM0MDY3 - OTIAEAGAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVj - dF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltinJ6gpbC5wcTN - 3+LnAAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAAOk= + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVO + U1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAqMC4wNzg3MTk0MjkzNSAwLjA3ODcxOTQy + OTM1IDAuMDc4NzE5NDI5MzUAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlND + b2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+q62vtL/I0NMAAAAAAAABAQAA + AAAAAAAZAAAAAAAAAAAAAAAAAAAA3A== BackgroundSettingsForInactiveWindows CursorColor - YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKMHCA9VJG51bGzTCQoLDA0OV05TV2hpdGVcTlNDb2xvclNwYWNlViRjbGFzc0sw - LjMwMjQxOTM2ABADgALSEBESE1okY2xhc3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRY - TlNPYmplY3RfEA9OU0tleWVkQXJjaGl2ZXLRFxhUcm9vdIABCBEaIy0yNztBSFBdZHBy - dHmEjZWYobO2uwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC9 + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxAREldO + U1doaXRlXE5TQ29sb3JTcGFjZVYkY2xhc3NLMC4zMDI0MTkzNgAQA4AC0hQVFhdaJGNs + YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRs + eYCMjpCVoKmxtAAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC9 Font - YnBsaXN0MDDUAQIDBAUGGBlYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKQHCBESVSRudWxs1AkKCwwNDg8QVk5TU2l6ZVhOU2ZGbGFnc1ZOU05hbWVWJGNs - YXNzI0AsAAAAAAAAEBCAAoADWENvbnNvbGFz0hMUFRZaJGNsYXNzbmFtZVgkY2xhc3Nl - c1ZOU0ZvbnSiFRdYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2ZXLRGhtUcm9vdIABCBEa - Iy0yNzxCS1JbYmlydHZ4gYaRmqGkrb/CxwAAAAAAAAEBAAAAAAAAABwAAAAAAAAAAAAA - AAAAAADJ + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGkCwwVFlUkbnVsbNQNDg8QERIT + FFZOU1NpemVYTlNmRmxhZ3NWTlNOYW1lViRjbGFzcyNALAAAAAAAABAQgAKAA11TRk1v + bm8tTWVkaXVt0hcYGRpaJGNsYXNzbmFtZVgkY2xhc3Nlc1ZOU0ZvbnSiGRtYTlNPYmpl + Y3QIERokKTI3SUxRU1heZ253foWOkJKUoqeyu8LFAAAAAAAAAQEAAAAAAAAAHAAAAAAA + AAAAAAAAAAAAAM4= FontAntialias @@ -195,18 +191,18 @@ Linewrap ProfileCurrentVersion - 2.0600000000000001 + 2.0699999999999998 RestoreLines 2000 ScrollbackLines 50000 SelectionColor - YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKMHCA9VJG51bGzTCQoLDA0OV05TV2hpdGVcTlNDb2xvclNwYWNlViRjbGFzc0sw - LjI1NDAzMjI1ABADgALSEBESE1okY2xhc3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRY - TlNPYmplY3RfEA9OU0tleWVkQXJjaGl2ZXLRFxhUcm9vdIABCBEaIy0yNztBSFBdZHBy - dHmEjZWYobO2uwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC9 + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxAREldO + U1doaXRlXE5TQ29sb3JTcGFjZVYkY2xhc3NLMC4yNTQwMzIyNQAQA4AC0hQVFhdaJGNs + YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRs + eYCMjpCVoKmxtAAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC9 ShouldLimitScrollback 1 @@ -216,19 +212,19 @@ xterm-color TextBoldColor - YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKMHCA9VJG51bGzTCQoLDA0OV05TV2hpdGVcTlNDb2xvclNwYWNlViRjbGFzc0Ix - ABADgALSEBESE1okY2xhc3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3Rf - EA9OU0tleWVkQXJjaGl2ZXLRFxhUcm9vdIABCBEaIy0yNztBSFBdZGdpa3B7hIyPmKqt - sgAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC0 + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxAREldO + U1doaXRlXE5TQ29sb3JTcGFjZVYkY2xhc3NCMQAQA4AC0hQVFhdaJGNsYXNzbmFtZVgk + Y2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRseYCDhYeMl6Co + qwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC0 TextColor - YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS - AAGGoKMHCA9VJG51bGzTCQoLDA0OV05TV2hpdGVcTlNDb2xvclNwYWNlViRjbGFzc0sw - Ljk0NzU4MDY0ABADgALSEBESE1okY2xhc3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRY - TlNPYmplY3RfEA9OU0tleWVkQXJjaGl2ZXLRFxhUcm9vdIABCBEaIy0yNztBSFBdZHBy - dHmEjZWYobO2uwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC9 + YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS + AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxAREldO + U1doaXRlXE5TQ29sb3JTcGFjZVYkY2xhc3NLMC45NDc1ODA2NAAQA4AC0hQVFhdaJGNs + YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRs + eYCMjpCVoKmxtAAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAAC9 UseBrightBold diff --git a/full-mac-setup.md b/full-mac-setup.md new file mode 100644 index 000000000..cfd9c419f --- /dev/null +++ b/full-mac-setup.md @@ -0,0 +1,118 @@ +# Full Mac Setup Process (for Jeff Geerling) + +There are some things in life that just can't be automated... or aren't 100% worth the time :( + +This document covers that, at least in terms of setting up a brand new Mac out of the box. + +## Initial configuration of a brand new Mac + +Before starting, I completed Apple's mandatory macOS setup wizard (creating a local user account, and optionally signing into my iCloud account). Once on the macOS desktop, I do the following (in order): + + - Install Ansible (following the guide in [README.md](README.md)) + - **Sign in to App Store** (since `mas` can't sign in automatically) + - Clone mac-dev-playbook to the Mac: `git clone git@github.com:geerlingguy/mac-dev-playbook.git` + - Drop `config.yml` from `~/Dropbox/Apps/Config` to the playbook (copy over the network or using a USB flash drive). + - Run the playbook. + - If there are errors, you may need to finish up other tasks like installing 'old-fashioned' apps first (since I try to place Photoshop in the Dock and it can't be installed automatically). Then, run the playbook again ;) + - Start Synchronization tasks: + - Open Photos and make sure iCloud sync options are correct + - Open Music, make sure computer is authorized, and set Library sync options + - Open Dropbox, sign in, and set up sync + - Install or complete setup for old-fashioned apps: + - Open Creative Cloud, sign in, and install needed apps + - Open iStat Menus and configure CPU/Net/Temp Combined view + - (If required:) + - Install [Elgato Stream Deck](https://www.elgato.com/en/downloads) + - Open Livestream profile inside `~/Dropbox/Apps/Config/Stream Deck` + - Install [Elgato Key Light Air (Control Center)](https://www.elgato.com/en/downloads) + - Install [Autodesk Fusion 360](https://www.autodesk.com) + - Install Microsoft Office Home & Student 2019 (https://account.microsoft.com/services/) + - Install [Fritzing](https://fritzing.org/download/) + - Configure FastMail account: + - Log into Fastmail + - Go to settings, then Privacy & Security + - Create a new app password, and on that page, download the configuration file + - Open the downloaded profile, then go to System Preferences, and Device Management + - Double-click on the Fastmail profile + - Click 'Install...' and install it + - Configure which accounts are enabled in the 'Internet Accounts' System Preferences pane + - Open Calendar and enable personal Google CalDAV account (you have to manually sign in). + - Manually copy `~/Development` folder from another Mac (to save time). + - Manual settings to automate someday: + - Finder: + - Disable click-to-show Desktop: `defaults write com.apple.WindowManager EnableStandardClickToShowDesktop -bool false` + - System Preferences: + - Accessibility > Display > Reduce transparency + - Keyboard > Keyboard Shortcuts... > Modifier Keys... > Caps Lock to Esc + - Keyboard > Key repeat rate to 'Fast', Delay until repeat to 'Short' + - Privacy & Security > Full Disk Access > enable "Terminal" + - Safari: + - View > Show Status Bar + - Preferences > Advanced > "Show full website address" + - Preferences > Advanced > "Show features for web developers" + - Install the 'Return YouTube Dislike' Userscript in Userscripts + - Dock: + - Add jgeerling, Downloads, Applications, and shared "mercury" folders + - Final Cut Pro + - Install FxFactory and sign in: https://fxfactory.com + - Copy contents of `~/Development/youtube/fcpx` into respective directories + - These things might be automatable, but I do them manually right now: + - Configure Time Machine backup drive + - Install Wireguard VPN configurations (if needed) + +## To Wrap in Post-provision automation + +The following tasks have to wait for the initial Dropbox sync to complete before they'll succeed. So ideally I'll stick this all in a post-provision script but somehow flag it not to run on first provision. + +``` +# ZSH Aliases. +ln -s /Users/jgeerling/Dropbox/Apps/Config/.aliases /Users/jgeerling/.aliases + +# Electrum BTC Wallet (open Electrum first). +ln -s /Users/jgeerling/Dropbox/Apps/Electrum/default_wallet /Users/jgeerling/.electrum/wallets/default_wallet + +# SSH setup. +ssh-keygen # and create a default key to set up .ssh folder +sudo ln -s /Users/jgeerling/Dropbox/Apps/Config/ssh/config ~/.ssh/config +# TODO - Manually copy any shared SSH keys that are needed. + +# Ansible setup. +sudo mkdir -p /etc/ansible +sudo ln -s /Users/jgeerling/Dropbox/Apps/Config/ansible/ansible.cfg /etc/ansible/ansible.cfg +sudo ln -s /Users/jgeerling/Dropbox/Apps/Config/ansible/hosts /etc/ansible/hosts +sudo ln -s /Users/jgeerling/Dropbox/VMs/roles /etc/ansible/roles +mkdir -p /Users/jgeerling/.ansible +ln -s /Users/jgeerling/Dropbox/Apps/Config/ansible/galaxy_token /Users/jgeerling/.ansible/galaxy_token +ln -s /Users/jgeerling/Dropbox/Apps/Config/ansible/mm-vault-password.txt /Users/jgeerling/.ansible/mm-vault-password.txt +ln -s /Users/jgeerling/Dropbox/VMs/ansible_collections /Users/jgeerling/.ansible/collections + +# Final Cut Pro setup. (Open Motion first) +cp -r /Users/jgeerling/Dropbox/Apps/Config/Motion/Motion\ Templates.localized/ /Users/jgeerling/Movies/Motion\ Templates.localized/ +cp -r /Users/jgeerling/Dropbox/Apps/Config/Motion/Text\ Styles/ /Users/jgeerling/Library/Application\ Support/Motion/Library/Text\ Styles.localized/ + +# Sequel Ace favorites. (Open Sequel Ace first) +cp /Users/jgeerling/Dropbox/Apps/Config/Sequel\ Ace/Favorites.plist /Users/jgeerling/Library/Containers/com.sequel-ace.sequel-ace/Data/Library/Application\ Support/Sequel\ Ace/Data/Favorites.plist + +# Font setup. +cp ~/Dropbox/Apps/Config/Fonts/* ~/Library/Fonts/ + +# Vim setup. +mkdir -p ~/.vim/autoload +mkdir -p ~/.vim/bundle +cd ~/.vim/autoload +curl https://raw.githubusercontent.com/tpope/vim-pathogen/master/autoload/pathogen.vim > pathogen.vim +cd ~/.vim/bundle +git clone https://github.com/preservim/nerdtree.git +``` + +## When formatting old Mac + + - Sign out of Adobe Creative Cloud + - Sign out of Panic Sync in Transmit + - Deauthorize Apple Music in iTunes/Music App + - Make sure anything new merged into `~/Dropbox/Apps/Config`: + - Fonts from ~/Library/Fonts + - Motion Plugins from ~/Movies/Motion + - Final Cut Pro Text Styles in ~/Library/Application Support/Motion/Library/Text Styles + - Sequel Ace shortcuts from ~/Library/Containers/com.sequel-ace.sequel-ace/Data/Library/Application\ Support/Sequel\ Ace/Data/Favorites.plist + - Follow Apple's guide [here](https://support.apple.com/en-au/HT212749) diff --git a/inventory b/inventory index 0dd74f155..5b7201063 100644 --- a/inventory +++ b/inventory @@ -1,2 +1,2 @@ -[localhost] -127.0.0.1 +[all] +127.0.0.1 ansible_connection=local diff --git a/main.yml b/main.yml index 12ef55e9d..500c91766 100644 --- a/main.yml +++ b/main.yml @@ -1,44 +1,56 @@ --- -- hosts: all - connection: local +- name: Configure host. + hosts: all vars_files: - default.config.yml pre_tasks: - - include_vars: "{{ item }}" + - name: Include playbook configuration. + include_vars: "{{ item }}" with_fileglob: - "{{ playbook_dir }}/config.yml" tags: ['always'] roles: - - role: geerlingguy.homebrew + - role: elliotweiser.osx-command-line-tools + - role: geerlingguy.mac.homebrew tags: ['homebrew'] - role: geerlingguy.dotfiles when: configure_dotfiles tags: ['dotfiles'] - - role: geerlingguy.mas - when: mas_installed_apps + - role: geerlingguy.mac.mas + when: mas_installed_apps or mas_installed_app_ids tags: ['mas'] + - role: geerlingguy.mac.dock + when: configure_dock + tags: ['dock'] tasks: - - include_tasks: tasks/ansible-setup.yml - - - include_tasks: tasks/sudoers.yml + - import_tasks: tasks/sudoers.yml when: configure_sudoers + tags: ['sudoers'] - - include_tasks: tasks/terminal.yml + - import_tasks: tasks/terminal.yml when: configure_terminal + tags: ['terminal'] - - include_tasks: tasks/osx.yml + - import_tasks: tasks/osx.yml when: configure_osx tags: ['osx'] - - include_tasks: tasks/extra-packages.yml + - import_tasks: tasks/extra-packages.yml tags: ['extra-packages'] - - name: Run configured post-provision ansible task files. - include_tasks: "{{ outer_item }}" - loop_control: - loop_var: outer_item - with_fileglob: "{{ post_provision_tasks|default(omit) }}" + - import_tasks: tasks/sublime-text.yml + when: configure_sublime + tags: ['sublime-text'] + + - name: Run post-provision task files in a block. + tags: ['post'] + block: + - name: Run configured post-provision ansible task files. + include_tasks: "{{ outer_item }}" + loop_control: + loop_var: outer_item + with_fileglob: "{{ post_provision_tasks | default(omit) }}" diff --git a/requirements.yml b/requirements.yml index a64b14976..f5815ad80 100644 --- a/requirements.yml +++ b/requirements.yml @@ -1,4 +1,7 @@ --- -- name: geerlingguy.dotfiles -- name: geerlingguy.homebrew -- name: geerlingguy.mas +roles: + - name: elliotweiser.osx-command-line-tools + - name: geerlingguy.dotfiles + +collections: + - name: geerlingguy.mac diff --git a/tasks/ansible-setup.yml b/tasks/ansible-setup.yml deleted file mode 100644 index efa950893..000000000 --- a/tasks/ansible-setup.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: Ensure Ansible downloads directory exists. - file: - path: "{{ downloads }}" - state: directory - -- name: Ensure /etc/ansible directory exists. - file: - path: /etc/ansible - state: directory - become: yes - -- name: Symlink /usr/local/etc/ansible to /etc/ansible. - file: - src: /etc/ansible - path: /usr/local/etc/ansible - state: link diff --git a/tasks/extra-packages.yml b/tasks/extra-packages.yml index ee9254c8f..294fdaace 100644 --- a/tasks/extra-packages.yml +++ b/tasks/extra-packages.yml @@ -5,30 +5,30 @@ arguments: "{{ item.name | default(item) }} {{ item.version | default('@stable') }}" # Ansible 2.4 supports `global_command` making `working_dir` optional. working_dir: "{{ lookup('env', 'COMPOSER_HOME') | default('~/.composer', true) }}" - with_items: "{{ composer_packages }}" + loop: "{{ composer_packages }}" - name: Install global NPM packages. npm: name: "{{ item.name | default(item) }}" state: "{{ item.state | default('present') }}" version: "{{ item.version | default(omit) }}" - global: yes + global: true executable: "{{ item.executable | default(omit) }}" - with_items: "{{ npm_packages }}" + loop: "{{ npm_packages }}" - name: Install global Pip packages. pip: name: "{{ item.name | default(item) }}" state: "{{ item.state | default('present') }}" version: "{{ item.version | default(omit) }}" - executable: "{{ item.executable | default(omit) }}" - with_items: "{{ pip_packages }}" + executable: "{{ item.executable | default('pip3') }}" + loop: "{{ pip_packages }}" - name: Install global Ruby gems. gem: name: "{{ item.name | default(item) }}" state: "{{ item.state | default('present') }}" version: "{{ item.version | default(omit) }}" - user_install: no + user_install: false executable: "{{ item.executable | default(omit) }}" - with_items: "{{ gem_packages }}" + loop: "{{ gem_packages }}" diff --git a/tasks/osx.yml b/tasks/osx.yml index b952d90db..ec12cd524 100644 --- a/tasks/osx.yml +++ b/tasks/osx.yml @@ -1,5 +1,5 @@ --- # TODO: Use sudo once .osx can be run via root with no user interaction. - name: Run .osx dotfiles. - shell: "{{ osx_script }}" + command: "{{ osx_script }}" changed_when: false diff --git a/tasks/sublime-text.yml b/tasks/sublime-text.yml new file mode 100644 index 000000000..d07f7698a --- /dev/null +++ b/tasks/sublime-text.yml @@ -0,0 +1,28 @@ +--- +- name: Ensure Sublime Text directories exist. + file: + path: "{{ item }}" + state: directory + loop: + - "{{ sublime_base_path }}/{{ sublime_config_path }}" + - "{{ sublime_base_path }}/Installed Packages" + +- name: Ensure Sublime Package Control is installed. + get_url: + url: "https://packagecontrol.io/Package%20Control.sublime-package" + dest: "{{ sublime_base_path }}/Installed Packages/Package Control.sublime-package" + +- name: Ensure Sublime Package Control Packages are configured. + template: + src: templates/Package_Control.sublime-settings.j2 + dest: "{{ sublime_base_path }}/{{ sublime_config_path }}/Package Control.sublime-settings" + +- name: Ensure Sublime text user Preferences and theme are set. + copy: + src: "files/sublime/{{ item }}" + dest: "{{ sublime_base_path }}/{{ sublime_config_path }}/{{ item }}" + loop: + - "Markdown.sublime-settings" + - "Plain text.sublime-settings" + - "Preferences.sublime-settings" + - "WordCount.sublime-settings" diff --git a/tasks/sudoers.yml b/tasks/sudoers.yml index 4a39c2010..55cf05c9a 100644 --- a/tasks/sudoers.yml +++ b/tasks/sudoers.yml @@ -11,11 +11,11 @@ sed_path: "{{ sed_which_result.stdout }}" when: sed_path is undefined -# Sudoers configuration (enables more convenient Vagrant usage). +# Sudoers configuration. - name: Copy sudoers configuration into place. - template: - src: templates/sudoers.j2 - dest: /etc/sudoers + copy: + content: "{{ sudoers_custom_config }}" + dest: /private/etc/sudoers.d/custom mode: 0440 validate: 'visudo -cf %s' - become: yes + become: true diff --git a/tasks/terminal.yml b/tasks/terminal.yml index 278450d78..b1a6d6e8c 100644 --- a/tasks/terminal.yml +++ b/tasks/terminal.yml @@ -1,19 +1,27 @@ --- # Custom Terminal theme. - name: Get current Terminal profile. - shell: defaults read com.apple.terminal 'Default Window Settings' + command: defaults read com.apple.terminal 'Default Window Settings' register: terminal_theme changed_when: false - check_mode: no + failed_when: false + check_mode: false - name: Ensure custom Terminal profile is added. - shell: open files/terminal/JJG-Term.terminal + copy: + src: files/terminal/JJG-Term.terminal + dest: /tmp/JJG-Term.terminal + changed_when: false + when: "'JJG-Term' not in terminal_theme.stdout" + +- name: Ensure custom Terminal profile is added. + command: open /tmp/JJG-Term.terminal changed_when: false when: "'JJG-Term' not in terminal_theme.stdout" # TODO: This doesn't work in Yosemite. Consider a different solution? - name: Ensure custom Terminal profile is set as default. - shell: "{{ item }}" + command: "{{ item }}" with_items: - defaults write com.apple.terminal 'Default Window Settings' -string JJG-Term - defaults write com.apple.terminal 'Startup Window Settings' -string JJG-Term diff --git a/templates/Package_Control.sublime-settings.j2 b/templates/Package_Control.sublime-settings.j2 new file mode 100755 index 000000000..5275151e4 --- /dev/null +++ b/templates/Package_Control.sublime-settings.j2 @@ -0,0 +1,13 @@ +{ + "auto_upgrade_last_run": null, + "bootstrapped": true, + "in_process_packages": + [ + ], + "installed_packages": + [ +{% for package in sublime_package_control %} + "{{ package }}"{% if not loop.last %},{% endif %} +{% endfor %} +], +} diff --git a/templates/sudoers.j2 b/templates/sudoers.j2 deleted file mode 100644 index ea4be0c18..000000000 --- a/templates/sudoers.j2 +++ /dev/null @@ -1,53 +0,0 @@ -# sudoers file. -# -# This file MUST be edited with the 'visudo' command as root. -# Failure to use 'visudo' may result in syntax or file permission errors -# that prevent sudo from running. -# -# See the sudoers man page for the details on how to write a sudoers file. -# - -# Host alias specification - -# User alias specification - -# Cmnd alias specification - -# Defaults specification -Defaults env_reset -Defaults env_keep += "BLOCKSIZE" -Defaults env_keep += "COLORFGBG COLORTERM" -Defaults env_keep += "__CF_USER_TEXT_ENCODING" -Defaults env_keep += "CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE" -Defaults env_keep += "LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME" -Defaults env_keep += "LINES COLUMNS" -Defaults env_keep += "LSCOLORS" -Defaults env_keep += "SSH_AUTH_SOCK" -Defaults env_keep += "TZ" -Defaults env_keep += "DISPLAY XAUTHORIZATION XAUTHORITY" -Defaults env_keep += "EDITOR VISUAL" -Defaults env_keep += "HOME MAIL" - -# Runas alias specification - -# User privilege specification -root ALL=(ALL) ALL -%admin ALL=(ALL) ALL - -# Uncomment to allow people in group wheel to run all commands -# %wheel ALL=(ALL) ALL - -# Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL - -# Samples -# %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom -# %users localhost=/sbin/shutdown -h now - -# Vagrant sudoers config -Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports -Cmnd_Alias VAGRANT_NFSD = /sbin/nfsd restart -Cmnd_Alias VAGRANT_EXPORTS_REMOVE = {{ sed_path }} -E -e /*/ d -ibak /etc/exports -Cmnd_Alias VAGRANT_HOSTS_ADD = /bin/sh -c echo "*" >> /etc/hosts -Cmnd_Alias VAGRANT_HOSTS_REMOVE = {{ sed_path }} -i -e /*/ d /etc/hosts -%admin ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD, VAGRANT_EXPORTS_REMOVE, VAGRANT_HOSTS_ADD, VAGRANT_HOSTS_REMOVE diff --git a/tests/ansible.cfg b/tests/ansible.cfg new file mode 100644 index 000000000..f8fc6cdba --- /dev/null +++ b/tests/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +inventory = inventory diff --git a/tests/config.yml b/tests/config.yml index d67f3bc0b..9631a151e 100644 --- a/tests/config.yml +++ b/tests/config.yml @@ -1,10 +1,10 @@ +--- homebrew_installed_packages: - autoconf - bash-completion - gettext - sqlite - ssh-copy-id - - cowsay - readline - pv - wget @@ -12,4 +12,4 @@ homebrew_installed_packages: homebrew_cask_apps: - firefox - - macvim + - licecap diff --git a/tests/inventory b/tests/inventory new file mode 100644 index 000000000..13cfabe9b --- /dev/null +++ b/tests/inventory @@ -0,0 +1,2 @@ +[local] +localhost ansible_connection=local diff --git a/tests/uninstall-homebrew.sh b/tests/uninstall-homebrew.sh new file mode 100755 index 000000000..40e1bf183 --- /dev/null +++ b/tests/uninstall-homebrew.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Uninstalls Homebrew using the official uninstall script. + +# Download and run the uninstall script. +curl -sLO https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh +chmod +x ./uninstall.sh +sudo ./uninstall.sh --force + +# Clean up Homebrew directories. +sudo rm -rf /usr/local/Homebrew +sudo rm -rf /usr/local/Caskroom +sudo rm -rf /usr/local/bin/brew +sudo rm -rf /opt/homebrew