From 87aa5aa5b86d2ed676460a6e77544a90f28c6a4b Mon Sep 17 00:00:00 2001 From: kj Date: Tue, 4 Aug 2020 01:14:24 -0400 Subject: [PATCH] Agregado web-mode para usarlo en lugar de html-mode. --- .../web-mode-autoloads.el | 27 + elpa/web-mode-20200612.1038/web-mode-pkg.el | 2 + elpa/web-mode-20200612.1038/web-mode.el | 14312 ++++++++++++++++ elpa/web-mode-20200612.1038/web-mode.elc | Bin 0 -> 330905 bytes init.el | 11 +- 5 files changed, 14350 insertions(+), 2 deletions(-) create mode 100644 elpa/web-mode-20200612.1038/web-mode-autoloads.el create mode 100644 elpa/web-mode-20200612.1038/web-mode-pkg.el create mode 100644 elpa/web-mode-20200612.1038/web-mode.el create mode 100644 elpa/web-mode-20200612.1038/web-mode.elc diff --git a/elpa/web-mode-20200612.1038/web-mode-autoloads.el b/elpa/web-mode-20200612.1038/web-mode-autoloads.el new file mode 100644 index 0000000..f319e69 --- /dev/null +++ b/elpa/web-mode-20200612.1038/web-mode-autoloads.el @@ -0,0 +1,27 @@ +;;; web-mode-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "web-mode" "web-mode.el" (0 0 0 0)) +;;; Generated autoloads from web-mode.el + +(autoload 'web-mode "web-mode" "\ +Major mode for editing web templates. + +\(fn)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "web-mode" '("web-mode-"))) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; web-mode-autoloads.el ends here diff --git a/elpa/web-mode-20200612.1038/web-mode-pkg.el b/elpa/web-mode-20200612.1038/web-mode-pkg.el new file mode 100644 index 0000000..07a32a1 --- /dev/null +++ b/elpa/web-mode-20200612.1038/web-mode-pkg.el @@ -0,0 +1,2 @@ +;;; -*- no-byte-compile: t -*- +(define-package "web-mode" "20200612.1038" "major mode for editing web templates" '((emacs "23.1")) :commit "60ffd878c4371644bd964f00fea38054645e3e47" :keywords '("languages") :authors '(("François-Xavier Bois ")) :maintainer '("François-Xavier Bois") :url "http://web-mode.org") diff --git a/elpa/web-mode-20200612.1038/web-mode.el b/elpa/web-mode-20200612.1038/web-mode.el new file mode 100644 index 0000000..6626eb3 --- /dev/null +++ b/elpa/web-mode-20200612.1038/web-mode.el @@ -0,0 +1,14312 @@ +;;; web-mode.el --- major mode for editing web templates +;;; -*- coding: utf-8; lexical-binding: t; -*- + +;; Copyright 2011-2020 François-Xavier Bois + +;; Version: 17.0.0 +;; Package-Version: 20200612.1038 +;; Package-Commit: 60ffd878c4371644bd964f00fea38054645e3e47 +;; Author: François-Xavier Bois +;; Maintainer: François-Xavier Bois +;; Package-Requires: ((emacs "23.1")) +;; URL: http://web-mode.org +;; Repository: http://github.com/fxbois/web-mode +;; Created: July 2011 +;; Keywords: languages +;; License: GNU General Public License >= 2 +;; Distribution: This file is not part of Emacs + +;;; Commentary: + +;;============================================================================== +;; WEB-MODE is sponsored by ** Kernix ** Best Digital Factory & Data Lab (Paris) +;;============================================================================== + +;;; Code: + +;;---- CONSTS ------------------------------------------------------------------ + +(defconst web-mode-version "17.0.0" + "Web Mode version.") + +;;---- GROUPS ------------------------------------------------------------------ + +(defgroup web-mode nil + "Major mode for editing web templates" + :group 'languages + :prefix "web-" + :link '(url-link :tag "Site" "http://web-mode.org") + :link '(url-link :tag "Repository" "https://github.com/fxbois/web-mode")) + +(defgroup web-mode-faces nil + "Faces for syntax highlighting." + :group 'web-mode + :group 'faces) + +;;---- CUSTOMS ----------------------------------------------------------------- + +(defcustom web-mode-block-padding 0 + "Multi-line block (php, ruby, java, python, asp, etc.) left padding. + -1 to have to code aligned on the column 0." + :type '(choice (integer :tags "Number of spaces") + (const :tags "No indent" nil)) + :group 'web-mode) + +(defcustom web-mode-part-padding 1 + "Part elements (script, style) left padding." + :type '(choice (integer :tags "Number of spaces") + (const :tags "No indent" nil)) + :group 'web-mode) + +(defcustom web-mode-script-padding web-mode-part-padding + "Script element left padding." + :type '(choice (integer :tags "Number of spaces") + (const :tags "No indent" nil)) + :group 'web-mode) + +(defcustom web-mode-style-padding web-mode-part-padding + "Style element left padding." + :type '(choice (integer :tags "Number of spaces") + (const :tags "No indent" nil)) + :group 'web-mode) + +(defcustom web-mode-attr-indent-offset nil + "Html attribute indentation level." + :type '(choice (integer :tags "Number of spaces") + (const :tags "Default" nil)) + :safe #'(lambda (v) (or (integerp v) (booleanp v))) + :group 'web-mode) + +(defcustom web-mode-attr-value-indent-offset nil + "Html attribute value indentation level." + :type '(choice (integer :tags "Number of spaces") + (const :tags "Default" nil)) + :safe #'(lambda (v) (or (integerp v) (booleanp v))) + :group 'web-mode) + +(defcustom web-mode-markup-indent-offset + (if (and (boundp 'standard-indent) standard-indent) standard-indent 2) + "Html indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-css-indent-offset + (if (and (boundp 'standard-indent) standard-indent) standard-indent 2) + "CSS indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-code-indent-offset + (if (and (boundp 'standard-indent) standard-indent) standard-indent 2) + "Code (javascript, php, etc.) indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-sql-indent-offset 4 + "Sql (inside strings) indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-enable-css-colorization (display-graphic-p) + "In a CSS part, set background according to the color: #xxx, rgb(x,x,x)." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-comment-interpolation nil + "Enable highlight of keywords like FIXME, TODO, etc. in comments." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-comment-annotation nil + "Enable annotation in comments (jsdoc, phpdoc, etc.)." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-indentation (display-graphic-p) + "Auto-indentation." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-closing (display-graphic-p) + "Auto-closing." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-pairing (display-graphic-p) + "Auto-pairing." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-opening (display-graphic-p) + "Html element auto-opening." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-quoting (display-graphic-p) + "Add double quotes after the character = in a tag." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-expanding nil + "e.g. s/ expands to |." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-control-block-indentation t + "Control blocks increase indentation." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-current-element-highlight nil + "Enable current element highlight." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-current-column-highlight nil + "Show column for current element." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-whitespace-fontification nil + "Enable whitespaces." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-html-entities-fontification nil + "Enable html entities fontification." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-block-face nil + "Enable block face (useful for setting a background for example). +See web-mode-block-face." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-part-face nil + "Enable part face (useful for setting background of ") + (cond + ((string-match-p " lang[ ]*=[ ]*[\"']stylus" style) + (setq element-content-type "stylus")) + ((string-match-p " lang[ ]*=[ ]*[\"']sass" style) + (setq element-content-type "sass")) + (t + (setq element-content-type "css")) + ) ;cond + ) ;let + ) ;style + ((string= tname "script") + (let (script) + (setq script (buffer-substring-no-properties tbeg tend) + part-close-tag "") + (cond + ((string-match-p " type[ ]*=[ ]*[\"']text/\\(jsx\\|babel\\)" script) + (setq element-content-type "jsx")) + ((string-match-p " type[ ]*=[ ]*[\"']text/\\(markdown\\|template\\)" script) + (setq element-content-type "markdown")) + ((string-match-p " type[ ]*=[ ]*[\"']text/ruby" script) + (setq element-content-type "ruby")) + ((seq-some (lambda (x) + (string-match-p (concat "type[ ]*=[ ]*[\"']" x) script)) + web-mode-script-template-types) + (setq element-content-type "html" + part-close-tag nil)) + ((string-match-p " type[ ]*=[ ]*[\"']application/\\(ld\\+json\\|json\\)" script) + (setq element-content-type "json")) + ((string-match-p " lang[ ]*=[ ]*[\"']\\(typescript\\|ts\\)" script) + (setq element-content-type "typescript")) + (t + (setq element-content-type "javascript")) + ) ;cond + ) ;let + ) ;script + ((and (string= tname "template") (string-match-p " lang" (buffer-substring-no-properties tbeg tend))) + (let (template) + (setq template (buffer-substring-no-properties tbeg tend) + part-close-tag "") + (cond + ((string-match-p " lang[ ]*=[ ]*[\"']pug" template) + (setq element-content-type "pug")) + (t + (setq element-content-type "html")) + ) ;cond + ) ;let + ) ;style + ((and (string= web-mode-engine "archibus") + (string= tname "sql")) + (setq element-content-type "sql" + part-close-tag "")) + ) + + (add-text-properties tbeg tend props) + (put-text-property tbeg (1+ tbeg) 'tag-beg flags) + (put-text-property (1- tend) tend 'tag-end t) + + (when (and part-close-tag + (web-mode-dom-sf part-close-tag reg-end t) + (setq part-beg tend) + (setq part-end (match-beginning 0)) + (> part-end part-beg)) + (put-text-property part-beg part-end 'part-side + (intern element-content-type web-mode-obarray)) + (setq tend part-end) + ) ;when + + (goto-char tend) + + ) ;while + + ))) + +;; FLAGS: attr +;; (1)custom-attr (2)engine-attr (4)spread-attr[jsx] (8)code-value + +;; STATES: attr +;; (0)nil (1)space (2)name (3)space-before (4)equal (5)space-after +;; (6)value-uq (7)value-sq (8)value-dq (9)value-bq : jsx attr={} + +(defun web-mode-attr-skip (limit) + + (let ((tag-flags 0) (attr-flags 0) (continue t) (attrs 0) (counter 0) (brace-depth 0) + (pos-ori (point)) (state 0) (equal-offset 0) (go-back nil) + (is-jsx (or (string= web-mode-content-type "jsx") (eq (get-text-property (point) 'part-type) 'jsx))) + attr name-beg name-end val-beg char pos escaped spaced quoted) + + (while continue + + (setq pos (point) + char (char-after) + ;;spaced (eq char ?\s) + spaced (member char '(?\s ?\n)) + ) + + (when quoted (setq quoted (1+ quoted))) + + (cond + + ((>= pos limit) + (setq continue nil) + (setq go-back t) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + ) + + ((or (and (= state 8) (not (member char '(?\" ?\\)))) + (and (= state 7) (not (member char '(?\' ?\\)))) + (and (= state 9) (not (member char '(?} ?\\)))) + ) + (when (and (= state 9) (eq char ?\{)) + (setq brace-depth (1+ brace-depth))) + ) + + ((and (= state 9) (eq char ?\}) (> brace-depth 1)) + (setq brace-depth (1- brace-depth))) + + ((get-text-property pos 'block-side) + (when (= state 2) + (setq name-end pos)) + ) + + ((and (= state 2) is-jsx (eq char ?\}) (eq attr-flags 4)) + (setq name-end pos) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 0 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((or (and (= state 8) (eq ?\" char) (not escaped)) + (and (= state 7) (eq ?\' char) (not escaped)) + (and (= state 9) (eq ?\} char) (= brace-depth 1)) + ) + + ;;(message "%S %S" (point) attr-flags) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 0 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (member state '(4 5)) (member char '(?\' ?\" ?\{))) + (setq val-beg pos) + (setq quoted 1) + (setq state (cond ((eq ?\' char) 7) + ((eq ?\" char) 8) + (t 9))) + (when (= state 9) + (setq brace-depth 1)) + ) + + ((and (eq ?\= char) (member state '(2 3))) + (setq equal-offset (- pos name-beg) + name-end (1- pos)) + (setq state 4) + (setq attr (buffer-substring-no-properties name-beg (1+ name-end))) + (when (and web-mode-indentless-attributes (member (downcase attr) web-mode-indentless-attributes)) + ;;(message "onclick") + (setq attr-flags (logior attr-flags 8))) + ) + + ((and spaced (= state 0)) + (setq state 1) + ) + + ((and (eq char ?\<) (not (member state '(7 8 9)))) + (setq continue nil) + (setq go-back t) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + ) + + ((and (eq char ?\>) (not (member state '(7 8 9)))) + (setq tag-flags (logior tag-flags 16)) + (when (eq (char-before) ?\/) + (setq tag-flags (logior tag-flags 8)) + ) + (setq continue nil) + (when name-beg + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))) + ) + + ((and spaced (member state '(1 3 5))) + ) + + ((and spaced (= state 2)) + (setq state 3) + ) + + ((and (eq char ?\/) (member state '(4 5))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (eq char ?\/) (member state '(0 1))) + ) + + ((and spaced (= state 4)) + (setq state 5) + ) + + ((and (= state 3) + (or (and (>= char 97) (<= char 122)) ;a - z + (and (>= char 65) (<= char 90)) ;A - Z + (eq char ?\-))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 2 + attr-flags 0 + equal-offset 0 + name-beg pos + name-end pos + val-beg nil) + ) + + ((and (eq char ?\n) (not (member state '(7 8 9)))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (= state 6) (member char '(?\s ?\n ?\/))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and quoted (= quoted 2) (member char '(?\s ?\n ?\>))) + (when (eq char ?\>) + (setq tag-flags (logior tag-flags 16)) + (setq continue nil)) + (setq state 6) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (not spaced) (= state 1)) + (when (and is-jsx (eq char ?\{)) + (setq attr-flags 4)) + (setq state 2) + (setq name-beg pos + name-end pos) + ) + + ((member state '(4 5)) + (setq val-beg pos) + (setq state 6) + ) + + ((= state 1) + (setq state 2) + ) + + ((= state 2) + (setq name-end pos) + (when (and nil (= attr-flags 0) (member char '(?\- ?\:))) + (let (attr) + (setq attr (buffer-substring-no-properties name-beg (1+ name-end))) + (cond + ((member attr '("http-equiv")) + (setq attr-flags (1- attr-flags)) + ) + ;;((and web-mode-engine-attr-regexp + ;; (string-match-p web-mode-engine-attr-regexp attr)) + ;; (setq attr-flags (logior attr-flags 2)) + ;; ) + ((and (eq char ?\-) (not (string= attr "http-"))) + (setq attr-flags (logior attr-flags 1))) + ) ;cond + ) ;let + ) ;when attr-flags = 1 + ) ;state=2 + + ) ;cond + + ;;(message "point(%S) end(%S) state(%S) c(%S) name-beg(%S) name-end(%S) val-beg(%S) attr-flags(%S) equal-offset(%S)" pos end state char name-beg name-end val-beg attr-flags equal-offset) + + (when (and quoted (>= quoted 2)) + (setq quoted nil)) + + (setq escaped (eq ?\\ char)) + (when (null go-back) + (forward-char)) + + ) ;while + + (when (> attrs 0) (setq tag-flags (logior tag-flags 1))) + + tag-flags)) + +(defun web-mode-attr-scan (state char name-beg name-end val-beg flags equal-offset) + ;;(message "point(%S) state(%S) c(%c) name-beg(%S) name-end(%S) val-beg(%S) flags(%S) equal-offset(%S)" + ;; (point) state char name-beg name-end val-beg flags equal-offset) + (when (null flags) (setq flags 0)) + (when (and name-beg name-end web-mode-engine-attr-regexp) + (let (name) + (setq name (buffer-substring-no-properties name-beg (1+ name-end))) + ;;(message "%S" name) + (cond + ((string-match-p "^data[-]" name) + (setq flags (logior flags 1)) + ) + ((string-match-p web-mode-engine-attr-regexp name) + (setq flags (logior flags 2)) + ) + ) + ) ;name + ) + ;;(message "%S" name) + (cond + ((null name-beg) + ;; (message "name-beg is null (%S)" (point)) + 0) + ((or (and (= state 8) (not (eq ?\" char))) + (and (= state 7) (not (eq ?\' char)))) + (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags) + (put-text-property name-beg val-beg 'tag-attr t) + (put-text-property (1- val-beg) val-beg 'tag-attr-end equal-offset) + 1) + ((and (member state '(4 5)) (null val-beg)) + (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags) + (put-text-property name-beg (+ name-beg equal-offset 1) 'tag-attr t) + (put-text-property (+ name-beg equal-offset) (+ name-beg equal-offset 1) 'tag-attr-end equal-offset) + 1) + (t + (let (val-end) + (if (null val-beg) + (setq val-end name-end) + (setq val-end (point)) + (when (or (null char) (member char '(?\s ?\n ?\> ?\/))) + (setq val-end (1- val-end)) + ) + ) ;if + (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags) + (put-text-property name-beg (1+ val-end) 'tag-attr t) + (put-text-property val-end (1+ val-end) 'tag-attr-end equal-offset) + ) ;let + 1) ;t + ) ;cond + ) + +(defun web-mode-part-foreach (reg-beg reg-end func) + (let ((i 0) (continue t) (part-beg reg-beg) (part-end nil)) + (while continue + (setq part-end nil) + (unless (get-text-property part-beg 'part-side) + (setq part-beg (web-mode-part-next-position part-beg))) + (when (and part-beg (< part-beg reg-end)) + (setq part-end (web-mode-part-end-position part-beg))) + (cond + ((> (setq i (1+ i)) 100) + (message "process-parts ** warning (%S) **" (point)) + (setq continue nil)) + ((or (null part-end) (> part-end reg-end)) + (setq continue nil)) + (t + (setq part-end (1+ part-end)) + (funcall func part-beg part-end) + (setq part-beg part-end)) + ) ;cond + ) ;while + )) + +(defun web-mode-part-scan (reg-beg reg-end &optional content-type depth) + (save-excursion + (let (token-re ch-before ch-at ch-next token-type beg continue) + ;;(message "%S %S" reg-beg reg-end) + (cond + (content-type + ) + ((member web-mode-content-type web-mode-part-content-types) + (setq content-type web-mode-content-type)) + (t + (setq content-type (symbol-name (get-text-property reg-beg 'part-side)))) + ) ;cond + + (goto-char reg-beg) + + (cond + ((member content-type '("javascript" "json")) + (setq token-re "/\\|\"\\|'\\|`")) + ((member content-type '("typescript")) + (setq token-re "\"\\|'\\|`\\|//\\|/\\*")) + ((member content-type '("jsx")) + (setq token-re "/\\|\"\\|'\\|`\\|]")) + ((string= web-mode-content-type "css") + (setq token-re "\"\\|'\\|/\\*\\|//")) + ((string= content-type "css") + (setq token-re "\"\\|'\\|/\\*")) + (t + (setq token-re "/\\*\\|\"\\|'")) + ) + + (while (and token-re (< (point) reg-end) (web-mode-dom-rsf token-re reg-end t)) + + (setq beg (match-beginning 0) + token-type nil + continue t + ch-at (char-after beg) + ch-next (or (char-after (1+ beg)) ?\d) + ch-before (or (char-before beg) ?\d)) + + ;;(message "[%S>%S|%S] %S %c %c %c" reg-beg reg-end depth beg ch-before ch-at ch-next) + + (cond + + ((eq ?\' ch-at) + (while (and continue (search-forward "'" reg-end t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + (t + (setq continue (web-mode-string-continue-p reg-beg))) + ) + ) ;while + (setq token-type 'string)) + + ((eq ?\` ch-at) + (while (and continue (search-forward "`" reg-end t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + (t + (setq continue (web-mode-string-continue-p reg-beg))) + ) + ) ;while + (setq token-type 'string)) + + ((eq ?\" ch-at) + (while (and continue (search-forward "\"" reg-end t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + (t + (setq continue (web-mode-string-continue-p reg-beg))) + ) ;cond + ) ;while + (cond + ((string= content-type "json") + (if (looking-at-p "[ ]*:") + (cond + ((eq ?\@ (char-after (1+ beg))) + (setq token-type 'context)) + (t + (setq token-type 'key)) + ) + (setq token-type 'string)) + ) ;json + (t + (setq token-type 'string)) + ) ;cond + ) + + ((and (eq ?\< ch-at) + (not (or (and (>= ch-before 97) (<= ch-before 122)) + (and (>= ch-before 65) (<= ch-before 90))))) + ;;(message "before [%S>%S|%S] pt=%S" reg-beg reg-end depth (point)) + (search-backward "<") + (if (web-mode-jsx-skip reg-end) + (web-mode-jsx-scan-element beg (point) depth) + (forward-char)) + ;;(message "after [%S>%S|%S] pt=%S" reg-beg reg-end depth (point)) + ) + + ((and (eq ?\/ ch-at) (member content-type '("javascript" "jsx"))) + (cond + ((eq ?\\ ch-before) + ) + ((eq ?\* ch-next) + ;;(message "--> %S %S" (point) reg-end) + (when (search-forward "*/" reg-end t) + (setq token-type 'comment)) + ) + ((eq ?\/ ch-next) + (setq token-type 'comment) + (goto-char (if (< reg-end (line-end-position)) reg-end (line-end-position))) + ) + ((and (looking-at-p ".*/") + (looking-back "\\(^\\|case\\|[[(,=:!&|?{};]\\)[ ]*/" (point-min))) + ;;(re-search-forward "/[gimyu]*" reg-end t)) + (let ((eol (line-end-position))) + (while (and continue (search-forward "/" eol t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + ((looking-back "\\\\+/" reg-beg t) + (setq continue (= (mod (- (point) (match-beginning 0)) 2) 0))) + (t + (re-search-forward "[gimyu]*" eol t) + (setq token-type 'string) + (setq continue nil)) + ) + ) ;while + ) ;let + ) + ) ;cond + ) + + ((eq ?\/ ch-next) + ;;(message "%S" (point)) + (cond + ((and (string= content-type "css") + (eq ?/ ch-at) + (eq ?: ch-before)) + ) + (t + (unless (eq ?\\ ch-before) + (setq token-type 'comment) + (goto-char (if (< reg-end (line-end-position)) reg-end (line-end-position))) + ) + ) + ) + + ) + + ((eq ?\* ch-next) + (cond + ((search-forward "*/" reg-end t) + (setq token-type 'comment)) + ((not (eobp)) + (forward-char)) + ) ;cond + ) + + ) ;cond + + (when (and beg (>= reg-end (point)) token-type) + (put-text-property beg (point) 'part-token token-type) + (cond + ((eq token-type 'comment) + (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "<")) + (when (< (point) (point-max)) + (if (< (point) (line-end-position)) + (put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax ">")) ;#445 + (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax ">")) ;#377 + ) + ) ;when + ) ;comment + ((eq token-type 'string) + (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "|")) + (when (< (point) (point-max)) + (if (< (point) (line-end-position)) + (put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax "|")) + (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax "|")) + ) + ) ;when + ) ;string + ) ;cond + ) ;when + + (when (> (point) reg-end) + (message "reg-beg(%S) reg-end(%S) token-type(%S) point(%S)" reg-beg reg-end token-type (point))) + + ;;(message "#[%S>%S|%S] %S %c %c %c | (%S)" reg-beg reg-end depth beg ch-before ch-at ch-next (point)) + + ) ;while + + ))) + +(defun web-mode-string-continue-p (reg-beg) + "Is `point' preceeded by an odd number of backslashes?" + (let ((p (1- (point)))) + (while (and (< reg-beg p) (eq ?\\ (char-before p))) + (setq p (1- p))) + (= (mod (- (point) p) 2) 0))) + +;; css rule = selector(s) + declaration (properties) +(defun web-mode-css-rule-next (limit) + (let (at-rule var-rule sel-beg sel-end dec-beg dec-end chunk) + (skip-chars-forward "\n\t ") + (setq sel-beg (point)) + (when (and (< (point) limit) + (web-mode-part-rsf "[{;]" limit)) + (setq sel-end (1- (point))) + (cond + ((eq (char-before) ?\{) + (setq dec-beg (point)) + (setq dec-end (web-mode-closing-paren-position (1- dec-beg) limit)) + (if dec-end + (progn + (goto-char dec-end) + (forward-char)) + (setq dec-end limit) + (goto-char limit)) + ) + (t + ) + ) ;cond + (setq chunk (buffer-substring-no-properties sel-beg sel-end)) + (cond + ((string-match "@\\([[:alpha:]-]+\\)" chunk) + (setq at-rule (match-string-no-properties 1 chunk))) + ((string-match "\\$\\([[:alpha:]-]+\\)" chunk) + (setq var-rule (match-string-no-properties 1 chunk))) + ) ;cond + ) ;when + (if (not sel-end) + (progn (goto-char limit) nil) + (list :at-rule at-rule + :var-rule var-rule + :sel-beg sel-beg + :sel-end sel-end + :dec-beg dec-beg + :dec-end dec-end) + ) ;if + )) + +(defun web-mode-css-rule-current (&optional pos part-beg part-end) + "Current CSS rule boundaries." + (unless pos (setq pos (point))) + (unless part-beg (setq part-beg (web-mode-part-beginning-position pos))) + (unless part-end (setq part-end (web-mode-part-end-position pos))) + (save-excursion + (let (beg end) + (goto-char pos) + (if (not (web-mode-part-sb "{" part-beg)) + (progn + (setq beg part-beg) + (if (web-mode-part-sf ";" part-end) + (setq end (1+ (point))) + (setq end part-end)) + ) ;progn + (setq beg (point)) + (setq end (web-mode-closing-paren-position beg part-end)) + (if end + (setq end (1+ end)) + (setq end (line-end-position))) +;; (message "%S >>beg%S >>end%S" pos beg end) + (if (> pos end) + + ;;selectors + (progn + (goto-char pos) + (if (web-mode-part-rsb "[};]" part-beg) + (setq beg (1+ (point))) + (setq beg part-beg) + ) ;if + (goto-char pos) + (if (web-mode-part-rsf "[{;]" part-end) + (cond + ((eq (char-before) ?\;) + (setq end (point)) + ) + (t + (setq end (web-mode-closing-paren-position (1- (point)) part-end)) + (if end + (setq end (1+ end)) + (setq end part-end)) + ) + ) ;cond + (setq end part-end) + ) + ) ;progn selectors + + ;; declaration + (goto-char beg) + (if (web-mode-part-rsb "[}{;]" part-beg) + (setq beg (1+ (point))) + (setq beg part-beg) + ) ;if + ) ;if > pos end + ) +;; (message "beg(%S) end(%S)" beg end) + (when (eq (char-after beg) ?\n) + (setq beg (1+ beg))) + (cons beg end) + ))) + +(defun web-mode-jsx-skip (reg-end) + (let ((continue t) (pos nil) (i 0) tag) + (looking-at "<\\([[:alpha:]][[:alnum:]:-]*\\)") + (setq tag (match-string-no-properties 1)) + ;;(message "point=%S tag=%S" (point) tag) + (save-excursion + (while continue + (cond + ((> (setq i (1+ i)) 1000) + (message "jsx-skip ** warning **") + (setq continue nil)) + ((looking-at "<[[:alpha:]][[:alnum:]:-]*[ ]*/>") + (goto-char (match-end 0)) + (setq pos (point)) + (setq continue nil)) + ((not (web-mode-dom-rsf ">\\([ \t\n]*[\];,)':}|&]\\)\\|{" reg-end)) + (setq continue nil) + ) + ((eq (char-before) ?\{) + (backward-char) + (web-mode-closing-paren reg-end) + (forward-char) + ) + (t + (setq continue nil) + (setq pos (match-beginning 1)) + ) ;t + ) ;cond + ) ;while + ) ;save-excursion + (when pos (goto-char pos)) + ;;(message "jsx-skip: %S" pos) + pos)) + +;; (defun web-mode-jsx-skip2 (reg-end) +;; (let ((continue t) (pos nil) (i 0) (tag nil) (regexp nil) (counter 1)) +;; (looking-at "<\\([[:alpha:]][[:alnum:]:-]*\\)") +;; (setq tag (match-string-no-properties 1)) +;; (setq regexp (concat " (setq i (1+ i)) 100) +;; (message "jsx-skip ** warning **") +;; (setq continue nil)) +;; ((looking-at "<[[:alpha:]][[:alnum:]:-]*[ ]*/>") +;; (goto-char (match-end 0)) +;; (setq pos (point)) +;; (setq continue nil)) +;; ((not (web-mode-dom-rsf ">\\([ \t\n]*[\];,)':}]\\)\\|{" reg-end)) +;; (setq continue nil) +;; ) +;; ((eq (char-before) ?\{) +;; (backward-char) +;; (web-mode-closing-paren reg-end) +;; (forward-char) +;; ) +;; (t +;; (setq continue nil) +;; (setq pos (match-beginning 1)) +;; ) ;t +;; ) ;cond +;; ) ;while +;; ) ;save-excursion +;; (when pos (goto-char pos)) +;; ;;(message "jsx-skip: %S" pos) +;; pos)) + +;; http://facebook.github.io/jsx/ +;; https://github.com/facebook/jsx/blob/master/AST.md +(defun web-mode-jsx-scan-element (reg-beg reg-end depth) + (unless depth (setq depth 1)) + (save-excursion + (let (token-beg token-end regexp) + (goto-char reg-beg) + (put-text-property reg-beg (1+ reg-beg) 'jsx-beg depth) + (put-text-property (1- reg-end) reg-end 'jsx-end depth) + (put-text-property reg-beg reg-end 'jsx-depth depth) + (goto-char reg-beg) + (web-mode-scan-elements reg-beg reg-end) + (web-mode-jsx-scan-expression reg-beg reg-end (1+ depth)) + ))) + +(defun web-mode-jsx-scan-expression (reg-beg reg-end depth) + (let ((continue t) beg end) + (save-excursion + (goto-char reg-beg) + ;;(message "reg-beg=%S reg-end=%S" reg-beg reg-end) + (while (and continue (search-forward "{" reg-end t)) + (backward-char) + (setq beg (point) + end (web-mode-closing-paren reg-end)) + (cond + ((eq (get-text-property beg 'part-token) 'comment) + (forward-char)) + ((not end) + (setq continue nil)) + (t + (setq end (1+ end)) + (put-text-property beg end 'jsx-depth depth) + (put-text-property beg (1+ beg) 'jsx-beg depth) + (put-text-property (1- end) end 'jsx-end depth) + (web-mode-part-scan beg end "jsx" (1+ depth)) + ) ;t + ) ;cond + ) ;while + ) ;save-excursion + )) + +(defun web-mode-jsx-is-html (&optional pos) + (interactive) + (unless pos (setq pos (point))) + (let (ret (depth (get-text-property pos 'jsx-depth))) + (cond + ((or (null depth) (<= pos 2)) + (setq pos nil)) + ((and (= depth 1) (get-text-property pos 'jsx-beg)) + (setq pos nil)) + ((get-text-property pos 'tag-end) + (setq pos nil)) + ((get-text-property pos 'tag-attr-beg) + (setq pos nil)) + ((get-text-property pos 'jsx-beg) + (setq pos (null (get-text-property pos 'tag-beg)))) + ((setq pos (web-mode-jsx-depth-beginning-position pos)) + (setq pos (not (null (get-text-property pos 'tag-beg))))) + (t + (setq pos nil)) + ) ;cond + ;;(message "is-html: %S (depth=%S)" pos depth) + pos)) + +(defun web-mode-jsx-is-expr (&optional pos) + (cond + ((and (get-text-property pos 'jsx-beg) + (not (get-text-property pos 'tag-beg))) + nil) + (t + (setq pos (web-mode-jsx-depth-beginning-position pos)) + (null (get-text-property pos 'tag-beg))) + ) ;cond + ) + +(defun web-mode-jsx-depth-beginning-position (&optional pos target-depth) + (interactive) + (unless pos (setq pos (point))) + (unless target-depth (setq target-depth (get-text-property pos 'jsx-depth))) + (cond + ((or (null target-depth) (bobp)) + (setq pos nil)) + ((and (get-text-property pos 'jsx-beg) (= target-depth (get-text-property pos 'jsx-depth))) + ) + (t + (let ((continue t) depth) + (while continue + (setq pos (previous-single-property-change pos 'jsx-depth)) + (cond + ((or (null pos) + (null (setq depth (get-text-property pos 'jsx-depth)))) + (setq continue nil + pos nil)) + ((and (get-text-property pos 'jsx-beg) (= target-depth depth)) + (setq continue nil)) + ) ;cond + ) ;while + ) ;let + ) ;t + ) ;cond + ;;(message "beg: %S" pos) + pos) + +(defun web-mode-jsx-element-next (reg-end) + (let (continue beg end) + (setq beg (point)) + (unless (get-text-property beg 'jsx-depth) + (setq beg (next-single-property-change beg 'jsx-beg))) + (setq continue (and beg (< beg reg-end)) + end beg) + (while continue + (setq end (next-single-property-change end 'jsx-end)) + (cond + ((or (null end) (> end reg-end)) + (setq continue nil + end nil)) + ((eq (get-text-property end 'jsx-depth) 1) + (setq continue nil)) + (t + (setq end (1+ end))) + ) ;cond + ) ;while + ;;(message "beg=%S end=%S" beg end) + (if (and beg end (< beg end)) (cons beg end) nil))) + +(defun web-mode-jsx-expression-next (reg-end) + (let (beg end depth continue pos) + (setq beg (point)) + ;;(message "pt=%S" beg) + (unless (and (get-text-property beg 'jsx-beg) (null (get-text-property beg 'tag-beg))) + ;;(setq beg (next-single-property-change beg 'jsx-beg)) + (setq continue t + pos (1+ beg)) + (while continue + (setq pos (next-single-property-change pos 'jsx-beg)) + (cond + ((null pos) + (setq continue nil + beg nil)) + ((> pos reg-end) + (setq continue nil + beg nil)) + ((null (get-text-property pos 'jsx-beg)) + ) + ((null (get-text-property pos 'tag-beg)) + (setq continue nil + beg pos)) + ;;(t + ;; (setq pos (1+ pos))) + ) ;cond + ) ;while + ) ;unless + ;;(message "beg=%S" beg) + (when (and beg (< beg reg-end)) + (setq depth (get-text-property beg 'jsx-beg) + continue (not (null depth)) + pos beg) + ;;(message "beg=%S" beg) + (while continue + (setq pos (next-single-property-change pos 'jsx-end)) + ;;(message "pos=%S" pos) + (cond + ((null pos) + (setq continue nil)) + ((> pos reg-end) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-end)) + (setq continue nil + end pos)) + (t + ;;(setq pos (1+ pos)) + ) + ) ;cond + ) ;while + ) ;when + ;;(message "%S > %S" beg end) + (if (and beg end) (cons beg end) nil))) + +(defun web-mode-jsx-depth-next (reg-end) + (let (beg end depth continue pos) + (setq beg (point)) + ;;(message "pt=%S" beg) + (unless (get-text-property beg 'jsx-beg) + ;;(setq beg (next-single-property-change beg 'jsx-beg)) + ;;(setq pos (1+ beg)) + (setq pos (next-single-property-change (1+ beg) 'jsx-beg)) + (cond + ((null pos) + (setq beg nil)) + ((>= pos reg-end) + (setq beg nil)) + (t + (setq beg pos)) + ) ;cond + ) ;unless + ;;(message "beg=%S" beg) + (when beg + (setq depth (get-text-property beg 'jsx-beg) + continue (not (null depth)) + pos beg) + ;;(message "beg=%S" beg) + (while continue + (setq pos (next-single-property-change pos 'jsx-end)) + ;;(message "pos=%S" pos) + (cond + ((null pos) + (setq continue nil)) + ((> pos reg-end) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-end)) + (setq continue nil + end pos)) + (t + ;;(setq pos (1+ pos)) + ) + ) ;cond + ) ;while + ) ;when + ;;(message "%S > %S" beg end) + (if (and beg end) (cons beg end) nil))) + +(defun web-mode-jsx-beginning () + (interactive) + (let (depth (continue t) (reg-beg (point-min)) (pos (point))) + (setq depth (get-text-property pos 'jsx-depth)) + (cond + ((not depth) + ) + ((get-text-property (1- pos) 'jsx-beg) + (goto-char (1- pos))) + (t + (while continue + (setq pos (previous-single-property-change pos 'jsx-beg)) + ;;(message "pos=%S" pos) + (cond + ((null pos) + (setq continue nil)) + ((<= pos reg-beg) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-beg)) + (setq continue nil)) + ) ;cond + ) ;while + (web-mode-go pos) + ) ;t + ) ;cond + )) + +(defun web-mode-jsx-end () + (interactive) + (let (depth (continue t) (reg-end (point-max)) (pos (point))) + (setq depth (get-text-property pos 'jsx-depth)) + (cond + ((not depth) + ) + ((get-text-property pos 'jsx-end) + (goto-char (+ pos 1))) + (t + (while continue + (setq pos (next-single-property-change pos 'jsx-end)) + ;;(message "pos=%S" pos) + (cond + ((null pos) + (setq continue nil)) + ((> pos reg-end) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-end)) + (setq continue nil)) + ) ;cond + ) ;while + (web-mode-go pos 1) + ) ;t + ) ;cond + )) + +;;---- FONTIFICATION ----------------------------------------------------------- + +;; 1/ after-change +;; 2/ extend-region +;; 3/ scan +;; 4/ fontify +;; 5/ post-command + +(defun web-mode-extend-region () + ;;(message "extend-region: flb(%S) fle(%S) wmcb(%S) wmce(%S)" font-lock-beg font-lock-end web-mode-change-beg web-mode-change-end) + (cond + (web-mode-fontification-off + nil) + (t + (when (or (null web-mode-change-beg) (< font-lock-beg web-mode-change-beg)) + ;;(message "font-lock-beg(%S) < web-mode-change-beg(%S)" font-lock-beg web-mode-change-beg) + (setq web-mode-change-beg font-lock-beg)) + (when (or (null web-mode-change-end) (> font-lock-end web-mode-change-end)) + ;;(message "font-lock-end(%S) > web-mode-change-end(%S)" font-lock-end web-mode-change-end) + (setq web-mode-change-end font-lock-end)) + (let ((region (web-mode-scan web-mode-change-beg web-mode-change-end))) + (when region + ;;(message "region: %S" region) + (setq font-lock-beg (car region) + font-lock-end (cdr region)) + ) ;when + ) ;let + nil) ;t + )) + +(defun web-mode-fontify (limit) + ;;(message "fontify: point(%S) limit(%S) change-beg(%S) change-end(%S)" (point) limit web-mode-change-beg web-mode-change-end) + (cond + (web-mode-fontification-off + nil) + (t + (web-mode-with-silent-modifications + (save-excursion + (save-restriction + (save-match-data + (let ((beg (point)) + (buffer-undo-list t) + (end limit) + (inhibit-point-motion-hooks t) + (inhibit-quit t)) + (remove-list-of-text-properties beg end '(font-lock-face face)) + (cond + ((and (get-text-property beg 'block-side) + (not (get-text-property beg 'block-beg))) + (web-mode-fontify-block beg end)) + ((or (member web-mode-content-type web-mode-part-content-types) + (get-text-property beg 'part-side)) + (web-mode-fontify-part beg end) + (web-mode-block-foreach beg end 'web-mode-fontify-block)) + ((string= web-mode-engine "none") + (web-mode-fontify-tags beg end) + (web-mode-part-foreach beg end 'web-mode-fontify-part)) + (t + (web-mode-fontify-tags beg end) + (web-mode-part-foreach beg end 'web-mode-fontify-part) + (web-mode-block-foreach beg end 'web-mode-fontify-block)) + ) ;cond + (when web-mode-enable-element-content-fontification + (web-mode-fontify-elements beg end)) + (when web-mode-enable-whitespace-fontification + (web-mode-fontify-whitespaces beg end)) + ) ;let + )))) + nil) ;t + )) + +(defun web-mode-buffer-fontify () + (interactive) + (cond + ((and (fboundp 'font-lock-flush) global-font-lock-mode) + (font-lock-flush) + (font-lock-ensure)) + (t ;emacs 24 + ;;(font-lock-fontify-buffer) + (and global-font-lock-mode + (font-lock-fontify-region (point-min) (point-max)))) + )) + +(defun web-mode-unfontify-region (beg end) + ;;(message "unfontify: %S %S" beg end) + ) + +(defun web-mode-fontify-region (beg end keywords) +;; (message "beg=%S end=%S keywords=%S" beg end (symbol-name keywords)) + (save-excursion + (let ((font-lock-keywords keywords) + (font-lock-multiline nil) + (font-lock-keywords-case-fold-search + (member web-mode-engine '("archibus" "asp" "template-toolkit"))) + (font-lock-keywords-only t) + (font-lock-extend-region-functions nil)) + (when (and (listp font-lock-keywords) global-font-lock-mode) + (font-lock-fontify-region beg end) + ) + ))) + +(defun web-mode-fontify-tags (reg-beg reg-end &optional depth) + (let ((continue t)) + (goto-char reg-beg) + (when (and (not (get-text-property (point) 'tag-beg)) + (not (web-mode-tag-next))) + (setq continue nil)) + (when (and continue (>= (point) reg-end)) + (setq continue nil)) + (while continue + (cond + (depth + (when (eq depth (get-text-property (point) 'jsx-depth)) + (web-mode-fontify-tag)) + ) + (t + (web-mode-fontify-tag)) + ) ;cond + (when (or (not (web-mode-tag-next)) + (>= (point) reg-end)) + (setq continue nil)) + ) ;while + (when web-mode-enable-inlays + (when (null web-mode-inlay-regexp) + (setq web-mode-inlay-regexp (regexp-opt '("\\[" "\\(" "\\begin{align}")))) + (let (beg end expr) + (goto-char reg-beg) + (while (web-mode-dom-rsf web-mode-inlay-regexp reg-end) + (setq beg (match-beginning 0) + end nil + expr (substring (match-string-no-properties 0) 0 2)) + (setq expr (cond + ((string= expr "\\[") "\\]") + ((string= expr "\\(") "\\)") + (t "\\end{align}"))) + (when (and (web-mode-dom-sf expr reg-end) + (setq end (match-end 0)) + (not (text-property-any beg end 'tag-end t))) + (font-lock-append-text-property beg end 'font-lock-face 'web-mode-inlay-face) + ) ;when + ) ;while + ) ;let + ) ;when + (when web-mode-enable-html-entities-fontification + (let (beg end) + (goto-char reg-beg) + (while (web-mode-dom-rsf "&\\([#]?[[:alnum:]]\\{2,8\\}\\);" reg-end) + (setq beg (match-beginning 0) + end (match-end 0)) + (when (not (text-property-any beg end 'tag-end t)) + (font-lock-append-text-property beg end 'font-lock-face 'web-mode-html-entity-face) + ) ;when + ) ;while + ) ;let + ) ;when + )) + +(defun web-mode-fontify-tag (&optional beg end) + (unless beg (setq beg (point))) + (unless end (setq end (1+ (web-mode-tag-end-position beg)))) + (let (name type face flags slash-beg slash-end bracket-end) + (setq flags (get-text-property beg 'tag-beg) + type (get-text-property beg 'tag-type) + name (get-text-property beg 'tag-name)) + (setq bracket-end (> (logand flags 16) 0)) + (cond + ((eq type 'comment) + (put-text-property beg end 'font-lock-face 'web-mode-comment-face) + (when (and web-mode-enable-comment-interpolation (> (- end beg) 5)) + (web-mode-interpolate-comment beg end nil))) + ((eq type 'cdata) + (put-text-property beg end 'font-lock-face 'web-mode-doctype-face)) + ((eq type 'doctype) + (put-text-property beg end 'font-lock-face 'web-mode-doctype-face)) + ((eq type 'declaration) + (put-text-property beg end 'font-lock-face 'web-mode-doctype-face)) + (name + (setq slash-beg (> (logand flags 4) 0) + slash-end (> (logand flags 8) 0) + bracket-end (> (logand flags 16) 0)) + (setq face (cond + ((not bracket-end) 'web-mode-html-tag-unclosed-face) + ((and web-mode-enable-element-tag-fontification + (setq face (cdr (assoc name web-mode-element-tag-faces)))) + face) + ((> (logand flags 32) 0) 'web-mode-html-tag-namespaced-face) + ((> (logand flags 2) 0) 'web-mode-html-tag-custom-face) + (t 'web-mode-html-tag-face))) + (put-text-property beg (+ beg (if slash-beg 2 1)) + 'font-lock-face 'web-mode-html-tag-bracket-face) + (unless (string= name "_fragment_") + (put-text-property (+ beg (if slash-beg 2 1)) + (+ beg (if slash-beg 2 1) (length name)) + 'font-lock-face face)) + (when (or slash-end bracket-end) + (put-text-property (- end (if slash-end 2 1)) end 'font-lock-face 'web-mode-html-tag-bracket-face) + ) ;when + (when (> (logand flags 1) 0) + ;;(message "%S>%S" beg end) + (web-mode-fontify-attrs beg end)) + ) ;case name + ) ;cond + )) + +(defun web-mode-fontify-attrs (reg-beg reg-end) + (let ((continue t) (pos reg-beg) beg end flags offset face) + ;;(message "fontify-attrs %S>%S" reg-beg reg-end) + (while continue + (setq beg (web-mode-attribute-next-position pos reg-end)) + (cond + ((or (null beg) (>= beg reg-end)) + (setq continue nil)) + (t + (setq flags (or (get-text-property beg 'tag-attr-beg) 0)) + (setq face (cond + ((= (logand flags 1) 1) 'web-mode-html-attr-custom-face) + ((= (logand flags 2) 2) 'web-mode-html-attr-engine-face) + ((= (logand flags 4) 4) nil) + (t 'web-mode-html-attr-name-face))) + ;;(setq end (if (get-text-property beg 'tag-attr-end) beg (web-mode-attribute-end-position beg))) + (setq end (web-mode-attribute-end-position beg)) + ;;(message "beg=%S end=%S" beg end) + (cond + ((or (null end) (>= end reg-end)) + (setq continue nil)) + (t + (setq offset (get-text-property end 'tag-attr-end)) + (if (= offset 0) + (put-text-property beg (1+ end) 'font-lock-face face) + (put-text-property beg (+ beg offset) 'font-lock-face face) + (put-text-property (+ beg offset) (+ beg offset 1) + 'font-lock-face + 'web-mode-html-attr-equal-face) + (when (not (get-text-property (+ beg offset 1) 'jsx-beg)) + (put-text-property (+ beg offset 1) (1+ end) + 'font-lock-face + 'web-mode-html-attr-value-face) + ) + ) ;if offset + (setq pos (1+ end)) + ) ;t + ) ;cond + ) ;t + );cond + ) ;while + )) + +(defun web-mode-fontify-block (reg-beg reg-end) + (let (sub1 sub2 sub3 continue char keywords token-type face beg end (buffer (current-buffer))) + ;;(message "reg-beg=%S reg-end=%S" reg-beg reg-end) + + ;; NOTE: required for blocks inside tag attrs + (remove-list-of-text-properties reg-beg reg-end '(font-lock-face)) + + (goto-char reg-beg) + + (when (null web-mode-engine-font-lock-keywords) + (setq sub1 (buffer-substring-no-properties + reg-beg (+ reg-beg 1)) + sub2 (buffer-substring-no-properties + reg-beg (+ reg-beg 2)) + sub3 (buffer-substring-no-properties + reg-beg (+ reg-beg (if (>= (point-max) (+ reg-beg 3)) 3 2)))) + ) + + (cond + + ((and (get-text-property reg-beg 'block-beg) + (eq (get-text-property reg-beg 'block-token) 'comment)) + (put-text-property reg-beg reg-end 'font-lock-face 'web-mode-comment-face) + ) ;comment block + + (web-mode-engine-font-lock-keywords + (setq keywords web-mode-engine-font-lock-keywords) + ) + + ((string= web-mode-engine "django") + (cond + ((string= sub2 "{{") + (setq keywords web-mode-django-expr-font-lock-keywords)) + ((string= sub2 "{%") + (setq keywords web-mode-django-code-font-lock-keywords)) + )) ;django + + ((string= web-mode-engine "mako") + (cond + ((member sub3 '("<% " "<%\n" "<%!")) + (setq keywords web-mode-mako-block-font-lock-keywords)) + ((eq (aref sub2 0) ?\%) + (setq keywords web-mode-mako-block-font-lock-keywords)) + ((member sub2 '("<%" " %S face(%S)" beg end face) + (remove-list-of-text-properties beg end '(face)) + (put-text-property beg end 'font-lock-face face) + ) + (setq continue nil + end nil) + ) ;if end + ) ;progn beg + (setq continue nil + end nil) + ) ;if beg + (when (and beg end) + (save-match-data + (when (and web-mode-enable-heredoc-fontification + (eq char ?\<) + (> (- end beg) 8) + ;;(progn (message "%S" (buffer-substring-no-properties beg end)) t) + (string-match-p "JS\\|JAVASCRIPT\\|HTM\\|CSS" (buffer-substring-no-properties beg end))) + (setq keywords + (cond + ((string-match-p "H" (buffer-substring-no-properties beg (+ beg 8))) + web-mode-html-font-lock-keywords) + (t + web-mode-javascript-font-lock-keywords) + )) + (web-mode-fontify-region beg end keywords) + )) +;; (message "%S %c %S beg=%S end=%S" web-mode-enable-string-interpolation char web-mode-engine beg end) + (when (and web-mode-enable-string-interpolation + (member char '(?\" ?\<)) + (member web-mode-engine '("php" "erb")) + (> (- end beg) 4)) + (web-mode-interpolate-block-string beg end) + ) ;when + (when (and web-mode-enable-comment-interpolation + (eq token-type 'comment) + (> (- end beg) 3)) + (web-mode-interpolate-comment beg end t) + ) ;when + (when (and web-mode-enable-comment-annotation + (eq token-type 'comment) + (> (- end beg) 3)) + (web-mode-annotate-comment beg end) + ) ;when + (when (and web-mode-enable-sql-detection + (eq token-type 'string) + (> (- end beg) 6) + ;;(eq char ?\<) + ;;(web-mode-looking-at-p (concat "[ \n]*" web-mode-sql-queries) (1+ beg)) + (web-mode-looking-at-p (concat "\\(.\\|<<<[[:alnum:]]+\\)[ \n]*" web-mode-sql-queries) beg) + ) + (web-mode-interpolate-sql-string beg end) + ) ;when + ) ;when beg end + ) ;while continue + ) ;when keywords + + ;;(when (and (member web-mode-engine '("jsp" "mako")) + (when (and (member web-mode-engine '("mako")) + (> (- reg-end reg-beg) 12) + (eq ?\< (char-after reg-beg))) + (web-mode-interpolate-block-tag reg-beg reg-end)) + + (when web-mode-enable-block-face +;; (message "block-face %S %S" reg-beg reg-end) + (font-lock-append-text-property reg-beg reg-end 'face 'web-mode-block-face)) + + )) + +(defun web-mode-fontify-part (reg-beg reg-end &optional depth) + (save-excursion + (let (start continue token-type face pos beg end string-face comment-face content-type) + ;;(message "fontify-part: reg-beg(%S) reg-end(%S)" reg-beg reg-end) + (if (member web-mode-content-type web-mode-part-content-types) + (setq content-type web-mode-content-type) + (setq content-type (symbol-name (get-text-property reg-beg 'part-side)))) + ;;(message "content-type=%S" content-type) + (unless depth + (when (string= content-type "jsx") (setq depth 0)) + ) + (setq string-face 'web-mode-part-string-face + comment-face 'web-mode-part-comment-face) + (cond + ((member content-type '("javascript" "jsx")) + (setq string-face 'web-mode-javascript-string-face + comment-face 'web-mode-javascript-comment-face) + (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords)) + ((string= content-type "json") + (setq string-face 'web-mode-json-string-face + comment-face 'web-mode-json-comment-face) + (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords)) + ((string= content-type "css") + (setq string-face 'web-mode-css-string-face + comment-face 'web-mode-css-comment-face) + (web-mode-fontify-css-rules reg-beg reg-end)) + ((string= content-type "sql") + (web-mode-fontify-region reg-beg reg-end web-mode-sql-font-lock-keywords)) + ((string= content-type "stylus") + (web-mode-fontify-region reg-beg reg-end web-mode-stylus-font-lock-keywords)) + ((string= content-type "sass") + (web-mode-fontify-region reg-beg reg-end web-mode-sass-font-lock-keywords)) + ((string= content-type "pug") + (web-mode-fontify-region reg-beg reg-end web-mode-pug-font-lock-keywords)) + ((string= content-type "markdown") + (web-mode-fontify-region reg-beg reg-end web-mode-markdown-font-lock-keywords)) + ((string= content-type "ruby") + (web-mode-fontify-region reg-beg reg-end web-mode-erb-font-lock-keywords)) + ((string= content-type "typescript") + (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords)) + ) ;cond + + (goto-char reg-beg) + + ;;(when (string= content-type "jsx") (web-mode-fontify-tags reg-beg reg-end)) + ;;(setq continue (and pos (< pos reg-end))) + (setq continue t + pos reg-beg) + (while continue + (if (get-text-property pos 'part-token) + (setq beg pos) + (setq beg (next-single-property-change pos 'part-token))) + (cond + ((or (null beg) (>= beg reg-end)) + (setq continue nil + end nil)) + ((and (eq depth 0) (get-text-property beg 'jsx-depth)) + (setq pos (or (next-single-property-change beg 'jsx-depth) (point-max)))) + (t + ;;(message "%c" (char-after beg)) + (setq token-type (get-text-property beg 'part-token)) + (setq face (cond + ((eq token-type 'string) string-face) + ((eq token-type 'comment) comment-face) + ((eq token-type 'context) 'web-mode-json-context-face) + ((eq token-type 'key) 'web-mode-json-key-face) + (t nil))) + (setq end (or (next-single-property-change beg 'part-token) (point-max)) + pos end) + (cond + ((or (null end) (> end reg-end)) + (setq continue nil + end nil)) + (t + (when face + (remove-list-of-text-properties beg end '(face)) + (put-text-property beg end 'font-lock-face face)) + (cond + ((< (- end beg) 6) + ) + ((eq token-type 'string) + (cond + ((and (eq (char-after beg) ?\`) + web-mode-enable-literal-interpolation + (member content-type '("javascript" "jsx"))) + (web-mode-interpolate-javascript-literal beg end) + ) + ((and (eq (char-after beg) ?\") + web-mode-enable-string-interpolation + (member content-type '("javascript" "jsx"))) + (web-mode-interpolate-javascript-string beg end)) + ) ;cond + ) ;case string + ((eq token-type 'comment) + (when web-mode-enable-comment-interpolation + (web-mode-interpolate-comment beg end t)) + (when web-mode-enable-comment-annotation + (web-mode-annotate-comment beg end)) + ) + ) ;cond + ) ;t + ) ;cond + ) ;t + ) ;cond + ) ;while + + (when (and (string= web-mode-content-type "html") web-mode-enable-part-face) + (font-lock-append-text-property reg-beg reg-end 'face + (cond + ((string= content-type "javascript") + 'web-mode-script-face) + ((string= content-type "css") + 'web-mode-style-face) + (t + 'web-mode-part-face))) + ) + + (when (and web-mode-enable-css-colorization (string= content-type "stylus")) + (goto-char reg-beg) + (while (and (re-search-forward "#[0-9a-fA-F]\\{6\\}\\|#[0-9a-fA-F]\\{3\\}\\|rgba?([ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)\\(.*?\\))" end t) + (<= (point) reg-end)) + (web-mode-colorize (match-beginning 0) (match-end 0)) + ) + ) + + (when (and (eq depth 0) (string= content-type "jsx")) + (let (pair elt-beg elt-end exp-beg exp-end exp-depth) + (goto-char reg-beg) + (while (setq pair (web-mode-jsx-element-next reg-end)) + ;;(message "elt-pair=%S" pair) + (setq elt-beg (car pair) + elt-end (cdr pair)) + (remove-list-of-text-properties elt-beg (1+ elt-end) '(face)) + (web-mode-fontify-tags elt-beg elt-end 1) + (goto-char elt-beg) + (while (setq pair (web-mode-jsx-expression-next elt-end)) + ;;(message "exp-pair=%S elt-end=%S" pair elt-end) + (setq exp-beg (car pair) + exp-end (cdr pair)) + (when (eq (char-after exp-beg) ?\{) + ;;(message "%S : %c %c" exp-beg (char-after (+ exp-beg 1)) (char-after (+ exp-beg 2))) + (cond + ;;((and (eq (char-after (+ exp-beg 1)) ?\/) (eq (char-after (+ exp-beg 2)) ?\*)) + ;; (put-text-property exp-beg (1+ exp-end) 'font-lock-face 'web-mode-part-comment-face) + ;; ) + (t + (setq exp-depth (get-text-property exp-beg 'jsx-depth)) + (remove-list-of-text-properties exp-beg exp-end '(font-lock-face)) + (put-text-property exp-beg (1+ exp-beg) 'font-lock-face 'web-mode-block-delimiter-face) + (when (and (eq (get-text-property exp-beg 'tag-attr-beg) 4) (web-mode-looking-at-p "\.\.\." (1+ exp-beg))) + (put-text-property exp-beg (+ exp-beg 4) 'font-lock-face 'web-mode-block-delimiter-face)) + (put-text-property exp-end (1+ exp-end) 'font-lock-face 'web-mode-block-delimiter-face) + (web-mode-fontify-tags (1+ exp-beg) exp-end (1+ exp-depth)) + (web-mode-fontify-part (1+ exp-beg) exp-end exp-depth) + (web-mode-fontify-region (1+ exp-beg) exp-end web-mode-javascript-font-lock-keywords) + ) ;t + ) ;cond + ) ;when + (goto-char (1+ exp-beg)) + ) ;while exp + + (when (and elt-beg web-mode-jsx-depth-faces) + (let (depth-beg depth-end jsx-face) + (goto-char elt-beg) + (while (setq pair (web-mode-jsx-depth-next reg-end)) + ;;(message "depth-pair=%S" pair) + (setq depth-beg (car pair) + depth-end (cdr pair) + depth (get-text-property depth-beg 'jsx-depth) + jsx-face (elt web-mode-jsx-depth-faces (1- depth))) + ;;(message "%S" jsx-face) + (font-lock-prepend-text-property depth-beg (1+ depth-end) 'face jsx-face) + (goto-char (+ depth-beg 2)) + ) + ) ;let + ) + + (goto-char (1+ elt-end)) + ) ;while elt + ) ;let + ) ;when + + ) ;let + ) ;save-excursion + ) + +(defun web-mode-fontify-css-rules (part-beg part-end) + (save-excursion + (goto-char part-beg) + (let (rule (continue t) (i 0) (at-rule nil) (var-rule nil)) + (while continue + (setq rule (web-mode-css-rule-next part-end)) + ;;(message "rule=%S" rule) + (cond + ((> (setq i (1+ i)) 1000) + (message "fontify-css-rules ** too much rules **") + (setq continue nil)) + ((null rule) + (setq continue nil)) + ((and (setq at-rule (plist-get rule :at-rule)) + (not (member at-rule '("charset" "font-face" "import" "viewport"))) + (plist-get rule :dec-end)) + (web-mode-fontify-css-rule (plist-get rule :sel-beg) + (plist-get rule :sel-end) + nil nil) + (web-mode-fontify-css-rules (plist-get rule :dec-beg) + (plist-get rule :dec-end))) + (t + (web-mode-fontify-css-rule (plist-get rule :sel-beg) + (plist-get rule :sel-end) + (plist-get rule :dec-beg) + (plist-get rule :dec-end))) + ) ;cond + ) ;while + ) ;let + )) + +(defun web-mode-fontify-css-rule (sel-beg sel-end dec-beg dec-end) + (save-excursion + ;;(let ((end sel-end)) + ;;(message "sel-beg=%S sel-end=%S dec-beg=%S dec-end=%S" sel-beg sel-end dec-beg dec-end) + (web-mode-fontify-region sel-beg sel-end web-mode-selector-font-lock-keywords) + (when (and dec-beg dec-end) + ;;(setq end dec-end) + (web-mode-fontify-region dec-beg dec-end web-mode-declaration-font-lock-keywords) + ) ;when + (when (and dec-beg dec-end) + (goto-char dec-beg) + (while (and web-mode-enable-css-colorization + (re-search-forward "#[0-9a-fA-F]\\{6\\}\\|#[0-9a-fA-F]\\{3\\}\\|rgba?([ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)\\(.*?\\))" dec-end t) + ;;(progn (message "%S %S" end (point)) t) + (<= (point) dec-end)) + (web-mode-colorize (match-beginning 0) (match-end 0)) + ) ;while + ) ;when + ;;) ;let + )) + +(defun web-mode-colorize-foreground (color) + (let* ((values (x-color-values color)) + (r (car values)) + (g (cadr values)) + (b (car (cdr (cdr values))))) + (if (> 128.0 (floor (+ (* .3 r) (* .59 g) (* .11 b)) 256)) + "white" "black"))) + +(defun web-mode-colorize (beg end) + (let (str plist len) + (setq str (buffer-substring-no-properties beg end)) + (setq len (length str)) + (cond + ((string= (substring str 0 1) "#") + (setq plist (list :background str + :foreground (web-mode-colorize-foreground str))) + (put-text-property beg end 'face plist)) + ((or (string= (substring str 0 4) "rgb(") (string= (substring str 0 5) "rgba(")) + (setq str (format "#%02X%02X%02X" + (string-to-number (match-string-no-properties 1)) + (string-to-number (match-string-no-properties 2)) + (string-to-number (match-string-no-properties 3)))) + (setq plist (list :background str + :foreground (web-mode-colorize-foreground str))) + (put-text-property beg end 'face plist)) + ) ;cond + )) + +(defun web-mode-interpolate-block-tag (beg end) + (save-excursion + (goto-char (+ 4 beg)) + (setq end (1- end)) + (while (re-search-forward "${.*?}" end t) + (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(face)) + (web-mode-fontify-region (match-beginning 0) (match-end 0) + web-mode-uel-font-lock-keywords)) + )) + +(defun web-mode-interpolate-javascript-string (beg end) + (save-excursion + (goto-char (1+ beg)) + (setq end (1- end)) + (while (re-search-forward "${.*?}" end t) + (put-text-property (match-beginning 0) (match-end 0) + 'font-lock-face + 'web-mode-variable-name-face) + ) + )) + +(defun web-mode-interpolate-javascript-literal (beg end) + (save-excursion + (goto-char (1+ beg)) + (setq end (1- end)) + (while (re-search-forward "${.*?}" end t) + (put-text-property (match-beginning 0) (match-end 0) + 'font-lock-face + 'web-mode-variable-name-face) + ) + (cond + ((web-mode-looking-back "\\(css\\|styled[[:alnum:].]+\\)" beg) + (goto-char (1+ beg)) + (while (re-search-forward ".*?:" end t) + (put-text-property (match-beginning 0) (match-end 0) + 'font-lock-face + 'web-mode-interpolate-color1-face) + ) + ) ;case css + ((web-mode-looking-back "\\(template\\|html\\)" beg) + (goto-char (1+ beg)) + (while (re-search-forward web-mode-tag-regexp end t) + (put-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-interpolate-color1-face) + ) + (goto-char (1+ beg)) + (while (re-search-forward "\\| [[:alnum:]]+=" end t) + (cond + ((member (char-after (match-beginning 0)) '(?\< ?\/ ?\>)) + (put-text-property (match-beginning 0) (match-end 0) + 'font-lock-face + 'web-mode-interpolate-color2-face) + ) + (t + (put-text-property (1+ (match-beginning 0)) (1- (match-end 0)) + 'font-lock-face + 'web-mode-interpolate-color3-face) + ) ;t + ) ;cond + ) ;while + ) ;case html + ) ;cond type of literal + )) + +;; todo : parsing plus compliqué: {$obj->values[3]->name} +(defun web-mode-interpolate-block-string (beg end) + (save-excursion + (goto-char (1+ beg)) + (setq end (1- end)) + (cond + ((string= web-mode-engine "php") + (while (re-search-forward "$[[:alnum:]_]+\\(->[[:alnum:]_]+\\)*\\|{[ ]*$.+?}" end t) +;; (message "%S > %S" (match-beginning 0) (match-end 0)) + (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(font-lock-face)) + (web-mode-fontify-region (match-beginning 0) (match-end 0) + web-mode-php-var-interpolation-font-lock-keywords) + )) + ((string= web-mode-engine "erb") + (while (re-search-forward "#{.*?}" end t) + (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(font-lock-face)) + (put-text-property (match-beginning 0) (match-end 0) + 'font-lock-face 'web-mode-variable-name-face) + )) + ) ;cond + )) + +(defun web-mode-interpolate-comment (beg end block-side) + (save-excursion + (let ((regexp (concat "\\_<\\(" web-mode-comment-keywords "\\)\\_>"))) + (goto-char beg) + (while (re-search-forward regexp end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-comment-keyword-face) + ) ;while + ))) + +(defun web-mode-annotate-comment (beg end) + (save-excursion + ;;(message "beg=%S end=%S" beg end) + (goto-char beg) + (when (looking-at-p "/\\*\\*") + (while (re-search-forward "\\(.+\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-face)) + (goto-char beg) + (while (re-search-forward "[ ]+\\({[^}]+}\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-type-face)) + (goto-char beg) + (while (re-search-forward "\\(@[[:alnum:]]+\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-tag-face)) + (goto-char beg) + (while (re-search-forward "}[[:blank:]]+\\([[:graph:]]+\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-value-face)) + (goto-char beg) + (while (re-search-forward "@see[[:blank:]]+\\([[:graph:]]+\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-value-face)) + (goto-char beg) + (while (re-search-forward "{\\(@\\(?:link\\|code\\)\\)\\s-+\\([^}\n]+\\)\\(#.+\\)?}" end t) + (font-lock-prepend-text-property (match-beginning 2) (match-end 2) + 'font-lock-face + 'web-mode-annotation-value-face)) + (goto-char beg) + (while (re-search-forward "\\(\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-html-face) + (font-lock-prepend-text-property (match-beginning 2) (match-end 2) + 'font-lock-face + 'web-mode-annotation-html-face) + (font-lock-prepend-text-property (match-beginning 3) (match-end 3) + 'font-lock-face + 'web-mode-annotation-html-face)) + ) ;when + )) + +(defun web-mode-interpolate-sql-string (beg end) + (save-excursion + (let ((case-fold-search t) + (regexp (concat "\\_<\\(" web-mode-sql-keywords "\\)\\_>"))) + (goto-char beg) + (while (re-search-forward regexp end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-sql-keyword-face) + ) ;while + ))) + +;;---- EFFECTS ----------------------------------------------------------------- + +(defun web-mode-fill-paragraph (&optional justify) + (save-excursion + (let ((pos (point)) fill-coll + prop pair beg end delim-beg delim-end chunk fill-col) + (cond + ((or (eq (get-text-property pos 'part-token) 'comment) + (eq (get-text-property pos 'block-token) 'comment)) + (setq prop + (if (get-text-property pos 'part-token) 'part-token 'block-token)) + (setq pair (web-mode-property-boundaries prop pos)) + (when (and pair (> (- (cdr pair) (car pair)) 6)) + (setq fill-coll (if (< fill-column 10) 70 fill-column)) + (setq beg (car pair) + end (cdr pair)) + (goto-char beg) + (setq chunk (buffer-substring-no-properties beg (+ beg 2))) + (cond + ((string= chunk "//") + (setq delim-beg "//" + delim-end "EOL")) + ((string= chunk "/*") + (setq delim-beg "/*" + delim-end "*/")) + ((string= chunk "{#") + (setq delim-beg "{#" + delim-end "#}")) + ((string= chunk "")) + ) + ) + ) ;comment - case + ((web-mode-is-content) + (setq pair (web-mode-content-boundaries pos)) + (setq beg (car pair) + end (cdr pair)) + ) + ) ;cond + ;;(message "beg(%S) end(%S)" beg end) + (when (and beg end) + (fill-region beg end)) + t))) + +(defun web-mode-engine-syntax-check () + (interactive) + (let ((proc nil) (errors nil) + (file (concat temporary-file-directory "emacs-web-mode-tmp"))) + (write-region (point-min) (point-max) file) + (cond + ;; ((null (buffer-file-name)) + ;; ) + ((string= web-mode-engine "php") + (setq proc (start-process "php-proc" nil "php" "-l" file)) + (set-process-filter + proc + (lambda (proc output) + (cond + ((string-match-p "No syntax errors" output) + (message "No syntax errors") + ) + (t + ;; (setq output (replace-regexp-in-string temporary-file-directory "" output)) + ;; (message output) + (message "Syntax error") + (setq errors t)) + ) ;cond + ;; (delete-file file) + ) ;lambda + ) + ) ;php + (t + (message "no syntax checker found") + ) ;t + ) ;cond + errors)) + +(defun web-mode-jshint () + "Run JSHint on all the JavaScript parts." + (interactive) + (let (proc lines) + (when (buffer-file-name) + (setq proc (start-process + "jshint-proc" + nil + (or (executable-find "jshint") "/usr/local/bin/jshint") + "--extract=auto" + (buffer-file-name))) + (setq web-mode-jshint-errors 0) + (set-process-filter proc + (lambda (proc output) + (let ((offset 0) overlay pos (old 0) msg) + (remove-overlays (point-min) (point-max) 'font-lock-face 'web-mode-error-face) + (while (string-match + "line \\([[:digit:]]+\\), col \\([[:digit:]]+\\), \\(.+\\)\\.$" + output offset) + (setq web-mode-jshint-errors (1+ web-mode-jshint-errors)) + (setq offset (match-end 0)) + (setq pos (web-mode-coord-position + (match-string-no-properties 1 output) + (match-string-no-properties 2 output))) + (when (get-text-property pos 'tag-beg) + (setq pos (1- pos))) + (when (not (= pos old)) + (setq old pos) + (setq overlay (make-overlay pos (1+ pos))) + (overlay-put overlay 'font-lock-face 'web-mode-error-face) + ) + (setq msg (or (overlay-get overlay 'help-echo) + (concat "line=" + (match-string-no-properties 1 output) + " column=" + (match-string-no-properties 2 output) + ))) + (overlay-put overlay 'help-echo + (concat msg " ## " (match-string-no-properties 3 output))) + ) ;while + )) + ) + ) ;when + )) + +(defun web-mode-dom-errors-show () + "Show unclosed tags." + (interactive) + (let (beg end tag pos l n tags i cont cell overlay overlays first + (ori (point)) + (errors 0) + (continue t) + ) + (setq overlays (overlays-in (point-min) (point-max))) + (when overlays + (dolist (overlay overlays) + (when (eq (overlay-get overlay 'face) 'web-mode-warning-face) + (delete-overlay overlay) + ) + ) + ) + (goto-char (point-min)) + (when (not (or (get-text-property (point) 'tag-beg) + (web-mode-tag-next))) + (setq continue nil)) + (while continue + (setq pos (point)) + (setq tag (get-text-property pos 'tag-name)) + (cond + ((eq (get-text-property (point) 'tag-type) 'start) + (setq tags (add-to-list 'tags (list tag pos))) +;; (message "(%S) opening %S" pos tag) + ) + ((eq (get-text-property (point) 'tag-type) 'end) + (setq i 0 + l (length tags) + cont t) + (while (and (< i l) cont) + (setq cell (nth i tags)) +;; (message "cell=%S" cell) + (setq i (1+ i)) + (cond + ((string= tag (nth 0 cell)) + (setq cont nil) + ) + (t + (setq errors (1+ errors)) + (setq beg (nth 1 cell)) + (setq end (web-mode-tag-end-position beg)) + (unless first + (setq first beg)) + (setq overlay (make-overlay beg (1+ end))) + (overlay-put overlay 'font-lock-face 'web-mode-warning-face) +;; (message "invalid <%S> at %S" (nth 0 cell) (nth 1 cell)) + ) + ) ;cond + ) ;while + + (dotimes (i i) + (setq tags (cdr tags))) + + ) + ) ;cond + (when (not (web-mode-tag-next)) + (setq continue nil)) + ) ;while + (message "%S error(s) detected" errors) + (if (< errors 1) + (goto-char ori) + (goto-char first) + (recenter)) + ;; (message "%S" tags) + )) + +(defun web-mode-fontify-elements (beg end) + (save-excursion + (goto-char beg) + (let ((continue (or (get-text-property (point) 'tag-beg) (web-mode-tag-next))) + (i 0) (ctx nil) (face nil)) + (while continue + (cond + ((> (setq i (1+ i)) 1000) + (message "fontify-elements ** too much tags **") + (setq continue nil)) + ((> (point) end) + (setq continue nil)) + ((not (get-text-property (point) 'tag-beg)) + (setq continue nil)) + ((eq (get-text-property (point) 'tag-type) 'start) + (when (and (setq ctx (web-mode-element-boundaries (point))) + (<= (car (cdr ctx)) end) + (setq face (cdr (assoc (get-text-property (point) 'tag-name) web-mode-element-content-faces)))) + (font-lock-prepend-text-property (1+ (cdr (car ctx))) (car (cdr ctx)) + 'font-lock-face face)) + ) + ) ;cond + (when (not (web-mode-tag-next)) + (setq continue nil)) + ) ;while + ))) + +(defun web-mode-enable (feature) + "Enable one feature." + (interactive + (list (completing-read + "Feature: " + (let (features) + (dolist (elt web-mode-features) + (setq features (append features (list (car elt))))) + features)))) + (when (and (or (not feature) (< (length feature) 1)) web-mode-last-enabled-feature) + (setq feature web-mode-last-enabled-feature)) + (when feature + (setq web-mode-last-enabled-feature feature) + (setq feature (cdr (assoc feature web-mode-features))) + (cond + ((eq feature 'web-mode-enable-current-column-highlight) + (web-mode-column-show)) + ((eq feature 'web-mode-enable-current-element-highlight) + (when (not web-mode-enable-current-element-highlight) + (web-mode-toggle-current-element-highlight)) + ) + ((eq feature 'web-mode-enable-whitespace-fontification) + (web-mode-whitespaces-on)) + (t + (set feature t) + (web-mode-buffer-fontify)) + ) + ) ;when + ) + +(defun web-mode-disable (feature) + "Disable one feature." + (interactive + (list (completing-read + "Feature: " + (let (features) + (dolist (elt web-mode-features) + (setq features (append features (list (car elt))))) + features)))) + (when (and (or (not feature) (< (length feature) 1)) web-mode-last-enabled-feature) + (setq feature web-mode-last-enabled-feature)) + (when feature + (setq feature (cdr (assoc feature web-mode-features))) + (cond + ((eq feature 'web-mode-enable-current-column-highlight) + (web-mode-column-hide)) + ((eq feature 'web-mode-enable-current-element-highlight) + (when web-mode-enable-current-element-highlight + (web-mode-toggle-current-element-highlight)) + ) + ((eq feature 'web-mode-enable-whitespace-fontification) + (web-mode-whitespaces-off)) + (t + (set feature nil) + (web-mode-buffer-fontify)) + ) + ) ;when + ) + +(defun web-mode-toggle-current-element-highlight () + "Toggle highlighting of the current html element." + (interactive) + (if web-mode-enable-current-element-highlight + (progn + (web-mode-delete-tag-overlays) + (setq web-mode-enable-current-element-highlight nil)) + (setq web-mode-enable-current-element-highlight t) + )) + +(defun web-mode-make-tag-overlays () + (unless web-mode-overlay-tag-start + (setq web-mode-overlay-tag-start (make-overlay 1 1) + web-mode-overlay-tag-end (make-overlay 1 1)) + (overlay-put web-mode-overlay-tag-start + 'font-lock-face + 'web-mode-current-element-highlight-face) + (overlay-put web-mode-overlay-tag-end + 'font-lock-face + 'web-mode-current-element-highlight-face))) + +(defun web-mode-delete-tag-overlays () + (when web-mode-overlay-tag-start + (delete-overlay web-mode-overlay-tag-start) + (delete-overlay web-mode-overlay-tag-end))) + +(defun web-mode-column-overlay-factory (index) + (let (overlay) + (when (null web-mode-column-overlays) + (dotimes (i 100) + (setq overlay (make-overlay 1 1)) + (overlay-put overlay 'font-lock-face 'web-mode-current-column-highlight-face) + (setq web-mode-column-overlays (append web-mode-column-overlays (list overlay))) + ) + ) ;when + (setq overlay (nth index web-mode-column-overlays)) + (when (null overlay) + (setq overlay (make-overlay 1 1)) + (overlay-put overlay 'font-lock-face 'web-mode-current-column-highlight-face) + (setq web-mode-column-overlays (append web-mode-column-overlays (list overlay))) + ) ;when + overlay)) + +(defun web-mode-column-hide () + (setq web-mode-enable-current-column-highlight nil) + (remove-overlays (point-min) (point-max) + 'font-lock-face + 'web-mode-current-column-highlight-face)) + +(defun web-mode-column-show () + (let ((index 0) overlay diff column line-to line-from) + (web-mode-column-hide) + (setq web-mode-enable-current-column-highlight t) + (save-excursion + (back-to-indentation) + (setq column (current-column) + line-to (web-mode-line-number)) + (when (and (get-text-property (point) 'tag-beg) + (member (get-text-property (point) 'tag-type) '(start end)) + (web-mode-tag-match) + (setq line-from (web-mode-line-number)) + (not (= line-from line-to))) + (when (> line-from line-to) + (let (tmp) + (setq tmp line-from) + (setq line-from line-to) + (setq line-to tmp)) + ) ;when + ;;(message "column(%S) line-from(%S) line-to(%S)" column line-from line-to) + (goto-char (point-min)) + (when (> line-from 1) + (forward-line (1- line-from))) + (while (<= line-from line-to) + (setq overlay (web-mode-column-overlay-factory index)) + (setq diff (- (line-end-position) (point))) + (cond + ((or (and (= column 0) (= diff 0)) + (> column diff)) + (end-of-line) + (move-overlay overlay (point) (point)) + (overlay-put overlay + 'after-string + (concat + (if (> column diff) (make-string (- column diff) ?\s) "") + (propertize " " + 'font-lock-face + 'web-mode-current-column-highlight-face) + ) ;concat + ) + ) + (t + (move-to-column column) + (overlay-put overlay 'after-string nil) + (move-overlay overlay (point) (1+ (point))) + ) + ) ;cond + (setq line-from (1+ line-from)) + (forward-line) + (setq index (1+ index)) + ) ;while + ) ;when + ) ;save-excursion + ) ;let + ) + +(defun web-mode-highlight-current-element () + (let ((ctx (web-mode-element-boundaries)) len) + (cond + ((null ctx) + (web-mode-delete-tag-overlays)) + ((eq (get-text-property (caar ctx) 'tag-type) 'void) ;; #1046 + (web-mode-make-tag-overlays) + (setq len (length (get-text-property (caar ctx) 'tag-name))) + (move-overlay web-mode-overlay-tag-start (+ (caar ctx) 1) (+ (caar ctx) 1 len)) + ) + (t + (web-mode-make-tag-overlays) + (setq len (length (get-text-property (caar ctx) 'tag-name))) + (move-overlay web-mode-overlay-tag-start (+ (caar ctx) 1) (+ (caar ctx) 1 len)) + (move-overlay web-mode-overlay-tag-end (+ (cadr ctx) 2) (+ (cadr ctx) 2 len)) + ) ;t + ) ;cond + )) + +(defun web-mode-fontify-whitespaces (beg end) + (save-excursion + (goto-char beg) + (while (re-search-forward web-mode-whitespaces-regexp end t) + (add-text-properties (match-beginning 0) (match-end 0) + '(face web-mode-whitespace-face)) + ) ;while + )) + +(defun web-mode-whitespaces-show () + "Toggle whitespaces." + (interactive) + (if web-mode-enable-whitespace-fontification + (web-mode-whitespaces-off) + (web-mode-whitespaces-on))) + +(defun web-mode-whitespaces-on () + "Show whitespaces." + (interactive) + (when web-mode-display-table + (setq buffer-display-table web-mode-display-table)) + (setq web-mode-enable-whitespace-fontification t)) + +(defun web-mode-whitespaces-off () + (setq buffer-display-table nil) + (setq web-mode-enable-whitespace-fontification nil)) + +(defun web-mode-use-tabs () + "Tweaks vars to be compatible with TAB indentation." + (let (offset) + (setq web-mode-block-padding 0) + (setq web-mode-script-padding 0) + (setq web-mode-style-padding 0) + (setq offset + (cond + ((and (boundp 'tab-width) tab-width) tab-width) + ((and (boundp 'standard-indent) standard-indent) standard-indent) + (t 4))) + ;; (message "offset(%S)" offset) + (setq web-mode-attr-indent-offset offset) + (setq web-mode-code-indent-offset offset) + (setq web-mode-css-indent-offset offset) + (setq web-mode-markup-indent-offset offset) + (setq web-mode-sql-indent-offset offset) + (add-to-list 'web-mode-indentation-params '("lineup-args" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-calls" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-concats" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-ternary" . nil)) + )) + +(defun web-mode-element-children-fold-or-unfold (&optional pos) + "Fold/Unfold all the children of the current html element." + (interactive) + (unless pos (setq pos (point))) + (save-excursion + (dolist (child (reverse (web-mode-element-children pos))) + (goto-char child) + (web-mode-fold-or-unfold)) + )) + +(defun web-mode-fold-or-unfold (&optional pos) + "Toggle folding on an html element or a control block." + (interactive) + (web-mode-scan) + (web-mode-with-silent-modifications + (save-excursion + (if pos (goto-char pos)) + (let (beg-inside beg-outside end-inside end-outside overlay overlays regexp) + (when (looking-back "^[\t ]*" (point-min)) + (back-to-indentation)) + (setq overlays (overlays-at (point))) + (dolist (elt overlays) + (when (and (not overlay) + (eq (overlay-get elt 'font-lock-face) 'web-mode-folded-face)) + (setq overlay elt))) + (cond + ;; *** unfolding + (overlay + (setq beg-inside (overlay-start overlay) + end-inside (overlay-end overlay)) + (remove-overlays beg-inside end-inside) + (put-text-property beg-inside end-inside 'invisible nil) + ) + ;; *** block folding + ((and (get-text-property (point) 'block-side) + (cdr (web-mode-block-is-control (point)))) + (setq beg-outside (web-mode-block-beginning-position (point))) + (setq beg-inside (1+ (web-mode-block-end-position (point)))) + (when (web-mode-block-match) + (setq end-inside (point)) + (setq end-outside (1+ (web-mode-block-end-position (point))))) + ) + ;; *** html comment folding + ((eq (get-text-property (point) 'tag-type) 'comment) + (setq beg-outside (web-mode-tag-beginning-position)) + (setq beg-inside (+ beg-outside 4)) + (setq end-outside (web-mode-tag-end-position)) + (setq end-inside (- end-outside 3)) + ) + ;; *** tag folding + ((or (member (get-text-property (point) 'tag-type) '(start end)) + (web-mode-element-parent)) + (when (not (web-mode-element-is-collapsed (point))) + (web-mode-tag-beginning) + (when (eq (get-text-property (point) 'tag-type) 'end) + (web-mode-tag-match)) + (setq beg-outside (point)) + (web-mode-tag-end) + (setq beg-inside (point)) + (goto-char beg-outside) + (when (web-mode-tag-match) + (setq end-inside (point)) + (web-mode-tag-end) + (setq end-outside (point))) + ) + ) + ) ;cond + (when (and beg-inside beg-outside end-inside end-outside) + (setq overlay (make-overlay beg-outside end-outside)) + (overlay-put overlay 'font-lock-face 'web-mode-folded-face) + (put-text-property beg-inside end-inside 'invisible t)) + )))) + +;;---- TRANSFORMATION ---------------------------------------------------------- + +(defun web-mode-buffer-change-tag-case (&optional type) + "Change html tag case." + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((continue t) f) + (setq f (if (member type '("upper" "uppercase" "upper-case")) 'uppercase 'downcase)) + (when (and (not (get-text-property (point) 'tag-beg)) + (not (web-mode-tag-next))) + (setq continue nil)) + (while continue + (skip-chars-forward " and < in html content." + (interactive) + (save-excursion + (let (expr (min (point-min)) (max (point-max))) + (when mark-active + (setq min (region-beginning) + max (region-end)) + (deactivate-mark)) + (goto-char min) + (while (web-mode-content-rsf "[&<>]" max) + (replace-match (cdr (assq (char-before) web-mode-xml-chars)) t t)) + ))) + +(defun web-mode-dom-quotes-replace () + "Replace dumb quotes." + (interactive) + (save-excursion + (let (expr (min (point-min)) (max (point-max))) + (when mark-active + (setq min (region-beginning) + max (region-end)) + (deactivate-mark)) + (goto-char min) + (setq expr (concat (car web-mode-smart-quotes) "\\2" (cdr web-mode-smart-quotes))) + (while (web-mode-content-rsf "\\(\"\\)\\(.\\{1,200\\}\\)\\(\"\\)" max) + (replace-match expr) + ) ;while + ))) + +;;---- INDENTATION ------------------------------------------------------------- + +;; todo : passer de règle en règle et mettre un \n à la fin +(defun web-mode-css-indent () + (save-excursion + (goto-char (point-min)) + (let ((continue t) rule part-end) + (while continue + (cond + ((not (web-mode-part-next)) + (setq continue nil)) + ((eq (get-text-property (point) 'part-side) 'css) + (setq part-end (web-mode-part-end-position)) + (while (setq rule (web-mode-css-rule-next part-end)) + (when (not (looking-at-p "[[:space:]]*\\($\\|<\\)")) + (newline) + (indent-according-to-mode) + (setq part-end (web-mode-part-end-position))) + ) + ) + ) ;cond + ) + ))) + +(defun web-mode-buffer-indent () + "Indent all buffer." + (interactive) + (let ((debug t) (ts (current-time)) (sub nil)) + (indent-region (point-min) (point-max)) + (when debug + (setq sub (time-subtract (current-time) ts)) + (message "buffer-indent: time elapsed = %Ss %9Sµs" (nth 1 sub) (nth 2 sub))) + (delete-trailing-whitespace))) + +(defun web-mode-point-context (pos) + "POS should be at the beginning of the indentation." + (save-excursion + (let (curr-char curr-indentation curr-line + language + options + reg-beg reg-col + prev-char prev-indentation prev-line prev-pos + token + part-language + depth) + + (setq reg-beg (point-min) + reg-col 0 + token "live" + options "" + language "" + prev-line "" + prev-char 0 + prev-pos nil) + + (when (get-text-property pos 'part-side) + (setq part-language (symbol-name (get-text-property pos 'part-side)))) + + ;;(message "part-language=%S" part-language) + + (cond + + ((and (bobp) (member web-mode-content-type '("html" "xml"))) + (setq language web-mode-content-type) + ) + + ((string= web-mode-content-type "css") + (setq language "css" + curr-indentation web-mode-css-indent-offset)) + + ((member web-mode-content-type '("javascript" "json" "typescript")) + (setq language web-mode-content-type + curr-indentation web-mode-code-indent-offset)) + + ((or (string= web-mode-content-type "jsx") + (and part-language (string= part-language "jsx"))) + (setq language "jsx" + curr-indentation web-mode-code-indent-offset) + (cond + ((web-mode-jsx-is-html pos) + (setq curr-indentation web-mode-markup-indent-offset + options "is-html")) + ((and (setq depth (get-text-property pos 'jsx-depth)) (> depth 1)) + (when (get-text-property pos 'jsx-beg) + (setq depth (1- depth))) + (setq reg-beg (web-mode-jsx-depth-beginning-position pos depth)) + (setq reg-beg (1+ reg-beg)) + ;;(message "%S" (point)) + (save-excursion + (goto-char reg-beg) + ;;(message "pt=%S" reg-beg) + (cond + ((and (not (looking-at-p "[ ]*$")) + (looking-back "^[[:space:]]*{" (point-min))) + (setq reg-col (+ (current-indentation) ;; #1027 + (cond + ((looking-at "[ ]+") (1+ (length (match-string-no-properties 0)))) + (t 0)) + )) + ) + ((looking-at-p "[ ]*\\[[ ]*$") ;; #0659 + (setq reg-col (current-indentation)) + ) + ((and (looking-back "=[ ]*{" (point-min)) ;; #0739 #1022 + (not (looking-at-p "[[:space:]]*<"))) + (setq reg-col (current-indentation)) + ) + ;;((and (looking-back "=[ ]*{" (point-min)) ;; #0739 + ;; (looking-at-p "{[ ]*")) + ;; (setq reg-col (current-indentation)) + ;; ) + ((get-text-property (1- (point)) 'tag-beg) + ;;(message "point=%S" (point)) + (setq reg-col (current-indentation)) + ) + (t + (message "%S : %S %S" (point) (current-indentation) web-mode-code-indent-offset) + ;;(setq reg-col (+ (current-indentation) web-mode-code-indent-offset web-mode-jsx-expression-padding))) + (setq reg-col (+ (current-indentation) web-mode-code-indent-offset))) + ) + + ;;(message "%S %S %S" (point) (current-indentation) reg-col) + ) ;save-excursion + ) + ((string= web-mode-content-type "jsx") + (setq reg-beg (point-min))) + (t + (setq reg-beg (or (web-mode-part-beginning-position pos) (point-min))) + (save-excursion + (goto-char reg-beg) + (search-backward "<" nil t) + (setq reg-col (current-column)) + ) ;save-excursion + ) + ) ;cond + ;;(message "jsx reg-beg=%S" reg-beg) + ) ;jsx + + ((string= web-mode-content-type "php") + (setq language "php" + curr-indentation web-mode-code-indent-offset)) + + ((or (string= web-mode-content-type "xml")) + (setq language "xml" + curr-indentation web-mode-markup-indent-offset)) + + ;; TODO: est ce util ? + ((and (get-text-property pos 'tag-beg) + (get-text-property pos 'tag-name) + ;;(not (get-text-property pos 'part-side)) + ) + (setq language "html" + curr-indentation web-mode-markup-indent-offset)) + + ((and (get-text-property pos 'block-side) + (not (get-text-property pos 'block-beg))) + + (setq reg-beg (or (web-mode-block-beginning-position pos) (point-min))) + (goto-char reg-beg) + (setq reg-col (current-column)) + ;;(message "%S %S" reg-beg reg-col) + (setq language web-mode-engine) + (setq curr-indentation web-mode-code-indent-offset) + + (cond + ((string= web-mode-engine "blade") + (save-excursion + (when (web-mode-rsf "{[{!]+[ ]*") + (setq reg-col (current-column)))) + (setq reg-beg (+ reg-beg 2)) + ) + ((string= web-mode-engine "razor") + ;;(setq reg-beg (+ reg-beg 2)) + ;;(setq reg-col (current-column)) + ) + ;; tests/demo.chtml + ((string= web-mode-engine "ctemplate") + (save-excursion + (when (web-mode-rsf "{{#?") + (setq reg-col (current-column)))) + ) + ((string= web-mode-engine "dust") + (save-excursion + (when (web-mode-rsf "{@") + (setq reg-col (current-column)))) + ) + ((string= web-mode-engine "svelte") + (save-excursion + (when (web-mode-rsf "{@") + (setq reg-col (current-column)))) + ) + ((string= web-mode-engine "template-toolkit") + (setq reg-beg (+ reg-beg 3) + reg-col (+ reg-col 3)) + ) + ((and (string= web-mode-engine "jsp") + (web-mode-looking-at "<%@" reg-beg)) + (save-excursion + (goto-char reg-beg) + (looking-at "<%@[ ]*[[:alpha:]]+[ ]+\\| pos (point-min)) + (eq (get-text-property pos 'part-token) 'comment) + (eq (get-text-property (1- pos) 'part-token) 'comment) + (progn + (setq reg-beg (previous-single-property-change pos 'part-token)) + t)) + (and (> pos (point-min)) + (eq (get-text-property pos 'block-token) 'comment) + (eq (get-text-property (1- pos) 'block-token) 'comment) + (progn + (setq reg-beg (previous-single-property-change pos 'block-token)) + t)) + (and (> pos (point-min)) + (eq (get-text-property pos 'tag-type) 'comment) + (not (get-text-property pos 'tag-beg)) + (progn + (setq reg-beg (web-mode-tag-beginning-position pos)) + t)) + ) + (setq token "comment")) + ((or (and (> pos (point-min)) + (member (get-text-property pos 'part-token) + '(string context key)) + (member (get-text-property (1- pos) 'part-token) + '(string context key))) + (and (eq (get-text-property pos 'block-token) 'string) + (eq (get-text-property (1- pos) 'block-token) 'string))) + (setq token "string")) + ) + + (goto-char pos) + (setq curr-line (web-mode-trim + (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (setq curr-char (if (string= curr-line "") 0 (aref curr-line 0))) + + (when (or (member language '("php" "blade" "javascript" "typescript" "jsx" "razor" "css")) + (and (member language '("html" "xml")) + (not (eq ?\< curr-char)))) + (let (prev) + (cond + ((member language '("html" "xml" "javascript" "jsx" "css")) + (when (setq prev (web-mode-part-previous-live-line reg-beg)) + (setq prev-line (nth 0 prev) + prev-indentation (nth 1 prev) + prev-pos (nth 2 prev)) + ) + ) + ((setq prev (web-mode-block-previous-live-line)) + (setq prev-line (car prev) + prev-indentation (cdr prev)) + (setq prev-line (web-mode-clean-block-line prev-line))) + ) ;cond + ) ;let + (when (>= (length prev-line) 1) + (setq prev-char (aref prev-line (1- (length prev-line)))) + (setq prev-line (substring-no-properties prev-line)) + ) + ) + + (cond + ((not (member web-mode-content-type '("html" "xml"))) + ) + ((member language '("javascript" "typescript" "jsx" "ruby")) + (setq reg-col (if web-mode-script-padding (+ reg-col web-mode-script-padding) 0))) + ((member language '("css" "sql" "markdown" "pug" "sass" "stylus")) + (setq reg-col (if web-mode-style-padding (+ reg-col web-mode-style-padding) 0))) + ((not (member language '("html" "xml"))) + (setq reg-col + (cond + ((not web-mode-block-padding) reg-col) + ((eq web-mode-block-padding -1) 0) + (t (+ reg-col web-mode-block-padding)) + ) ;cond + ) ;setq + ) + ) + + (list :curr-char curr-char + :curr-indentation curr-indentation + :curr-line curr-line + :language language + :options options + :prev-char prev-char + :prev-indentation prev-indentation + :prev-line prev-line + :prev-pos prev-pos + :reg-beg reg-beg + :reg-col reg-col + :token token) + ))) + +(defun web-mode-indent-line () + + (web-mode-scan) + + (let ((offset nil) + (char nil) + (debug nil) + (inhibit-modification-hooks nil) + (adjust t)) + + (save-excursion + (back-to-indentation) + (setq char (char-after)) + (let* ((pos (point)) + (ctx (web-mode-point-context pos)) + (curr-char (plist-get ctx :curr-char)) + (curr-indentation (plist-get ctx :curr-indentation)) + (curr-line (plist-get ctx :curr-line)) + (language (plist-get ctx :language)) + (prev-char (plist-get ctx :prev-char)) + (prev-indentation (plist-get ctx :prev-indentation)) + (prev-line (plist-get ctx :prev-line)) + (prev-pos (plist-get ctx :prev-pos)) + (reg-beg (plist-get ctx :reg-beg)) + (reg-col (plist-get ctx :reg-col)) + (token (plist-get ctx :token)) + (options (plist-get ctx :options)) + (chars (list curr-char prev-char)) + (tmp nil) + (is-js (member language '("javascript" "jsx" "ejs")))) + + (when (member language '("json" "typescript")) + (setq language "javascript")) + + ;;(message "%S" language) + ;;(message "curr-char=[%c] prev-char=[%c]\n%S" curr-char prev-char ctx) + ;;(message "options=%S" ctx) + + (cond + + ((or (bobp) (= (line-number-at-pos pos) 1)) + (when debug (message "I100(%S) first line" pos)) + (setq offset 0)) + + ;; #1073 + ((get-text-property pos 'invisible) + (when debug (message "I110(%S) invible" pos)) + (setq offset nil)) + + ((string= token "string") + (when debug (message "I120(%S) string" pos)) + (cond + ((web-mode-is-token-end pos) + (if (get-text-property pos 'block-side) + (web-mode-block-token-beginning) + (web-mode-part-token-beginning)) + (setq offset (current-indentation)) + ) + ((and web-mode-enable-sql-detection + (web-mode-block-token-starts-with (concat "[ \n]*" web-mode-sql-queries))) + (save-excursion + (let (col) + (web-mode-block-string-beginning) + (skip-chars-forward "[ \"'\n]") + (setq col (current-column)) + (goto-char pos) + (if (looking-at-p "\\(SELECT\\|INSERT\\|DELETE\\|UPDATE\\|FROM\\|LEFT\\|JOIN\\|WHERE\\|GROUP BY\\|LIMIT\\|HAVING\\|\)\\)") + (setq offset col) + (setq offset (+ col web-mode-sql-indent-offset))) + ) + ) ;save-excursion + ) + ((and is-js + (web-mode-is-ql-string pos "Relay\.QL")) + (setq offset (web-mode-relayql-indentation pos)) + ) + ((and is-js + (web-mode-is-ql-string pos "gql")) + (setq offset (web-mode-relayql-indentation pos "gql")) + ) + ((and is-js + (web-mode-is-ql-string pos "graphql")) + (setq offset (web-mode-relayql-indentation pos "graphql")) + ) + ((and is-js + (web-mode-is-css-string pos)) + (when debug (message "I127(%S) css string" pos)) + (setq offset (web-mode-token-css-indentation pos)) + ) + ((and is-js + (web-mode-is-html-string pos)) + (when debug (message "I128(%S) html string" pos)) + (setq offset (web-mode-token-html-indentation pos)) + ) + (t + (setq offset nil)) + ) ;cond + ) ;case string + + ((string= token "comment") + (when debug (message "I130(%S) comment" pos)) + (if (eq (get-text-property pos 'tag-type) 'comment) + (web-mode-tag-beginning) + (goto-char (car + (web-mode-property-boundaries + (if (eq (get-text-property pos 'part-token) 'comment) + 'part-token + 'block-token) + pos)))) + (setq offset (current-column)) + (cond + ((string= web-mode-engine "freemarker") + (setq offset (+ (current-indentation) 2))) + ((member (buffer-substring-no-properties (point) (+ (point) 2)) '("/*" "{*" "@*")) + (cond + ((eq ?\* curr-char) + (setq offset (+ offset 1))) + (t + (setq offset (+ offset 3))) + ) ;cond + ) + ((string= (buffer-substring-no-properties (point) (+ (point) 4)) "" curr-line) + (setq offset offset)) + ((string-match-p "^-" curr-line) + (setq offset (+ offset 3))) + (t + (setq offset (+ offset 5))) + ) ;cond + ) + ((and (string= web-mode-engine "django") (looking-back "{% comment %}" (point-min))) + (setq offset (- offset 12))) + ((and (string= web-mode-engine "mako") (looking-back "<%doc%>" (point-min))) + (setq offset (- offset 6))) + ((and (string= web-mode-engine "mason") (looking-back "<%doc%>" (point-min))) + (setq offset (- offset 6))) + ) ;cond + ) ;case comment + + ((and (string= web-mode-engine "mason") + (string-match-p "^%" curr-line)) + (when debug (message "I140(%S) mason" pos)) + (setq offset 0)) + + ((and (get-text-property pos 'block-beg) + (or (web-mode-block-is-close pos) + (web-mode-block-is-inside pos))) + (when debug (message "I150(%S) block-match" pos)) + (cond + ((not (web-mode-block-match)) + ) + ((and (string= web-mode-engine "closure") + (string-match-p "{\\(case\\|default\\)" curr-line)) + (setq offset (+ (current-indentation) web-mode-markup-indent-offset))) + (t + (setq offset (current-indentation)) + (if (and (string= web-mode-engine "blade") + (string-match-p "@break" curr-line)) + (setq offset (+ (current-indentation) offset))) + ) + ) ;cond + ) + + ((eq (get-text-property pos 'block-token) 'delimiter-end) + (when debug (message "I160(%S) block-beginning" pos)) + (when (web-mode-block-beginning) + (setq reg-col (current-indentation)) + (setq offset (current-column)))) + + ((or (and (get-text-property pos 'tag-beg) + (eq (get-text-property pos 'tag-type) 'end)) + (and (eq (get-text-property pos 'tag-type) 'comment) + (string-match-p "" (point)) + (web-mode-insert-text-at-pos "" (point)) + (web-mode-insert-text-at-pos "") + (search-backward " -->") + ) ;case html + ) ;cond + )) + +(defun web-mode-comment (pos) + (let (ctx language col sel beg end tmp block-side single-line-block pos-after content) + + (setq pos-after pos) + + (setq block-side (get-text-property pos 'block-side)) + (setq single-line-block (web-mode-is-single-line-block pos)) + + (cond + + ((and block-side (string= web-mode-engine "erb")) + (web-mode-comment-erb-block pos) + ) + + ((and block-side (string= web-mode-engine "artanis")) + (web-mode-comment-artanis-block pos) + ) + + ((and single-line-block block-side + (intern-soft (concat "web-mode-comment-" web-mode-engine "-block"))) + (funcall (intern (concat "web-mode-comment-" web-mode-engine "-block")) pos) + ) + + (t + (setq ctx (web-mode-point-context + (if mark-active (region-beginning) (line-beginning-position)))) + ;;(message "%S" ctx) + (setq language (plist-get ctx :language)) + (setq col (current-column)) + (cond + (mark-active + ;;(message "%S %S" (point) col) + ) + ((and (member language '("html" "xml")) + (get-text-property (progn (back-to-indentation) (point)) 'tag-beg)) + (web-mode-element-select)) + (t + (end-of-line) + (set-mark (line-beginning-position))) + ) ;cond + + (setq beg (region-beginning) + end (region-end)) + + (when (> (point) (mark)) + (exchange-point-and-mark)) + + (if (and (eq (char-before end) ?\n) + (not (eq (char-after end) ?\n))) + (setq end (1- end))) + + (setq sel (buffer-substring-no-properties beg end)) + + (cond + + ((member language '("html" "xml")) + (cond + ((and (= web-mode-comment-style 2) (string= web-mode-engine "django")) + (setq content (concat "{# " sel " #}"))) + ((and (= web-mode-comment-style 2) (member web-mode-engine '("ejs" "erb"))) + (setq content (concat "<%# " sel " %>"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "artanis")) + (setq content (concat "<%; " sel " %>"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "aspx")) + (setq content (concat "<%-- " sel " --%>"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "smarty")) + (setq content (concat "{* " sel " *}"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "expressionengine")) + (setq content (concat "{!-- " sel " --}"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "xoops")) + (setq content (concat "<{* " sel " *}>"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "hero")) + (setq content (concat "<%# " sel " %>"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "blade")) + (setq content (concat "{{-- " sel " --}}"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "ctemplate")) + (setq content (concat "{{!-- " sel " --}}"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "razor")) + (setq content (concat "@* " sel " *@"))) + (t + (setq content (concat "")) + (when (< (length sel) 1) + (search-backward " -->") + (setq pos-after nil)) + )) + ) ;case html + + ((member language '("php" "javascript" "typescript" "java" "jsx")) + (let (alt) + (setq alt (cdr (assoc language web-mode-comment-formats))) + ;;(message "language=%S alt=%S sel=%S col=%S" language alt sel col) + (cond + ((and alt (string= alt "//")) + (setq content (replace-regexp-in-string (concat "\n[ ]\\{" (number-to-string col) "\\}") "\n" sel)) + (setq content (replace-regexp-in-string (concat "\n") "\n// " content)) + (setq content (concat "// " content))) + ((get-text-property pos 'jsx-depth) + (setq content (concat "{/* " sel " */}"))) + (web-mode-comment-prefixing + (setq content (replace-regexp-in-string (concat "\n[ ]\\{" (number-to-string col) "\\}") "\n* " sel)) + (setq content (concat "/* " content " */"))) + (t + (setq content (concat "/* " sel " */"))) + ) ;cond + ) ;let + ) + + ((member language '("erb")) + (setq content (replace-regexp-in-string "^[ ]*" "#" sel))) + + ((member language '("asp")) + (setq content (replace-regexp-in-string "^[ ]*" "''" sel))) + + (t + (setq content (concat "/* " sel " */"))) + + ) ;cond + + (when content + (delete-region beg end) + (deactivate-mark) + (let (beg end) + (setq beg (point-at-bol)) + (insert content) + (setq end (point-at-eol)) + (indent-region beg end) + ) + ) ;when + + ) ;t + ) ;cond + + (when pos-after (goto-char pos-after)) + + )) + +(defun web-mode-comment-ejs-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "//" (+ beg 2)))) + +(defun web-mode-comment-erb-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "#" (+ beg 2)))) + +(defun web-mode-comment-artanis-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos ";" (+ beg 2)))) + +(defun web-mode-comment-django-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "#" end) + (web-mode-insert-text-at-pos "#" (1+ beg)))) + +(defun web-mode-comment-dust-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "!" end) + (web-mode-insert-text-at-pos "!" (1+ beg)))) + +(defun web-mode-comment-aspx-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "#" end) + (web-mode-insert-text-at-pos "#" (1+ beg)))) + +(defun web-mode-comment-jsp-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "--" (+ beg 2)))) + +(defun web-mode-comment-go-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "*/" (1- end)) + (web-mode-insert-text-at-pos "/*" (+ beg (if (web-mode-looking-at "{{" beg) 2 0))))) + +(defun web-mode-comment-php-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "*/" (- end 2)) + (web-mode-insert-text-at-pos "/*" (+ beg 1 (if (web-mode-looking-at "<\\?php" beg) 5 3))))) + +(defun web-mode-comment-svelte-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "!" end) + (web-mode-insert-text-at-pos "!" (1+ beg)))) + +(defun web-mode-comment-boundaries (&optional pos) + (interactive) + (unless pos (setq pos (point))) + (let ((beg pos) (end pos) prop) + (save-excursion + (goto-char pos) + (setq prop + (cond + ((eq (get-text-property pos 'block-token) 'comment) 'block-token) + ((eq (get-text-property pos 'tag-type) 'comment) 'tag-type) + ((eq (get-text-property pos 'part-token) 'comment) 'part-token) + (t nil) + )) + (if (null prop) + (setq beg nil + end nil) + (when (and (not (bobp)) + (eq (get-text-property pos prop) (get-text-property (1- pos) prop))) + (setq beg (or (previous-single-property-change pos prop) (point-min)))) + (when (and (not (eobp)) + (eq (get-text-property pos prop) (get-text-property (1+ pos) prop))) + (setq end (or (next-single-property-change pos prop) (point-max))))) + (message "beg(%S) end(%S) point-max(%S)" beg end (point-max)) + (when (and beg (string= (buffer-substring-no-properties beg (+ beg 2)) "//")) + (goto-char end) + (while (and (looking-at-p "\n[ ]*//") + (not (eobp))) + (search-forward "//") + (backward-char 2) + ;;(message "%S" (point)) + (setq end (next-single-property-change (point) prop)) + (goto-char end) + ;;(message "%S" (point)) + ) ;while + ) ;when + ;;(when end (setq end (1- end))) ;; #1021 + ) ;save-excursion + ;;(message "beg=%S end=%S" beg end) + (if (and beg end) (cons beg end) nil) + )) + +(defun web-mode-uncomment (pos) + (let ((beg pos) (end pos) (sub2 "") comment boundaries) + (save-excursion + (cond + ((and (get-text-property pos 'block-side) + (intern-soft (concat "web-mode-uncomment-" web-mode-engine "-block"))) + (funcall (intern (concat "web-mode-uncomment-" web-mode-engine "-block")) pos)) + ((and (setq boundaries (web-mode-comment-boundaries pos)) + (setq beg (car boundaries)) + (setq end (1+ (cdr boundaries))) + (> (- end beg) 4)) + (message "%S" boundaries) + ;;(message "beg(%S) end(%S)" beg end) + (setq comment (buffer-substring-no-properties beg end)) + (setq sub2 (substring comment 0 2)) + (cond + ((member sub2 '("$\\)" "" comment))) + ((string= sub2 "{#") + (setq comment (replace-regexp-in-string "\\(^{#[ ]?\\|[ ]?#}$\\)" "" comment))) + ((string= sub2 "{/") ;jsx comments + (setq comment (replace-regexp-in-string "\\(^{/\\*[ ]?\\|[ ]?\\*/}$\\)" "" comment))) + ((string= sub2 "/*") + ;;(message "%S" comment) + ;;(setq comment (replace-regexp-in-string "\\(\\*/\\|^/\\*[ ]?\\|^[ \t]*\\*\\)" "" comment)) + (setq comment (replace-regexp-in-string "\\([ ]?\\*/$\\|^/\\*[ ]?\\)" "" comment)) + (setq comment (replace-regexp-in-string "\\(^[ \t]*\\*\\)" "" comment)) + ;;(message "%S" comment) + ) + ((string= sub2 "//") + (setq comment (replace-regexp-in-string "^ *//" "" comment))) + ) ;cond + (delete-region beg end) + (web-mode-insert-and-indent comment) + (goto-char beg) + ) + ) ;cond + (indent-according-to-mode) + ))) + +(defun web-mode-uncomment-erb-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (cond + ((string= (buffer-substring-no-properties beg (+ beg 4)) "<%#=") + (web-mode-remove-text-at-pos 1 (+ beg 2))) + ((string-match-p "<[%[:alpha:]]" (buffer-substring-no-properties (+ beg 2) (- end 2))) + (web-mode-remove-text-at-pos 2 (1- end)) + (web-mode-remove-text-at-pos 3 beg)) + (t + (web-mode-remove-text-at-pos 1 (+ beg 2))) + ) ;cond + ) + ) + +(defun web-mode-uncomment-artanis-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (cond + ((string= (buffer-substring-no-properties beg (+ beg 4)) "<%;=") + (web-mode-remove-text-at-pos 1 (+ beg 2))) + ((string-match-p "<[%[:alpha:]]" (buffer-substring-no-properties (+ beg 2) (- end 2))) + (web-mode-remove-text-at-pos 2 (1- end)) + (web-mode-remove-text-at-pos 3 beg)) + (t + (web-mode-remove-text-at-pos 1 (+ beg 2))) + ) ;cond + ) + ) + +(defun web-mode-uncomment-ejs-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (+ beg 2)))) + +(defun web-mode-uncomment-django-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (cond + ((web-mode-looking-at-p "{#[{%]" beg) + (web-mode-remove-text-at-pos 1 (1- end)) + (web-mode-remove-text-at-pos 1 (1+ beg)) + ) + (t + (web-mode-remove-text-at-pos 2 (1- end)) + (web-mode-remove-text-at-pos 2 beg)) + ) ;cond + )) + +(defun web-mode-uncomment-ctemplate-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 5 (- end 4)) + (web-mode-remove-text-at-pos 5 beg))) + +(defun web-mode-uncomment-dust-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (1- end)) + (web-mode-remove-text-at-pos 1 (1+ beg)))) + +(defun web-mode-uncomment-aspx-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (1- end)) + (web-mode-remove-text-at-pos 1 (1+ beg)))) + +(defun web-mode-uncomment-jsp-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 2 (+ beg 2)))) + +(defun web-mode-uncomment-go-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 2 (+ beg 2)) + (web-mode-remove-text-at-pos 2 (- end 5)))) + +(defun web-mode-uncomment-svelte-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (1- end)) + (web-mode-remove-text-at-pos 1 (1+ beg)))) + +(defun web-mode-snippet-names () + (let (codes) + (dolist (snippet web-mode-snippets) + (add-to-list 'codes (car snippet) t)) + codes)) + +(defun web-mode-snippet-insert (code) + "Insert a snippet." + (interactive + (list (completing-read "Snippet: " (web-mode-snippet-names)))) + (let (beg + (continue t) + (counter 0) + end + sel + snippet + (l (length web-mode-snippets)) + pos) + (when mark-active + (setq sel (web-mode-trim (buffer-substring-no-properties + (region-beginning) (region-end)))) + (delete-region (region-beginning) (region-end))) + (while (and continue (< counter l)) + (setq snippet (nth counter web-mode-snippets)) + (when (string= (car snippet) code) + (setq continue nil)) + (setq counter (1+ counter))) + (when snippet + (setq snippet (cdr snippet)) + (setq beg (point-at-bol)) + (insert snippet) + (setq pos (point) + end (point)) + (cond + ((string-match-p "¦" snippet) + (search-backward "¦") + (delete-char 1) + (setq pos (point) + end (1- end))) + ((string-match-p "|" snippet) + (search-backward "|") + (delete-char 1) + (setq pos (point) + end (1- end))) + ) ;cond + (when sel + (insert sel) + (setq pos (point) + end (+ end (length sel)))) + (goto-char end) + (setq end (point-at-eol)) + (unless sel (goto-char pos)) + (indent-region beg end)) + )) + +(defun web-mode-looking-at (regexp pos) + (save-excursion + (goto-char pos) + (looking-at regexp))) + +(defun web-mode-looking-at-p (regexp pos) + (save-excursion + (goto-char pos) + (looking-at-p regexp))) + +(defun web-mode-looking-back (regexp pos &optional limit greedy) + (save-excursion + (goto-char pos) + (if limit + (looking-back regexp limit greedy) + (looking-back regexp (point-min))))) + +(defun web-mode-insert-text-at-pos (text pos) + (let ((mem web-mode-enable-auto-pairing)) + (setq web-mode-enable-auto-pairing nil) + (save-excursion + (goto-char pos) + (insert text) + (setq web-mode-enable-auto-pairing mem) + ))) + +(defun web-mode-remove-text-at-pos (n &optional pos) + (unless pos (setq pos (point))) + (delete-region pos (+ pos n))) + +(defun web-mode-insert-and-indent (text) + (let (beg end) + (setq beg (point-at-bol)) + (insert text) + (setq end (point-at-eol)) + (indent-region beg end) + )) + +(defun web-mode-column-at-pos (pos) + (save-excursion + (goto-char pos) + (current-column))) + +(defun web-mode-indentation-at-pos (pos) + (save-excursion + (goto-char pos) + (current-indentation))) + +(defun web-mode-navigate (&optional pos) + "Move point to the matching opening/closing tag/block." + (interactive) + (unless pos (setq pos (point))) + (let (init) + (goto-char pos) + (setq init (point)) + (when (> (current-indentation) (current-column)) + (back-to-indentation)) + (setq pos (point)) + (cond + ((and (get-text-property pos 'block-side) + (web-mode-block-beginning) + (web-mode-block-controls-get (point))) + (web-mode-block-match)) + ((member (get-text-property pos 'tag-type) '(start end)) + (web-mode-tag-beginning) + (web-mode-tag-match)) + (t + (goto-char init)) + ) + )) + +(defun web-mode-block-match (&optional pos) + (unless pos (setq pos (point))) + (let (pos-ori controls control (counter 1) type (continue t) pair) + (setq pos-ori pos) + (goto-char pos) + (setq controls (web-mode-block-controls-get pos)) + ;;(message "controls=%S" controls) + (cond + (controls + (setq pair (car controls)) + (setq control (cdr pair)) + (setq type (car pair)) + (when (eq type 'inside) (setq type 'close)) + (while continue + (cond + ((and (> pos-ori 1) (bobp)) + (setq continue nil)) + ((or (and (eq type 'open) (not (web-mode-block-next))) + (and (eq type 'close) (not (web-mode-block-previous)))) + (setq continue nil) + ) + ((null (setq controls (web-mode-block-controls-get (point)))) + ) + (t + ;;TODO : est il nécessaire de faire un reverse sur controls si on doit matcher backward + (dolist (pair controls) + (cond + ((not (string= (cdr pair) control)) + ) + ((eq (car pair) 'inside) + ) + ((eq (car pair) type) + (setq counter (1+ counter))) + (t + (setq counter (1- counter))) + ) + ) ;dolist + (when (= counter 0) + (setq continue nil)) + ) ;t + ) ;cond + ) ;while + (if (= counter 0) (point) nil) + ) ;controls + (t + (goto-char pos-ori) + nil + ) ;controls = nul + ) ;conf + )) + +(defun web-mode-tag-match (&optional pos) + "Move point to the matching opening/closing tag." + (interactive) + (unless pos (setq pos (point))) + (let (regexp name) + (cond + ((eq (get-text-property pos 'tag-type) 'void) + (web-mode-tag-beginning)) + ((and (eq (get-text-property pos 'tag-type) 'comment) + (web-mode-looking-at-p " %S %S" pos (get-text-property pos 'jsx-depth)) + ) + ((and blockside + (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((and (not blockside) + (member (get-text-property pos 'part-token) '(string comment)) + (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))) + (setq pos (web-mode-part-token-beginning-position pos))) + ((and (not blockside) + (get-text-property pos 'block-side)) + (when (setq pos (web-mode-block-beginning-position pos)) + (setq pos (1- pos)))) + ((member char '(?\) ?\] ?\})) + (setq pos (web-mode-part-opening-paren-position pos reg-beg)) + (setq pos (1- pos))) + ((and (eq char ?\=) + (web-mode-looking-back "[<>!=]+" pos reg-beg t)) + (setq pos (- pos 1 (length (match-string-no-properties 0))))) + ((member char '(?\( ?\{ ?\[ ?\= ?\< ?\>)) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq continue nil + pos (+ pos (length (match-string-no-properties 0))))) + + ((web-mode-looking-at "\\(return\\)[ \n]" pos) + (setq continue nil + pos (+ pos (length (match-string-no-properties 0))))) + ((and (eq char ?\:) + (web-mode-looking-back "[{,][ \t\n]*[[:alnum:]_]+[ ]*" pos)) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq continue nil + pos (+ pos (length (match-string-no-properties 0))))) + (t + (setq pos (web-mode-rsb-position pos regexp reg-beg)) + (when (not pos) + (cond + (is-jsx + (when (web-mode-looking-at "[ \n]*" reg-beg) + (setq pos (+ reg-beg (length (match-string-no-properties 0))))) + (setq continue nil)) + (t + (message "javascript-statement-beginning-position ** search failure **") + (setq continue nil + pos reg-beg)) + ) ;cond + ) + ) ;t + ) ;cond + ) ;while + ;;(message "%S -------" pos) + pos)) + +(defun web-mode-javascript-args-beginning-position (pos &optional reg-beg) + (unless pos (setq pos (point))) + (setq pos (1- pos)) + (let ((char nil) + (blockside (get-text-property pos 'block-side)) + (i 0) + (continue (not (null pos)))) + (unless reg-beg + (if blockside + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos))) + ) + (while continue + (setq char (char-after pos)) + ;;(message "pos(%S) char(%c)" pos char) + (cond + ((> (setq i (1+ i)) 20000) + (message "javascript-args-beginning-position ** warning (%S) **" pos) + (setq continue nil + pos nil)) + ((null pos) + (message "javascript-args-beginning-position ** invalid pos **") + (setq continue nil)) + ((< pos reg-beg) + (message "javascript-args-beginning-position ** failure(position) **") + (setq continue nil + pos reg-beg)) + ((and blockside + (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((and (not blockside) + (member (get-text-property pos 'part-token) '(string comment)) + (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))) + (setq pos (web-mode-part-token-beginning-position pos))) + ((and (not blockside) + (get-text-property pos 'block-side)) + (when (setq pos (web-mode-block-beginning-position pos)) + (setq pos (1- pos))) + ) + ((member char '(?\) ?\] ?\})) + (when (setq pos (web-mode-part-opening-paren-position pos reg-beg)) + (setq pos (1- pos)))) + ((member char '(?\( ?\[ ?\{)) + (web-mode-looking-at ".[ ]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))) + continue nil) + ) + ((web-mode-looking-at "\\(var\\|let\\|return\\|const\\)[ \n]" pos) + (setq pos (+ pos (length (match-string-no-properties 0))) + continue nil)) + (t + (setq pos (web-mode-rsb-position pos "[\]\[}{)(]\\|\\(var\\|let\\|return\\|const\\)" reg-beg)) + (when (not pos) + (message "javascript-args-beginning-position ** search failure **") + (setq continue nil + pos reg-beg))) + ) ;cond + ) ;while + ;;(message "=%S" pos) + pos)) + +(defun web-mode-javascript-calls-beginning-position (pos &optional reg-beg) + (unless pos (setq pos (point))) + ;;(message "pos=%S" pos) + (let ((char nil) + (dot-pos nil) + (blockside (get-text-property pos 'block-side)) + (i 0) + (continue (not (null pos)))) + (unless reg-beg + (setq reg-beg (if blockside + (web-mode-block-beginning-position pos) + (web-mode-part-beginning-position pos)))) + (while continue + (setq char (char-after pos)) + ;;(message "%S| %S=%c" reg-beg pos char) + (cond + ((> (setq i (1+ i)) 20000) + (message "javascript-calls-beginning-position ** warning (%S) **" pos) + (setq continue nil + pos nil)) + ((null pos) + (message "javascript-calls-beginning-position ** invalid pos **") + (setq continue nil)) + ((< pos reg-beg) + (setq continue nil + pos reg-beg)) + ((and blockside + (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((and (not blockside) + (member (get-text-property pos 'part-token) '(string comment)) + (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))) + (setq pos (web-mode-part-token-beginning-position pos))) + ((and (not blockside) + (get-text-property pos 'block-side)) + (when (setq pos (web-mode-block-beginning-position pos)) + (setq pos (1- pos)))) + ((and (member char '(?\.)) (> i 1)) + (setq dot-pos pos + pos (1- pos))) + ((member char '(?\) ?\])) + (when (setq pos (web-mode-part-opening-paren-position pos reg-beg)) + (setq pos (1- pos))) + ) + ((member char '(?\( ?\{ ?\} ?\[ ?\= ?\? ?\: ?\; ?\, ?\& ?\| ?\>)) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))) + continue nil)) + ((web-mode-looking-at "\\(return\\|else\\|const\\)[ \n]" pos) + (setq pos (+ pos (length (match-string-no-properties 0))) + continue nil)) + (t + (setq pos (web-mode-rsb-position pos "[\]\[}{)(=?:;,&|>.]\\|\\(return\\|else\\|const\\)" reg-beg)) + (when (not pos) + (message "javascript-calls-beginning-position ** search failure **") + (setq pos reg-beg + continue nil)) + ) ;t + ) ;cond + ) ;while + ;;(message "pos=%S dot-pos=%S" pos dot-pos) + (if (null pos) pos (cons pos dot-pos)) + )) + +(defun web-mode-part-token-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'part-token)) + nil) + ((or (= pos (point-min)) + (and (> pos (point-min)) + (not (get-text-property (1- pos) 'part-token)))) + pos) + (t + (setq pos (previous-single-property-change pos 'part-token)) + (if (and pos (> pos (point-min))) pos (point-min))) + )) + +(defun web-mode-part-token-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'part-token)) + nil) + ((or (= pos (point-max)) + (not (get-text-property (1+ pos) 'part-token))) + pos) + (t + (1- (next-single-property-change pos 'part-token))) + )) + +(defun web-mode-block-token-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'block-token)) + nil) + ((or (= pos (point-min)) + (and (> pos (point-min)) + (not (get-text-property (1- pos) 'block-token)))) + pos) + (t + (setq pos (previous-single-property-change pos 'block-token)) + (if (and pos (> pos (point-min))) pos (point-min))) + )) + +(defun web-mode-block-token-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'block-token)) + nil) + ((or (= pos (point-max)) + (not (get-text-property (1+ pos) 'block-token))) + pos) + (t + (1- (next-single-property-change pos 'block-token))) + )) + +(defun web-mode-block-code-end-position (&optional pos) + (unless pos (setq pos (point))) + (setq pos (web-mode-block-end-position pos)) + (cond + ((not pos) + nil) + ((and (eq (get-text-property pos 'block-token) 'delimiter-end) + (eq (get-text-property (1- pos) 'block-token) 'delimiter-end)) + (previous-single-property-change pos 'block-token)) + ((= pos (1- (point-max))) ;; TODO: comparer plutot avec line-end-position + (point-max)) + (t + pos) + )) + +(defun web-mode-block-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((get-text-property pos 'block-end) + pos) + ((get-text-property pos 'block-side) + (or (next-single-property-change pos 'block-end) + (point-max))) + (t + nil) + )) + +(defun web-mode-block-previous-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((= pos (point-min)) + (setq pos nil)) + ((get-text-property pos 'block-side) + (setq pos (web-mode-block-beginning-position pos)) + (cond + ((or (null pos) (= pos (point-min))) + (setq pos nil) + ) + ((and (setq pos (previous-single-property-change pos 'block-beg)) + (> pos (point-min))) + (setq pos (1- pos)) + ) + ) + ) ;block-side + ((get-text-property (1- pos) 'block-side) + (setq pos (web-mode-block-beginning-position (1- pos))) + ) + (t + (setq pos (previous-single-property-change pos 'block-side)) + (cond + ((and (null pos) (get-text-property (point-min) 'block-beg)) + (setq pos (point-min))) + ((and pos (> pos (point-min))) + (setq pos (web-mode-block-beginning-position (1- pos)))) + ) + ) + ) ;conf + pos) + +(defun web-mode-block-next-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-max))) + (cond + ((and (get-text-property pos 'block-side) + (setq pos (web-mode-block-end-position pos)) + (< pos (point-max)) + (setq pos (1+ pos))) + (unless (get-text-property pos 'block-beg) + (setq pos (next-single-property-change pos 'block-side))) + ) + (t + (setq pos (next-single-property-change pos 'block-side))) + ) ;cond + (if (and pos (<= pos limit)) pos nil)) + +(defun web-mode-is-css-string (pos) + (let (beg) + (cond + ((and (setq beg (web-mode-part-token-beginning-position pos)) + (web-mode-looking-at-p "`" beg) + (web-mode-looking-back "\\(styled[[:alnum:].]+\\|css\\)" beg)) + beg) + (t + nil) + ) ;cond + )) + +;; Relay.QL , gql, graphql +(defun web-mode-is-ql-string (pos prefix-regexp) + (let (beg) + (cond + ((and (setq beg (web-mode-part-token-beginning-position pos)) + (web-mode-looking-back prefix-regexp beg)) + beg) + (t + nil) + ) ;cond + )) + +(defun web-mode-is-html-string (pos) + (let (beg) + (cond + ((and (setq beg (web-mode-part-token-beginning-position pos)) + (web-mode-looking-at-p "`[ \t\n]*<[a-zA-Z]" beg) + (web-mode-looking-back "\\(template\\|html\\)\\([ ]*[=:][ ]*\\)?" beg)) + beg) + (t + nil) + ) ;cond + )) + +;;---- EXCURSION --------------------------------------------------------------- + +(defun web-mode-backward-sexp (n) + (interactive "p") + (if (< n 0) (web-mode-forward-sexp (- n)) + (let (pos) + (dotimes (_ n) + (skip-chars-backward "[:space:]") + (setq pos (point)) + (cond + ((bobp) nil) + ((get-text-property (1- pos) 'block-end) + (backward-char 1) + (web-mode-block-beginning)) + ((get-text-property (1- pos) 'block-token) + (backward-char 1) + (web-mode-block-token-beginning)) + ((get-text-property (1- pos) 'part-token) + (backward-char 1) + (web-mode-part-token-beginning)) + ((get-text-property (1- pos) 'tag-end) + (backward-char 1) + (web-mode-element-beginning)) + ((get-text-property (1- pos) 'tag-attr) + (backward-char 1) + (web-mode-attribute-beginning)) + ((get-text-property (1- pos) 'tag-type) + (backward-char 1) + (web-mode-tag-beginning)) + ((get-text-property (1- pos) 'jsx-end) + (backward-char 1) + (web-mode-jsx-beginning)) + (t + (let ((forward-sexp-function nil)) + (backward-sexp)) + ) ;case t + ) ;cond + ) ;dotimes + ))) ;let if defun + +(defun web-mode-forward-sexp (n) + (interactive "p") + (if (< n 0) (web-mode-backward-sexp (- n)) + (let (pos) + (dotimes (_ n) + (skip-chars-forward "[:space:]") + (setq pos (point)) + (cond + ((eobp) nil) + ((get-text-property pos 'block-beg) + (web-mode-block-end)) + ((get-text-property pos 'block-token) + (web-mode-block-token-end)) + ((get-text-property pos 'part-token) + (web-mode-part-token-end)) + ((get-text-property pos 'tag-beg) + (web-mode-element-end)) + ((get-text-property pos 'tag-attr) + (web-mode-attribute-end)) + ((get-text-property pos 'tag-type) + (web-mode-tag-end)) + ((get-text-property pos 'jsx-beg) + (web-mode-jsx-end)) + (t + (let ((forward-sexp-function nil)) + (forward-sexp)) + ) ;case t + ) ;cond + ) ;dotimes + ))) ;let if defun + +(defun web-mode-comment-beginning () + "Fetch current comment beg." + (interactive) + (web-mode-go (web-mode-comment-beginning-position (point)))) + +(defun web-mode-comment-end () + "Fetch current comment end." + (interactive) + (web-mode-go (web-mode-comment-end-position (point)) 1)) + +(defun web-mode-tag-beginning () + "Fetch current html tag beg." + (interactive) + (web-mode-go (web-mode-tag-beginning-position (point)))) + +(defun web-mode-tag-end () + "Fetch current html tag end." + (interactive) + (web-mode-go (web-mode-tag-end-position (point)) 1)) + +(defun web-mode-tag-previous () + "Fetch previous tag." + (interactive) + (web-mode-go (web-mode-tag-previous-position (point)))) + +(defun web-mode-tag-next () + "Fetch next tag. Might be html comment or server tag (e.g. jsp)." + (interactive) + (web-mode-go (web-mode-tag-next-position (point)))) + +(defun web-mode-attribute-beginning () + "Fetch html attribute beginning." + (interactive) + (web-mode-go (web-mode-attribute-beginning-position (point)))) + +(defun web-mode-attribute-end () + "Fetch html attribute end." + (interactive) + (web-mode-go (web-mode-attribute-end-position (point)) 1)) + +(defun web-mode-attribute-next (&optional arg) + "Fetch next attribute." + (interactive "p") + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-attribute-next-position (point)))) + ((< arg 1) (web-mode-element-previous (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-attribute-next-position (point))) + ) + ) + ) + ) + +(defun web-mode-attribute-previous (&optional arg) + "Fetch previous attribute." + (interactive "p") + (unless arg (setq arg 1)) + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-attribute-previous-position (point)))) + ((< arg 1) (web-mode-element-next (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-attribute-previous-position (point))) + ) + ) + ) + ) + +(defun web-mode-element-previous (&optional arg) + "Fetch previous element." + (interactive "p") + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-element-previous-position (point)))) + ((< arg 1) (web-mode-element-next (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-element-previous-position (point))) + ) ;while + ) ;t + ) ;cond + ) + +(defun web-mode-element-next (&optional arg) + "Fetch next element." + (interactive "p") + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-element-next-position (point)))) + ((< arg 1) (web-mode-element-previous (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-element-next-position (point))) + ) ;while + ) ;t + ) ;cond + ) + +(defun web-mode-element-sibling-next () + "Fetch next sibling element." + (interactive) + (let ((pos (point))) + (save-excursion + (cond + ((not (get-text-property pos 'tag-type)) + (if (and (web-mode-element-parent) + (web-mode-tag-match) + (web-mode-tag-next) + (member (get-text-property (point) 'tag-type) '(start void comment))) + (setq pos (point)) + (setq pos nil)) + ) + ((member (get-text-property pos 'tag-type) '(start void)) + (if (and (web-mode-tag-match) + (web-mode-tag-next) + (member (get-text-property (point) 'tag-type) '(start void comment))) + (setq pos (point)) + (setq pos nil)) + ) + ((and (web-mode-tag-next) + (member (get-text-property (point) 'tag-type) '(start void comment))) + (setq pos (point))) + (t + (setq pos nil)) + ) ;cond + ) ;save-excursion + (web-mode-go pos))) + +(defun web-mode-element-sibling-previous () + "Fetch previous sibling element." + (interactive) + (let ((pos (point))) + (save-excursion + (cond + ((not (get-text-property pos 'tag-type)) + (if (and (web-mode-element-parent) + (web-mode-tag-previous) + (web-mode-element-beginning)) + (setq pos (point)) + (setq pos nil)) + ) + ((eq (get-text-property pos 'tag-type) 'start) + (if (and (web-mode-tag-beginning) + (web-mode-tag-previous) + (web-mode-element-beginning)) + (setq pos (point)) + (setq pos nil)) + ) + ((and (web-mode-element-beginning) + (web-mode-tag-previous) + (web-mode-element-beginning)) + (setq pos (point))) + (t + (setq pos nil)) + ) ;cond + ) ;save-excursion + (web-mode-go pos))) + +(defun web-mode-element-beginning () + "Move to beginning of element." + (interactive) + (web-mode-go (web-mode-element-beginning-position (point)))) + +(defun web-mode-element-end () + "Move to end of element." + (interactive) + (web-mode-go (web-mode-element-end-position (point)) 1)) + +(defun web-mode-element-parent () + "Fetch parent element." + (interactive) + (web-mode-go (web-mode-element-parent-position (point)))) + +(defun web-mode-element-child () + "Fetch child element." + (interactive) + (web-mode-go (web-mode-element-child-position (point)))) + +(defun web-mode-dom-traverse () + "Traverse html dom tree." + (interactive) + (cond + ((web-mode-element-child) + ) + ((web-mode-element-sibling-next) + ) + ((and (web-mode-element-parent) + (not (web-mode-element-sibling-next))) + (goto-char (point-min))) + (t + (goto-char (point-min))) + ) ;cond + ) + +(defun web-mode-closing-paren (limit) + (let ((pos (web-mode-closing-paren-position (point) limit))) + (if (or (null pos) (> pos limit)) + nil + (goto-char pos) + pos) + )) + +(defun web-mode-part-next () + "Move point to the beginning of the next part." + (interactive) + (web-mode-go (web-mode-part-next-position (point)))) + +(defun web-mode-part-beginning () + "Move point to the beginning of the current part." + (interactive) + (web-mode-go (web-mode-part-beginning-position (point)))) + +(defun web-mode-part-end () + "Move point to the end of the current part." + (interactive) + (web-mode-go (web-mode-part-end-position (point)) 1)) + +(defun web-mode-block-previous () + "Move point to the beginning of the previous block." + (interactive) + (web-mode-go (web-mode-block-previous-position (point)))) + +(defun web-mode-block-next () + "Move point to the beginning of the next block." + (interactive) + (web-mode-go (web-mode-block-next-position (point)))) + +(defun web-mode-block-beginning () + "Move point to the beginning of the current block." + (interactive) + (web-mode-go (web-mode-block-beginning-position (point)))) + +(defun web-mode-block-end () + "Move point to the end of the current block." + (interactive) + (web-mode-go (web-mode-block-end-position (point)) 1)) + +(defun web-mode-block-token-beginning () + (web-mode-go (web-mode-block-token-beginning-position (point)))) + +(defun web-mode-block-token-end () + (web-mode-go (web-mode-block-token-end-position (point)) 1)) + +(defun web-mode-part-token-beginning () + (web-mode-go (web-mode-part-token-beginning-position (point)))) + +(defun web-mode-part-token-end () + (web-mode-go (web-mode-part-token-end-position (point)) 1)) + +(defun web-mode-block-opening-paren (limit) + (web-mode-go (web-mode-block-opening-paren-position (point) limit))) + +(defun web-mode-block-string-beginning (&optional pos block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-string-beginning-position pos block-beg))) + +(defun web-mode-block-statement-beginning (pos block-beg is-ternary) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-statement-beginning-position pos block-beg is-ternary))) + +(defun web-mode-block-args-beginning (&optional pos block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-args-beginning-position pos block-beg))) + +(defun web-mode-block-calls-beginning (&optional pos block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-calls-beginning-position pos block-beg))) + +(defun web-mode-javascript-string-beginning (&optional pos reg-beg) + (unless pos (setq pos (point))) + (unless reg-beg + (if (get-text-property pos 'block-side) + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos)))) + (web-mode-go (web-mode-javascript-string-beginning-position pos reg-beg))) + +(defun web-mode-javascript-statement-beginning (pos reg-beg is-ternary) + (unless pos (setq pos (point))) + (unless reg-beg + (if (get-text-property pos 'block-side) + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos)))) + (web-mode-go (web-mode-javascript-statement-beginning-position pos reg-beg is-ternary))) + +(defun web-mode-javascript-args-beginning (&optional pos reg-beg) + (unless pos (setq pos (point))) + (unless reg-beg + (setq reg-beg (if (get-text-property pos 'block-side) + (web-mode-block-beginning-position pos) + (web-mode-part-beginning-position pos)))) + ;;(message "reg-beg%S" reg-beg) + (web-mode-go (web-mode-javascript-args-beginning-position pos reg-beg))) + +(defun web-mode-javascript-calls-beginning (&optional pos reg-beg) + (unless pos (setq pos (point))) + (unless reg-beg + (if (get-text-property pos 'block-side) + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos)))) + (let (pair) + (setq pair (web-mode-javascript-calls-beginning-position pos reg-beg)) + (when pair (web-mode-go (car pair))) + )) + +(defun web-mode-go (pos &optional offset) + (unless offset (setq offset 0)) + (when pos + (cond + ((and (> offset 0) (<= (+ pos offset) (point-max))) + (setq pos (+ pos offset))) + ((and (< offset 0) (>= (+ pos offset) (point-min))) + (setq pos (+ pos offset))) + ) ;cond + (goto-char pos)) + pos) + +;;---- SEARCH ------------------------------------------------------------------ + +(defun web-mode-rsf-balanced (regexp-open regexp-close &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) + (level 1) + (pos (point)) + ret + (regexp (concat regexp-open "\\|" regexp-close))) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + (cond + ((null ret) + (setq continue nil) + ) + (t + (if (string-match-p regexp-open (match-string-no-properties 0)) + (setq level (1+ level)) + (setq level (1- level))) + (when (< level 1) + (setq continue nil) + ) + ) ;t + ) ;cond + ) ;while + (when (not (= level 0)) (goto-char pos)) + ret)) + +(defun web-mode-block-sb (expr &optional limit noerror) + (unless limit (setq limit (web-mode-block-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-backward expr limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-block-sf (expr &optional limit noerror) + (unless limit (setq limit (web-mode-block-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-block-rsb (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-block-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-block-rsf (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-block-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-sb (expr &optional limit noerror) + (unless limit (setq limit (web-mode-part-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-backward expr limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-sf (expr &optional limit noerror) + (unless limit (setq limit (web-mode-part-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-rsb (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-rsf (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit t)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-javascript-rsb (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side)) + (not (get-text-property (point) 'jsx-depth))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-javascript-rsf (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit t)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side)) + (not (get-text-property (point) 'jsx-depth))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-dom-sf (expr &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (if (or (null ret) + (not (get-text-property (- (point) (length expr)) 'block-side))) + (setq continue nil)) + ) + ret)) + +(defun web-mode-dom-rsf (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) (ret nil)) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + ;; (message "ret=%S point=%S limit=%S i=%S" ret (point) limit 0) + (cond + ((null ret) + (setq continue nil)) + ((or (get-text-property (match-beginning 0) 'block-side) + (get-text-property (match-beginning 0) 'part-token)) + ) + (t + (setq continue nil)) + ) ;cond + ) ;while + ret)) + +(defun web-mode-rsb-position (pos regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (save-excursion + (goto-char pos) + (if (re-search-backward regexp limit noerror) (point) nil) + )) + +(defun web-mode-rsb (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil))) + ret)) + +(defun web-mode-rsf (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil)) + ) + ret)) + +(defun web-mode-sb (expr &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-backward expr limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil))) + ret)) + +(defun web-mode-sf (expr &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil))) + ret)) + +(defun web-mode-content-rsf (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret beg end) + (while continue + (setq ret (re-search-forward regexp limit noerror) + beg (if (null ret) (point) (match-beginning 0)) + end (if (null ret) (point) (1- (match-end 0)))) + (if (or (null ret) + (and (web-mode-is-content beg) + (web-mode-is-content end))) + (setq continue nil))) + ret)) + +;;---- ADVICES ----------------------------------------------------------------- + +(defadvice ac-start (before web-mode-set-up-ac-sources activate) + "Set `ac-sources' based on current language before running auto-complete." + (when (equal major-mode 'web-mode) + ;; set ignore each time to nil. User has to implement a hook to change it + ;; for each completion + (setq web-mode-ignore-ac-start-advice nil) + (run-hooks 'web-mode-before-auto-complete-hooks) + (unless web-mode-ignore-ac-start-advice + (when web-mode-ac-sources-alist + (let ((new-web-mode-ac-sources + (assoc (web-mode-language-at-pos) + web-mode-ac-sources-alist))) + (setq ac-sources (cdr new-web-mode-ac-sources))))))) + +;;---- MINOR MODE ADDONS ------------------------------------------------------- + +(defun web-mode-yasnippet-exit-hook () + "Yasnippet exit hook" + (when (and (boundp 'yas-snippet-beg) (boundp 'yas-snippet-end)) + (indent-region yas-snippet-beg yas-snippet-end))) + +(defun web-mode-imenu-index () + (interactive) + "Returns imenu items." + (let (toc-index + line) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (setq line (buffer-substring-no-properties + (line-beginning-position) + (line-end-position))) + (let (found + (i 0) + item + regexp + type + type-idx + content + content-idx + content-regexp + close-tag-regexp + concat-str + jumpto + str) + (while (and (not found ) (< i (length web-mode-imenu-regexp-list))) + (setq item (nth i web-mode-imenu-regexp-list)) + (setq regexp (nth 0 item)) + (setq type-idx (nth 1 item)) + (setq content-idx (nth 2 item)) + (setq concat-str (nth 3 item)) + (when (not (numberp content-idx)) + (setq content-regexp (nth 2 item) + close-tag-regexp (nth 4 item) + content-idx nil)) + + (when (string-match regexp line) + + (cond + (content-idx + (setq type (match-string type-idx line)) + (setq content (match-string content-idx line)) + (setq str (concat type concat-str content)) + (setq jumpto (line-beginning-position))) + (t + (let (limit) + (setq type (match-string type-idx line)) + (goto-char (line-beginning-position)) + (save-excursion + (setq limit (re-search-forward close-tag-regexp (point-max) t))) + + (when limit + (when (re-search-forward content-regexp limit t) + (setq content (match-string 1)) + (setq str (concat type concat-str content)) + (setq jumpto (line-beginning-position)) + ) + ))) + ) + (when str (setq toc-index + (cons (cons str jumpto) + toc-index) + ) + (setq found t)) + ) + (setq i (1+ i)))) + (forward-line) + (goto-char (line-end-position)) ;; make sure we are at eobp + )) + (nreverse toc-index))) + +;;---- UNIT TESTING ------------------------------------------------------------ + +(defun web-mode-test () + "Executes web-mode unit tests. See `web-mode-tests-directory'." + (interactive) + (let (files ret regexp) + (setq regexp "^[[:alnum:]][[:alnum:]._]+\\'") + (setq files (directory-files web-mode-tests-directory t regexp)) + (dolist (file files) + (cond + ((eq (string-to-char (file-name-nondirectory file)) ?\_) + (delete-file file)) + (t + (setq ret (web-mode-test-process file))) + ) ;cond + ) ;dolist + )) + +(defun web-mode-test-process (file) + (with-temp-buffer + (let (out sig1 sig2 success err) + (setq-default indent-tabs-mode nil) + (if (string-match-p "sql" file) + (setq web-mode-enable-sql-detection t) + (setq web-mode-enable-sql-detection nil)) + (insert-file-contents file) + (set-visited-file-name file) + (web-mode) + (setq sig1 (md5 (current-buffer))) + (delete-horizontal-space) + (while (not (eobp)) + (forward-line) + (delete-horizontal-space) + (end-of-line)) + (web-mode-buffer-indent) + (setq sig2 (md5 (current-buffer))) + (setq success (string= sig1 sig2)) + (setq out (concat (if success "ok" "ko") " : " (file-name-nondirectory file) "\n")) + (princ out) + (setq err (concat (file-name-directory file) "_err." (file-name-nondirectory file))) + (if success + (when (file-readable-p err) + (delete-file err)) + (write-file err) + (message "[%s]" (buffer-string)) + ) ;if + out))) + +;;---- MISC -------------------------------------------------------------------- + +(defun web-mode-set-engine (engine) + "Set the engine for the current buffer." + (interactive + (list (completing-read + "Engine: " + (let (engines) + (dolist (elt web-mode-engines) + (setq engines (append engines (list (car elt))))) + engines)))) + (setq web-mode-content-type "html" + web-mode-engine (web-mode-engine-canonical-name engine) + web-mode-minor-engine engine) + (web-mode-on-engine-setted) + (web-mode-buffer-fontify)) + +(defun web-mode-set-content-type (content-type) + "Set the content-type for the current buffer" + (interactive (list (completing-read "Content-type: " web-mode-part-content-types))) + (setq web-mode-content-type content-type) + (when (called-interactively-p 'any) + ) + (web-mode-buffer-fontify)) + +(defun web-mode-on-engine-setted () + (let (elt elts engines) + + (when (string= web-mode-engine "razor") (setq web-mode-enable-block-face t)) + ;;(setq web-mode-engine-attr-regexp (cdr (assoc web-mode-engine web-mode-engine-attr-regexps))) + (setq web-mode-engine-token-regexp (cdr (assoc web-mode-engine web-mode-engine-token-regexps))) + + ;;(message "%S %S %S" web-mode-engine web-mode-engine-attr-regexp web-mode-engine-token-regexp) + + (when (null web-mode-minor-engine) + (setq web-mode-minor-engine "none")) + + (setq elt (assoc web-mode-engine web-mode-engine-open-delimiter-regexps)) + (cond + (elt + (setq web-mode-block-regexp (cdr elt))) + ((string= web-mode-engine "archibus") + (setq web-mode-block-regexp nil)) + (t + (setq web-mode-engine "none")) + ) + + (unless (boundp 'web-mode-extra-auto-pairs) + (setq web-mode-extra-auto-pairs nil)) + + (setq web-mode-auto-pairs + (append + (cdr (assoc web-mode-engine web-mode-engines-auto-pairs)) + (cdr (assoc nil web-mode-engines-auto-pairs)) + (cdr (assoc web-mode-engine web-mode-extra-auto-pairs)) + (cdr (assoc nil web-mode-extra-auto-pairs)))) + + (unless (boundp 'web-mode-extra-snippets) + (setq web-mode-extra-snippets nil)) + + (setq elts + (append + (cdr (assoc web-mode-engine web-mode-extra-snippets)) + (cdr (assoc nil web-mode-extra-snippets)) + (cdr (assoc web-mode-engine web-mode-engines-snippets)) + (cdr (assoc nil web-mode-engines-snippets)))) + + ;;(message "%S" elts) + + (dolist (elt elts) + (unless (assoc (car elt) web-mode-snippets) + (setq web-mode-snippets (append (list elt) web-mode-snippets))) + ) + + (setq web-mode-engine-font-lock-keywords + (symbol-value (cdr (assoc web-mode-engine web-mode-engines-font-lock-keywords)))) + + (when (and (string= web-mode-minor-engine "jinja") + (not (member "endtrans" web-mode-django-control-blocks))) + (add-to-list 'web-mode-django-control-blocks "endtrans") + (setq web-mode-django-control-blocks-regexp + (regexp-opt web-mode-django-control-blocks t)) + ) + + (when (string= web-mode-engine "spip") + (modify-syntax-entry ?# "w" (syntax-table))) + +;; (message "%S" (symbol-value (cdr (assoc web-mode-engine web-mode-engines-font-lock-keywords)))) + + )) + +(defun web-mode-detect-engine () + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "-\\*- engine:[ ]*\\([[:alnum:]-]+\\)[ ]*-\\*-" web-mode-chunk-length t) + (setq web-mode-minor-engine (match-string-no-properties 1)) + (setq web-mode-engine (web-mode-engine-canonical-name web-mode-minor-engine))) + web-mode-minor-engine)) + +(defun web-mode-guess-engine-and-content-type () + (let (buff-name elt found) + + (setq buff-name (buffer-file-name)) + (unless buff-name (setq buff-name (buffer-name))) + (setq web-mode-is-scratch (string= buff-name "*scratch*")) + (setq web-mode-content-type nil) + + (when (boundp 'web-mode-content-types-alist) + (setq found nil) + (dolist (elt web-mode-content-types-alist) + (when (and (not found) (string-match-p (cdr elt) buff-name)) + (setq web-mode-content-type (car elt) + found t)) + ) ;dolist + ) ;when + + (unless web-mode-content-type + (setq found nil) + (dolist (elt web-mode-content-types) + (when (and (not found) (string-match-p (cdr elt) buff-name)) + (setq web-mode-content-type (car elt) + found t) + ;;(message "%S" web-mode-content-type) + ) ;when + ) ;dolist + ) ;unless + + (when (boundp 'web-mode-engines-alist) + (setq found nil) + (dolist (elt web-mode-engines-alist) + (cond + ((stringp (cdr elt)) + (when (string-match-p (cdr elt) buff-name) + (setq web-mode-engine (car elt)))) + ((functionp (cdr elt)) + (when (funcall (cdr elt)) + (setq web-mode-engine (car elt)))) + ) ;cond + ) ;dolist + ) ;when + + (unless web-mode-engine + (setq found nil) + (dolist (elt web-mode-engine-file-regexps) + ;;(message "%S %S" (cdr elt) buff-name) + (when (and (not found) (string-match-p (cdr elt) buff-name)) + (setq web-mode-engine (car elt) + found t)) + ) + ) + + (when (and (or (null web-mode-engine) (string= web-mode-engine "none")) + (string-match-p "php" (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (setq web-mode-engine "php")) + + (when (and (string= web-mode-content-type "javascript") + (string-match-p "@jsx" + (buffer-substring-no-properties + (point-min) + (if (< (point-max) web-mode-chunk-length) + (point-max) + web-mode-chunk-length) + ))) + (setq web-mode-content-type "jsx")) + + (when web-mode-engine + (setq web-mode-minor-engine web-mode-engine + web-mode-engine (web-mode-engine-canonical-name web-mode-engine)) + ) + + (when (and (or (null web-mode-engine) + (string= web-mode-engine "none")) + web-mode-enable-engine-detection) + (web-mode-detect-engine)) + + (web-mode-on-engine-setted) + + )) + +(defun web-mode-engine-canonical-name (name) + (let (engine) + (cond + ((null name) + nil) + ((assoc name web-mode-engines) + name) + (t + (dolist (elt web-mode-engines) + (when (and (null engine) (member name (cdr elt))) + (setq engine (car elt))) + ) ;dolist + engine) + ))) + +(defun web-mode-on-after-save () + (when web-mode-is-scratch + (web-mode-guess-engine-and-content-type) + (web-mode-buffer-fontify)) + nil) + +(defun web-mode-on-exit () + (web-mode-with-silent-modifications + (put-text-property (point-min) (point-max) 'invisible nil) + (remove-overlays) + (remove-hook 'change-major-mode-hook 'web-mode-on-exit t) + )) + +(defun web-mode-file-link (file) + "Insert a link to a file in html document. This function can be +extended to support more filetypes by customizing +`web-mode-links'." + (interactive + (list (file-relative-name (read-file-name "Link file: ")))) + (let ((matched nil) + (point-line (line-number-at-pos)) + (point-column (current-column))) + (dolist (type web-mode-links) + (when (string-match (car type) file) + (setq matched t) + (when (nth 2 type) + (goto-char (point-min)) + (search-forward "") + (backward-char 7) + (open-line 1)) + (insert (format (cadr type) file)) + (indent-for-tab-command) + (when (nth 2 type) + ;; return point where it was and fix indentation + (forward-line) + (indent-for-tab-command) + (if (> point-line (- (line-number-at-pos) 2)) + (forward-line (+ (- point-line (line-number-at-pos)) 1)) + (forward-line (- point-line (line-number-at-pos)))) + (move-to-column point-column)) + ;; move point back if needed + (backward-char (nth 3 type)))) + (when (not matched) + (user-error "Unknown file type")))) + +(defun web-mode-reload () + "Reload web-mode." + (interactive) + (web-mode-with-silent-modifications + (put-text-property (point-min) (point-max) 'invisible nil) + (remove-overlays) + (setq font-lock-unfontify-region-function 'font-lock-default-unfontify-region) + (load "web-mode.el") + (setq web-mode-change-beg nil + web-mode-change-end nil) + (web-mode) + )) + +(defun web-mode-trace (msg) + (let (sub) + (when (null web-mode-time) (setq web-mode-time (current-time))) + (setq sub (time-subtract (current-time) web-mode-time)) + (when nil + (save-excursion + (let ((n 0)) + (goto-char (point-min)) + (while (web-mode-tag-next) + (setq n (1+ n)) + ) + (message "%S tags found" n) + ))) + (message "%18s: time elapsed = %Ss %9Sµs" msg (nth 1 sub) (nth 2 sub)) + )) + +(defun web-mode-reveal () + "Display text properties at point." + (interactive) + (let (symbols out) + (setq out (format + "[point=%S engine=%S minor=%S content-type=%S language-at-pos=%S]\n" + (point) + web-mode-engine + web-mode-minor-engine + web-mode-content-type + (web-mode-language-at-pos (point)))) + (setq symbols (append web-mode-scan-properties '(font-lock-face face))) + (dolist (symbol symbols) + (when symbol + (setq out (concat out (format "%s(%S) " (symbol-name symbol) (get-text-property (point) symbol))))) + ) + (message "%s\n" out) + ;;(message "syntax-class=%S" (syntax-class (syntax-after (point)))) + (message nil))) + +(defun web-mode-debug () + "Display informations useful for debugging." + (interactive) + (let ((modes nil) + (customs '(web-mode-enable-current-column-highlight web-mode-enable-current-element-highlight indent-tabs-mode)) + (ignore '(abbrev-mode auto-composition-mode auto-compression-mode auto-encryption-mode auto-insert-mode blink-cursor-mode column-number-mode delete-selection-mode display-time-mode electric-indent-mode file-name-shadow-mode font-lock-mode global-font-lock-mode global-hl-line-mode line-number-mode menu-bar-mode mouse-wheel-mode recentf-mode show-point-mode tool-bar-mode tooltip-mode transient-mark-mode))) + (message "\n") + (message "--- WEB-MODE DEBUG BEG ---") + (message "versions: emacs(%S.%S) web-mode(%S)" + emacs-major-version emacs-minor-version web-mode-version) + (message "vars: engine(%S) minor(%S) content-type(%S) file(%S)" + web-mode-engine + web-mode-minor-engine + web-mode-content-type + (or (buffer-file-name) (buffer-name))) + (message "system: window(%S) config(%S)" window-system system-configuration) + (message "colors: fg(%S) bg(%S) " + (cdr (assoc 'foreground-color default-frame-alist)) + (cdr (assoc 'background-color default-frame-alist))) + (mapc (lambda (mode) + (condition-case nil + (if (and (symbolp mode) (symbol-value mode) (not (member mode ignore))) + (add-to-list 'modes mode)) + (error nil)) + ) ;lambda + minor-mode-list) + (message "minor modes: %S" modes) + (message "vars:") + (dolist (custom customs) + (message (format "%s=%S " (symbol-name custom) (symbol-value custom)))) + (message "--- WEB-MODE DEBUG END ---") + (switch-to-buffer "*Messages*") + (goto-char (point-max)) + (recenter) + )) + +(provide 'web-mode) + +;;; web-mode.el ends here + +;; Local Variables: +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: diff --git a/elpa/web-mode-20200612.1038/web-mode.elc b/elpa/web-mode-20200612.1038/web-mode.elc new file mode 100644 index 0000000000000000000000000000000000000000..e32e49b12dd2e21503772e63adce427d92969146 GIT binary patch literal 330905 zcmeFaeScdwk|vtznan2c-}KJT_T8DiyL;z^ieuR^C6Uy79NV%jC+gUi+me%XONw$t z9!az*lI9_0DOP$u(ESMazx`zQd8z;$oHtUoJGuLtyH0d?4p1l*fI^{AC;(rqKf3?V zAAIn^l`p>dBDmi>>9;#kOFr7&VErU)#=&Vch}*qxP+y#BNX+Z@@HhxNouJnrwolqW zg+oNgGgl;X`?wtkhrkjvd);B!?#97rcvxKyy1j07ZR`HVM$kMC2Vrvvv^OP5*lh)I zFKC9{Zf_VIL_wz)wxU+h?hbo~hI&2d4T2~fblTBi=E^jaOds?{-Bv%i7Lm-VA@ll` zfd8g%1=HamIt)^g!E~(}On0L05lWDXxqkh6aA(aXj)#MG_o&*5;<%rN3o7+S#ezkH z0jR3{cs0HjybfcOSnDr1M6gy~y+Oh|Axc{brarxXU1|xHUGneBl`B(sYb(Kb(LwOI z*NSZI&;09^=~i@zI*o_H>*%0*f=FBDpi*0!nVXrb1k+QW1~b9@+%htnJ~$sn)h3Zt zb{lhZ_^aWsj=u)}=JB_HzeW5l?KWzNuOVK3>!1C0x6U`Fsu3EgYD~dDV!>~1;j{ms zP&MGF0Y@Fsb;Q;IUAKAEe5g9o)sbr*DFh0s6sHf>ARa(A46X)gmYh>i$U&fp6A%rS zCJ)8(F_!e2V?RD)O~?^AkXy)unz_5D|voB0d_;6{vgk9 zCcr*IJn9J4Je~mgMDT6O^XUZGKRT?>CO~dE$n6P`&mH8q6Cl5Hkl#;${F8(H^90Bp z2f4dD0d&uS{xAV@->cFeC%}dt?7;-srU%=a02?7*8Q^dN%uz5E8 zJR9YCHf){^o9Dcr=X`md^T^Y5+uiy+@^wrw&%ASEA$S9DphRD6zVpb}rCea%#VHp+ ziKJYxWnJ*|Tqw_T!REPO^IY)rT+HPu*(}=p7Hxiuwr&?~UbV(mQF}58Y<`P2zex#f z)h~e*!L?+oy(9;hz|ywFx?sf>Cs+c-irCV&1lq$QC?_@4MA*$M1w+NOra?{G=VKWg~Yf7mJ*5%N$JE!aiOjF zXjt)qsm0hFC?gcHZ3l{vF(fToO03jqjF%digP0sBEF>$6g)uoSSxP7@G{Lz3@WI~@ z=x^lto4+YX{I>$}ck=vj4BX!f#D9?IM`PeV7Kq)h{QPzd;O?P-{KG`R-wDKjl;=N= zLHM5p;-BRCpU1%cULgJtdH$C%aQ`e2|02)-ItK3l6o~&O&;LFK?tcix|0U0V9Rn8# z#3vKsb}IrhH4*Srfw(Hq&&FhYO(3S_d3_Ar4T1Pvo;Sz9RRv;3p0i`%<^-Z9&-xg+ zhCs~Ab72hJqChOkb9oHhia@N&^NTTXw*=x#dEOoacSj)Z%5!ZD+&zJ~FV6>K;MN7= zp*+7D1NXH+Y{>HuW8l6Kh)42#JO=KGKy1qM=@_^_3dA#cZjFK47KrEa{B{i7cLMRf zJpVKX?#}|TBhTI4F@Spl@`F70$H4t45TQH|#=tcNq9xC044g`~BY`^}1J@Ra7xH{L z2CgFzC-Q_~Egd9!0@0V}t1)l`fr#Zf90NBJh|`I1uLa_4BHXz^{3OpeWAeQah@a*8 zmoaevCJ-3sRD#HWS6(}ahIHY`S)Wr;f)_}W(&|Js#Ed3TnSu|9l`#owmXex^GfYUv zNi;-TN@^Qvo+ILEVy6cO;F^p>Aub?r2LTm|Lm@JIzr%?449wQL}?Z ziR#gyH|jepe$Z`qg39CY1r`cu)tA+SsMQ`~34%buFgodT1tG2ktD3YEc8^BkQ4|NO zeJpac&w>iq1Q6e8cV7n6qd})CZ>z)bD5z|;hfyV{91n;6)!A9QdN9))996F8fS*PE zUfdq`2InS8j5J4B@);e>V1Z-y@a&-1jvW?Yun4P%VG|@(9?B2bK;m;O0i6ZM?W5xk z{#c@!N}ynwIynso?eGB0Mh@FSr`LR0?T4)vD`E~+H0li7ELRjrTrk}~?%xasql5FC z!He)TyczV*hsV9{%^-{s5e=I&*Mm-UI1CJyncXhdhN`sy3rol0X~bVyAPGTU7fVi9 z<{BPz>8dk2=>~Hkc6E5(kAmsuaj)IPFV>`@qiBHO@CZeHGCDcHSMM;0`z$r9{#)_lGxwczE84GNr&e&tIP& z&CpR)*%AUQMd@n%We8wNz5Mz4D`p=Khl8rNRke3`7)QgP^7Zhf6ELEEFd9atC1tr2 z^>G??z#s425)Y!o5DabkVl@sAqhM-h`t*8G`DnL}b*1{;;zyk1)IR!zq7-uEG&tz> zI#Jl|?*;X}gqMW&)37s&CX_&6e$jHgV+l^e!OKxUL;ZC75UaTUQg1xOXE^s#BU#n>O8ewl|yKL?&08ar_GrbAM~AumPN4pg{Vi^5*a|O;KsZi%3uvltmTf zh>BlzGBnL&TzS=@M2y?Os!Qha_3>qkx|H!!yO6QHfpH!Prd#b8W8680#;||fZdUtf zwvBEO2COcMN=QQV$b+!?l0zVPB5XE$0~s11#EsDI4OWAxv$Hb{3P%UiXE*WRb@Wlw zX_Ee8$>^O>+M-}sp6~ZC#?sHBvMxj>qZY;c%joqactjVWD@T@guwx`a+1Mj?O~p=h1a2ms?Rzej=D|p2y>X?e$-@BLxi980~cR}Kpn4&1+oq?=mfsBPBpO1 z2m)#h(cplRKP!kkV821gq0Gl&OKc}v5b^?+;hsQh0-C{(!H)&FIYhRiVI+ljWlz&b z()=#Yi30}FSEFbEj;5$F<7ff?<7g0JEGT1pjm?t0joA!_XXylxZSiq$)M=s5ifdl* zhpn5zAJ)EwTi&ycr`tDWumw+jz5V!60RdK=Fg3+Xx@fi%t$a36MFiO>lsz%Y?aj!(;W;CG3 zWMGG30o48%f+yi`8DV~kavkowgx0A7l6Q585b7u7is=IUQfVTo zhM3z)iycI0R?$1q3SwYDJ<=If>4{pEpyrb)x(8b+vUMsNmV{`vmeJ|KLDjr9OT=lq z(h#>rnh`Ebe;V$Vz}=p`T?raFN=3a%QEC;Vv2`jr7}ZF8etm7Jgm536s-#t}O6d2& zF*Jd_r#X1Nh|kbsse+)j24PhdD|ikE*TibJhSmb-QINn)r2WfiUjSkwpfiv)p}$wf zl4AyuRh=z+K^_-sULlocs;gr&OQ7B_x47Hx_aj(-#uUuLykAZSqc-el@XH>PlZAP| zoJ1^yG-r*;$^pG!UT%UmCMyf`emRk6#+FC`-Y*Z1kZw{iHZuchW(e<^E0pqKT-C7- zmS2%b(9G?y;Kft~bQXrr$^#i12~Hv~aB&Vq`O86Y)NMny5-n&-5IcnoT^vJhe|T)I z#_J(QTZAG{ghCU5Iur-J*Im&DSg=9Vk3bW(X0NkyaD!SE!!Z0ZG6JGHfIx?Qy*BOg zqk*XkI0FF%aaM(ig*|D`3QQNhUvUkwl>xT#wBs!$D1LiU#F=?aZB75MU3W^d4_EZ?f?`=P>WVyM+nw##${ zMgt!R8ms$cv*}Q8hhUP6T!m`r5@u!L9VMqyShb3@h+LKjTyr*@J*yt01v=3|H~>X9 z>;<)7NM}rmDZW7D5s*RD_*6nbidC z*TZAfg{lsmA`GAk!qya9o!By=4kOnwZ$c)bMoa_$~{tl+6F$j5+xC(Un3I=Lf zERni@9S+!m!00Z$3Gy(syWl}EBX!!UtdICG{=g5)`-2{qB;wv+EP@T|kp+iQ-$XPk+b)W$cdaZhzTQpIse3%=Og-Z~9HHgmBD8x`=68Wtm zMi$I6ETZXYtXjt0-2{Uz#LG#$i(N%{kAvl9e0y9C)BH=6chxV!R=4+ho?_`O@W^7} zyCAA9{&fh-;wdDERa#q^RJ1Y0U~>h-;W=p5Dn99TdxURyxtk69yD)W!aU1dIZ3UI; z%MWQz&KL{Z(#WZV$!y;pRmuqgYey+Kbb$#jU zIe8+Ddr7&OW`tB;MsQ|wGcvRl4#Vn=yxz5c!x|Thm6&0Qt6nWM`OFjDSCw#~FI8$0;7MTxQEFJ! zdP~!-Dy=`rPAwlEG?x$4tRqQ1pO75yc(}7ANFiT1T#3TD@yPR(TQ{kyFLk^jHL09D zWU7vAv@}Jka_IUHV@z+t2dtp&lN^jWC13wsvmcDGd){wYqV31gsMV{AvNINSsRAwT z03Mcn9^tUcyvL%)B!G@1I!vdkh4>AIJoN(@;0MF=_pW;>1d!!&5Vd+N|srx}2{uZEqT#p)yzHcxD)1S0Y`aP^wbceZYtQF+lv#}U*wPRVf0JYO39Zb?c zR$~}7V9FoD6x_@;HWH*Vvbj%gn!lp9OOOVFt3g$tiP^!=^KrGAIUaGgmD{JlrXcG@9 zteVJCAo)%+k>~_T(V}j$0?jizFq^IwG~~oQ>|$$zjb_h+5+wj8yZYs`b5!JzG~NM; z3@`6osYqQ^ycaP}m*E;u(oX(h+lM=EdZc9nI(3yIqn(JB;9`VW$~@C z-UqX3zq}V;(v#6u)nzbW*{+xPAgNkO&{*4hs@mBx{IqXdG3**9eF|^lVdyclWs%8L ztA9L?W|C$2GSr^I&{Ibp`YaKpHlDjO3l~>Nc$Fr}O7l&dJagqrFlgylUq{@D0H4rK zE7dw`{=a<2S>=9m&ZT;Ys`>Q(xnyO_v}+6t<_cY!HC=twz%?QFl**iDO<&BE>D6{! z2_;mJRC{LZ*0w4W#10_UWDcpcoiAnlsYw~JK1?xM1Cb&X;wL;w)G|fxk2N&CWCjK! z4wD&aZqk^zJ$ilAGptu0z_Pw6gHFbjk)%wKDb9Nq*E?7t{k-pWVAFh8E2NL;5qsXB zBKj`XCg3YGPWkBW(f+>tmWZ4&(#P}`go%yHPwUkV+3@oAd>=`Ebw<4}XM)FAVC0#2 z@Cl{sAp6e?vw|FmQ;rj{#@E~=^p+7-`!?d@-zhK1TFk#!UXTWaExN!jc$_!#TeD8W zD84Kejcv?elcY*XQ6@`?B;y+}29wJvg~(Hz%wCf)P+ZpI*{4=K+N|I!(nN|gq4Jbq z_qU$;$l-U1gDE}inU$(dEZf0{TK!isC}5qQ349dPJ3Is#ZG^Gb-^F!owOn|KGNZWz zbkumTE=<Cw`+HaSHG9k7f@4k@(=qV{jqN9Q2xo(Dpz(pH!a*-VDrb+7dtH{ zXWxh#&BkJJMt0kQ;_@ros?+{ZuOqfs@9@j$o#{&Bed8HhH1N~Cdjg(JyU6~iB2=Qj z(I-1)jmxHf$R$KEWeX_%!*${Hv#I5Jt@g#u;Ik-fVqfAHDI;9sSmj$3a&5VwI!fYj zRr5xS1cz@X$l$20EUEb#(1mGz>p&)LePvnn7{`xEj`L+4IKQ&6vJ#R73Q{eUrCOO^ zSvgojs=c6A$DycjbcV?CB3J-ys&WVF#4{k1POp}62uX_R>i&*pC z*9bek5fzUP;Nw<^`n1=Ecd9)A08|MPLFE7&{*d;7*f7M&Q(Rv07UB2-Y)+^gGqQbh z#AmlJd7(!hMO_5Ik%nZQL_;`~R?vju34Y_=2%9|c0=If0`!zBsDzUV=ST(__GSQ|# zC-fzxO;j^}z&J#u_=(|3#-CR#2X(cPc!FZ$q$*t@2}w3p zJLQ);Pr`vrMxjddA|{HdyNmTec6h)El8bg6J!J|-txT*e=(@0#$Fm}nuv-MOSq9rK zcp)~&ZKp;GVP6m3wCpUn#-7D4Aur@^dEpFS-$cSn7#T*xWaZfxW2$Tq~U1xdl-*Ys-PAM>x?2tgpZMwm0P>J(>pt>VW)o_ zuI}y0YjTY9sA|)j>uz_6evv(%t@8w-@ zEEe^M7LIap2!U?)4oJS3y)(X8pH!=W`eb)^=l+AW?KS-J)A(QV^}*)-?LR$T$LpQ5 zlMX9E%Dq%pZr}2wr^Bb%)r)r2{;(5#ytljirhapG_vcTMQ}8h!9|w3a=5q!CX19y? z-Q8>Y_3_@Fo!zcWmNd=$^1L+7(i}+yf5?Vs_>yD5gRt(7u;v<_Kx>V$Ewi=n-O91*anad*1b~MP^=_(L!Q-R z5H~SeV2=YgOX;wvG15@=TCgq~7>)l;rw!n^px#yCQ0loM0R10TVBRQUQK=!Vkp~dp z`T=Kvwt0{H8W#7@l~0CSa9Y}N5Y!e$9-~OUfY_0exf58g5w^1m5~Q7iO{2u zklJ(TPwgT&4*MZT9H`C-Fvmrb{1P0u* z8g4;A7=KJH%6Nsm;ro8pCVc<6hZ7LA;;@MsA(0t6`D>~;k;U3lgo>mLhl2?BS`1zy zZx%_4b0oz%9^r#w*g>E#vS6k~e}Og&DmZ+j-BC(U!j}p}WcE!5_fwo$1lnz8|D(Gfet;(oX*z~iz zI|E@9-+`J1AuP`saD&LZYeJi^`?v%z2+c4mC&yg#qR^Mf7Nl{CMifPq|pfqx<5ek3z@$Wju06IE(V4g`7&(?Rak2$uN@eik%jQI1cUjI<{?Y;`jgsNWiIc7_8JkY+gpIQVjCpViI=RIeM{|aFl2rngFjBT=W%_0pBsr z)6%H^;$oo8Br&4TD5{gt)wi$5m~>IU;}F`-wJ0iTr@wO??}3Vo=8#Vu(BzfcXg&r> zKj~;j4{{aPMCKQ#9NtZB1G&IhT17uHcp#!|u+f%mMA8|p%A`5ymrZ1Qf>WJr^5Kjt zWO}>=HA5v#>oifF6#pqIB4&S(PI2PZfM`$#Xyn*WbtaRod?;S8*X_i^Ju2Q5sYz|Y z1k-_C4q>7k5`$`q2-4AeX>Q((-gApVaykU%p_pX)P!}*`QhN_{Lzpxm2<7xHJ36M- zwwd4|w{zOSU)C_D@EH{>MXbBXV+S2m7R)r2HcvoqAMx_lk+E6HYMk>uwzKUNqtKRxVBYIJQK-YX=t23--=w0MU ziF1lYp|7p1F#i5=Td+4I@q_RPXXP?rxn9>0%;Ze|f^U8MYev^`VIfjuUnQ0^HGs$B zRMu^Ia2U0GyYk=^YYFJb?GDY(BuPrJZt)8}>xO)sVNLL_LKw~!SjgG%GSq-1L!ocO z%TP+Z0XIlNP!|F>9Dd3C8=M4TqJ`c^;mJYE1PB3-N19l0J#m#?pA%}Im{=iY(>8Xa zA(gY4&{~tcHyy25*hJwr6IyFhIh!ZZk!Icy>NZc>SR~WRs%r?=oMX&*(E{RdRoP5P zQU=+y1=I$AYTH)|@KhVSF7!Pez*=nT8Z@`|HhTPlT|##BYaMHx2zdwtQHZl0IJ>D4Q)VNV%SSbtS}k0SlTUsXQU* zxmS6L0-Pl^v$CWZJWgv!`JUUVF*MjuEztL-Zlv&kO6XC(`I7<0rHCy3pKWn!l2_<~ z3onF@+Pc8I_!=Y>(uYtgr5o29`kj=fE-e+}6l@$BAkDKdCp9bPs4HuQwmOtM4q6bkl6_qp6gvTxH!)r# zyMw_g)-efCThxG2M+6HbhkQ3flb=%Cbdsm84CB6Quu21A6OvQW3CF-z$*+|~XK zOWIMIoza05c4b+K$H*$xiPA|^H+!)52yIduSk$%rrq$6LS>lvdnI3BbA*Pk^ryywg zf>9wX#)TDWjaH;$S!)*uTG-kW25GfnTbA-HYlFAiJSu=8b(p46eDw^G0OeMkz^Fq* zy&)Omgb6b=)U{8+cuHd!`tOoTBbe^BR5c|DvrhZ17`z?<0}eBV9rRRCEGv)MHeL{p zi-sy{=7mQi%OE;dL?fLcEaMJS!F2|6zad9TblB}3@_Sx~0<1w{&yoR<6o)YC*6IwY zEekmkFs}hpZ478=z>3g-fY@-^q68ed0YaV}K}W}9Tu`ib zdoYraa13WxovJRIuGw~d7prV6C@iM7VT8zbbk@`%bx~@q?KPBeSNjAf|4YH=7lo{L z_pmKe9er170!{^5F>@*`)B9^HM5u+z8q**$)8I*v- zPLF0}uqs@TBtZ|?FPk!J5AO7S5)u}dG|50^AC6QP_}G$!!Ac6*iJg4X0Ng1pS=5%K zOeZZfP{Q>}h?cRGS=69qgXWWVs|6dj1V}Z*b%Sf$>`yB3PILs*N~1wf8fAG&NAvE1 z_O6<;7EU?Wftjve#NV}5AO-GUqU& zC=-6{B@C+LIIQG`LFc6|dv>sC=-ALp7<66;z$$>Dwyqq536N1l7NxRr=A~0a7BmDq zw6wC8l}SzeE}1L`E$RC;ZEhUIEzMb5mh$uxEd~<-)Bq~L4n{g!AOPorXdNhz_AHO< z@Wa(QslsI`0qt~JgUT=PAUH8BT36|X5EX{YS|l7=&IBtuc=gSPv{heaB18gdV?j@( zd1^~i-+i8DE_p8s-(Z)m)1x#6PXAG2YEoBpLC|lN>=476wUnJR8h)xI7$kjFVh3TX zEfWNY3L$Qg^i|1hU^_-_S*UX(-NK4AK72-8UlnQwUSAbv!W>pb>b#C!FwK*mns&s2 z-**+>D26KS1|8c`HG8k4s^T_CI;sZ52d?L;_5>q=(=DY&agw^W=8DRr7+c$gBvl6D zV;$RdsE?f@s?8za!h9=>QbTcDDO}QV3a8D$Uql)JvV<+1^fvoxx~}T+F}5PARFLAw zMs--$VGy5i#H3V_o{i7Ce5w+P&xU?V-Q&}u*6*LJ8d#Tt4~^2Sl;SLgK{T&?_73EHxfoF$(TRI#Q$w~{~w z!%wbCq<{SM`i0aOE;nLfetO-t-|&5)abgGZ+*kQ;ZgC9c97K>}Q4RQnga;a>JRd)s_{x3Yoo zxsMQr`_?6#_tr0X;kbXD;kCI>6!f~eSwype^s-un2{-tjo%+FgS*p1`Zb&yOrCwW<&MTI54r2 z@9kT|gI?<#KLh-=cz`~heAAa%hR+(9Sxq8_!KT3ijTq-B!`sYdgAmQAm4Fbh3y(~A zbi!af1>vCyg~BP}@+&b%CI)+QF<+1~{`E~_k4@}xjWKviXxoIsS1*VMO(ibCvAyK3 z7Z#x`)e1s=lh}@l?X($#r-YuE&=Z`$$#D6Vn6Ax=4uP@;ozAUq;`>b2S8T6L7)Oza z;rb%@ViPA986Zl2C1z-1TsukV$b^nMw{JO``6k5Qnnk$4o!Qh_*$OdwFk5cDmUn@u z8;IjNg+OIdGjU^ZVi6^ zS&VgXcrhzr@Ibn1;;w3@x2}Gvuor<1xr@csTv!_u%X}a_M@K3mE1=jRpwj_*iwPos zU|kLC#p&ElI2PG55%R5MS(I1d$OMe;6RuDG=iT(@YWlM(pH+}ktr7z>HuhUq)*FdN z?9Z$(#HH$w-=BP9K|c9JLGJpgOd>xUTl01$u)Ks`y_rIK)#iB-C1jCMlVzUtzj#3g z=r2P2n^Xa{Kvk_1hwcY~bf3zP?o*q9pR6Ri;*rqh$Z{-Z$h@jG!*ZFBDZ_+Q1{w5n z@gcfgHC?r>;n+b*^D0i(Bg?U661q<%)bfZpF_j~6{GMe_Q(TM2U$QK~Hs$k;cFIp( z2bLz>aTU6!->&-Xw~qp0Y#*+L7PQS9Lmc{oZAtN}0_-J3!&TQ2T$O2GGgU8GQjH-Y z+C6<3ecu$M$c9o)?1$V*}zp&d9*iUJHe@g7X?T(@i|NwtQaiKV1~a6KuM<&5VlaFu4=hfp|lDK5(X;ThhK;u zi&U6Fsx6d~1wuu>SsA%R664ajDwb4Q%fT1;FP{*RezJs5Y*MMr=?fl;UYMHk4#RsU z*D17ehvcsTNr|-@gehz3Iyk^o;$`p!>(T?NPXI!7YZgeDRnf%JPiT2_)tnhmWsGfw z0HhQEtDYHeJ_~O?*>$`WHq@wecFq8FvX4EcOES3DOOXzjj?p}abDYbEAIJr*lS(H* z43Z>z1f5NzUm4O&piN-Q$bKn~4 z(!jQzNoGTGDP4p~Y^GDlD{-C9B=RCmq8Lu$x-Ly3z4&yo6wDTlH@VuXm0Mjiz`W>{ z_$dag>SO9mt88_*EBu5&!k}seomcf1f>8v)P8tEZbro;mc*yWuv+^#{=0F_-;*QsW zEJ>RL?Ou=J(E>uv>`e0U0^yc-Kf(nW4v)!sl9nvflFRzpqKD$;aJ zMeJM+HXgEh_Sn7fwf^J*KBUrAzo2`}g3@VsQOO2AX2Ur7jlvdx;X~7jXfKjq1aLE? z`twAje>6O-E~7xRLL-*(B$XJTOkJ9HSRaU5Dpib5NDxK(Ey12^Zo-l? z_u^m{{%v~18SiSf_r?@>NEugRN$-4#&8A1#BCL)E^@BU7E~YNP{_Ex#Nxh$GA|2T64}Zh`1L!MXuW!Zi=yQPdS#qpa5L z<%|xmR@Y^^2GIyT?>2UovVru*aW3P$Tn;z#*gH5ZqNKsCX$+LWZlmq&F~O~?Y@@qq z8H{3hrLBuUYTd#cJ({tn(dQ3MliE4?`Kq^#5*zhk@bfoTe!gutd09m2UViH;c9amc zF-ZxLaL~Pg*$Gcrn)vikE3~yN0sPig8)SB&5d|?A{taelEr4-82W3r<+Unlt2EfWS z5e_?_?%jE_^X4ymhCplbA^M%EH!q~f0e8av~eK!b=xA+^If!aYlqQwG{WTl0(9n_Y@^-E+# zJ`$32+vZiafxb@JE-8D`*cm@HjF@y^Qu-N24X;8{Gki;lMXvPNj*LB`cTC7R7P`!| z(gh}-$afQ}s8OK-or|_I&Fm~r?ZT~s=BOft@%**lB)mBF>Ff;%H3Pz3Zz5-Qcc!PF ztv`kj{lzr?rgrSURD4K_aT60Vw%nHS=iZTuy9%>_K>3q?uXR$c+*2M+H&}(ACIO$k zF$7wdZs}1wt9SQys>ycl&oP*4exBU2(jsyDzExU!v(*n2lA#hww+zQV*$h()p76dZ zyL6`Kj2DbvI5#7Kk`uvoBMdkAxCt#U(H!U}wJ6z2Ru(Cj*y2PI@${7z!WCz7a0HWb zE0wqXm+?b}tD7;M>991^Kh~9EFGki^#3mtu$qHc-mP2c6Wqz(!TPQTD=phoa@19$c zF#4O#)0JacUAC_7RpAP{Ysm3A!YIeG;5-(h!QzdDkY(m^5Tc1qLKB^&AiQ(1gi>91 zOM$r4wTg{Rrd}{I=>@j`yKYAo`mw{KThHBb zK&nPmarbS&Tk>Fak!yW+%-(qOo@(ZLnxmmpa$){SE+i|MzKY|o z^$us83CVR`n4_>Elv!|#NpRGQ;+xlj`vCi*uL!L}_#nodiWA72 zGUu_epsm}w0^J&$=vj7(JZwziGCpP&Cpg(g?m#EbZWQ5wyI>l#|2cm5dvHFyq9k^& z$;p+3$4$jJWoD*m7Yoa!qS@@I>SBA-#fyG)hrdVdLp;$y*j;rU>y?#T$;$cF7*n>e zqZ3fBq06Qaak>Gj`1DBNdj~Jzz!31J6%0<2hTEa>E{>G5fcu;~lo zSn!x52TfYJQ!udyfDm2HCw?GOU?3XeSSPSJ&|riRJkpMXr~?8LTMp9uh^awWtdoS0 z%+e*eI0?NY*qkec$r!#ArWV{NQKLt6fo}#6w6hnFgTU!Ks}I&6t#7ZRzBit1tv}nw z%N9cJ^X2(d99qIC%n)#x0$#xVI9CTRdRGWuMtxK=qIhsgZa0f}eBLiETjX>h>?si9 z!82MMyl5%#q9w)4!)Ke1@$=o+>(3}uzJj268r=I6ULS3I!;nXiH{1CAdhOedClpM7 z*xY!+@b!lb-gxq4owDcQ^GA>Hv-x~mKEGXi^n87b0nZ++KU0KT>rdC7t*NNOjq8Yf zur5DqD%yxIkIJNrkm;^8aW5bBvihO6+J3ZqXr41CHQzXYe0|qd|-4qcfbFfn!|`A=&YZt&mM=OdLMLwILh@AZ?06 zLF9LMJm|efu&Au~9d+#+{Sb*kmr3A6!<=Zeq%Sg_a7QjQg~N!!;b>G8>8+^4oputoJOWLXHcePWYVCR9mE1yhLI>8UiI~rg)nP+iZ6PFJ!Ix} zFpyzHzf#7Nj+)a~*JES(DG6egG-bG=QaPnq0d3fI?E=%DG* zuh|&*QE3z5zAb$8R1RV4h!63HM=!>j1x6P)l#6vRfl@1AFK!rN^?D;yH=;4~`u1{1ePK{wa z5{(=8DqGvn_Mfgj*f*NA{d~6Z)z{mIUVpN^e}D7w(>43?$LE{dqEj>G$!6+v-oK{?Tu}y;s(uwjjgpuk2b$se_#T5cqOa@<_mlK-78}}AS^Ie{;;+AWdG^2 z_3iCH;b-Fs>3Otq52--Ky+>n}EwiH6jQ03>IrK@5eX4l`)AMf`}`+~htUt20tq z%aCApl~Sut5a2`AX?;;25rSwE>w-aa-Ij5AsYDP}3{j<3OgJr;2oh5wQPGlEOOAK!*%P)7Ke_)#FE)z>_|VpLjw`!P8dunUHwijyhE3 ztD4a8!b6mixJb>SiQZoAX{f}BtjJIvC%vDL z9EK(wCI|%Vwb&huU4!^QgjoGWKEuIc#JMa2<$fYII^NY60xw>|3mk>R0%5y0A#kLZ zB6A#p&^|Wv;s;YG`clX_K<(%?-^UcgzehExa>-22wFE*=>NK~5h`j(o@MXc>Az z6?n`ksY{9a08X*=L4%MFi#mk^38F(*HH?Is1*#A!dkn+apGql5<)uP=To?X_jIZ6! zc^ZKaaRFkHkvwp15wh!HSijCz!MobLpn{PM9PBEb!4vn{x?)jfQMwp=htDJzwv(x4gvR35F zFI&QBWLmS7nF!MgE~`=a8vJTCYPO7Ekyp7^s?W|M9P5f#GBg(DU??RhgU*mzclc`5 zkrW3DCd^{=nBhYlcMC{ukfary!LAD}1Mwb<;$SJFb*3`#sImIliWgsW>;YDbn41c7 zp_K%V(9f8snJQbRwj=HS{`!;qn-5@V7Tf9m{=*n>*#uL7lHITSK{Ax{P94@SM zF?SU3{6*0SMK82^o#_OfSewG>aadVHO(ZJX5zI0O5GcJ01z%Q9oKUkf4MJBXd>NtP zx(K($qiI;pPIgck!nf?nuHY5`yeCbe+X0LMG@1R)<=F4JeBrQ^D)NT?_xGtOMUiR# zR(oLHFik)1wd5l_P#GHz_pLQ|G{kMfAv-kpHu9Cd;Q(F)a)eJs9KrUFV59CbLh_*M zXQu*A&ldZKQ@7hP;ZJ%D?apXA%=+=-%q%8nTEq}++KI28lG`1!g`ne7tHlzg`5`Yj z(XV3`boUmP%h+i4RiM-$A)#WL*vE1jbY8K#$EY!8h~24j`$Q}`GshTb9k5#Ba~>ne zPKY-+&)~($#{o|ns=N+GpBDMEueFU(dWV>w{SfC5#j!9TgFyf`xx3icxMy9yR2(HJ zbk+hSiJ(_uv+qq$aQrJ5$^kWTMnG#3;6^yWh4Nl5l0j~9jL`zqgKSW|Z^j<98{+Iu zA>@;N?D}p}MLXZ;0_DCAAhJSg-jl`7eM7y8NLDfPNx3GCocObkOw7?W2=VU@+0Q^F zIROm41kFbN8pykTl!G_W}@n_c*OcxyxwACCO~z|L~_4(xK9fa>U94#Y97H$MSF=)iwV+> zqnG`dAR*Dbr^z&dKB*?iR-I^bDQvDF1~Ms(3BV#_2Q~zBl7uIkIBEt=yAN+1gi96Y zBQ;Odk3#K>*%h#u{qK87(H2SCLWC}GTuPUlaOY33J{41!M7tE)sO%G-@H7(F6Bag- zJxiCGJW+x$4^*2|*-1uH+!Z98+F|$;0PJ2E3`5-!hjR-$HzE*TD=^Q3F5%U%>T{HzlKD`4> z2v3t9mi-3#?H-N{!gzTu>WIOIq)Aq`Puh@VW@A~lmn2hh36U@J8Sl&REiTvDcRD@Z zWop9nm~b1M9VlYlH8Rwiwy*oJ?tm!Tf%-BGC0{5yKbrIa0?SID;J1;-S~G?-jG0fv zWLzXSC^Qr#zUXEv*dd!ZbcP}BeoMSl`rB)-IwPD=r&OYuAW3XeoFD{SBL$giPwcyG z1L@xP$rHWN5M>^OI1#5$(TZssuZAJ#h?IM+`ikob2sf8uN(EEDGu)iK?W=w*gM4q_ zO;9Y?Yk=W#77quCbim+v8x1-}`ttS^2o~D05blqP;fV6qjG_9WmFZQtLBbH;*(aJ( z^5L+i^6=sfa)dx#fqd@mLx&RS-|Y2X;-W8*)Qks*RJ%ee4gGHd(BBRIYy{Q23|#Br zI2c19c7CDgc7*W04AR5!l$#uUt>+N4Q8pB{OWP_UyhVyeEnk8d>bac~(NraM!Fk~T1fvg(VH0xK|(fj6E zlVk|oRRei#aeH5;f}rE;v6N8kaY3eo^u7!v7X5(_265G*Y3r6V3K1l4Y!R4+&-aaK zoZKfHlO&asf!u9}DrO%+gnYe#Ln7ayZ#0h`1^%ZY0XHETAxi^Q45~N3ZE=7_xNpvSQgN3M?+P8TS+Z zFEbfno7S(mL}*U030rGe-)^p-MS9qC#RNQzbm89rgge=_-h{3DC#{E22vKeF zzBPnlyY*COk`l6QJf4z|2Uxn+#W1GcR*Q~AKkvSTGEL?%pW@*UZl*3DwhVz!de3Ar zo&CWDYLFkY1Ss_g|G=V>jZkfEXHVfLC{n3T?XtKq|+wM(~<-6J;xzz z&;lHBo0uU!IEVZ-xcU9CH^9U-Nyo5nqH|s30X}?g*`*=<%wwfkPlvASv9R#$<56&& zWj@j6+wHXH-|4|Ubw)cqxKGWVKaV)=K0N?oCl7Vfbb4UIoE!kFfC%ry#aMv( zfy&gZP7gN4dw1RV0h}IenOls27HuslzQrg&4Taz1IQ`eMyc<4WKs zU5jb#SR0b*?%%`GnEc{sH~!w2$<_S_Dnaf)IFQ&4p5OT>M(V%%3l z=zX~Z^u95N-ls1p6Y>=2%6%~BFw(ljr^$jpYb|m+-yXCN*<5^m3U$l8Zb1PQJ3Yg{ zh4M*KA4p*y@F2v>0}cf1a+m}>J4F-a&jxX=OX1gX$SzZ%5&2Z}-?}d2uAkA~f+sHy zW1i^VYC3s{JJ9ecCKfVKI7IzmfDpA?14z=g&Q>+xiD=`R3<;j9?#=H+CH*QIqC??4 zYy{)o)d}98iRtj`h#7yaQ(Y;>2AgXGorm^i6cyG zJJ3dKIu2iOH=Oj`jo11z$46QYbW0?BqEZrFo*!ax*c2JM z$(o=HlgY>?>jM`q$P_|e?E>~wyJ-FFt9yueW{U6(E1@jPGcme7!>uZ^)x7cy3vA5l znefXqQvur5*X5u#MEaliMp%YKzc&N6AN4qV(HoRR@iJvE${HxPFxE@)wxlZYbR4pE z#1e0b3bCad<11TWR#Ln5isc7a+{a}~`UbuLQEYc7!nSz!Ze=?po^4$mFg(j2*S+{* zyBFVydYfI#RNXe#)=gtQw;b}^aL9ABrtobzAQ%#T7ey~y(n-ymN&21I6~DvOf>3&x zNaato#f+1jy0HIV3zmwa)Z}etW}kvUF3<#hYg6!e_~h7nO(V2H=)a-NuyR z>{nYEK~W$;up`i{PZ@tiyBx*l(N;JV*@kD{Lq(=&x^6mYMbNEu7$wv=X?rVu)FQ?& zZs@kuq=t+Ohwj(TZ{@IiMzaZIffEbjbaS}i3S-Gic(MmMi-DIg;ZiNS92BmhAN8^+ zpzMp6o!WhnTKyR?0^yyWd0eemR|fH?!$6>6ZCTl;XRjP$p@Ga!ddnzkCPRgY?wV2~|k-uB^A3 zOWd+8jl~-jM0hJHdSQX|x~p9JGIrJt`J4#R98uMS5=ytwn5~cVIO3r`w^Rvs+~z?H znz(c~gC@P{(eC}nvMGJUWKMy_7d1Yin@ZmHSLT!WNR|?0(aK*@Fk2`qEuBB(hCG?P zU>l<Iyd1)(3G7Y%uYCylDr#OE*DTm0c3}EZzhf?(!S@RjbeX2>`8Jqd z3a0mLR1MAk>M$cyB-gx*FiSUkUiO^>Z%2u$J7j>UFGmyM6kZt)oKYPsR)*elHa7R&v(`nzLyuZevju+632FYSc4`q zw6BSE1Mvt?ecN-Gqyn*4!!wz@?US0qTdIR>Dcti|*w@YBHo>%~p159Jm;!tI3${2K zP&dys!>9;m5nhl$a4Exy@Ypzc>^SAu5Aoo>u+B?vL@=jX69;|o&=4Td#>E6ND! zsw=yUhyW2v=*5Ry4Ai)dcja=tK%(I}l04<8MG4bXG8z_2Yg21F1ZkC7MWPE^0C0>^ zCFHc1tjsM_RNqTJ*vAc#5>Exh8Z2`su4uyEzIDtk3zBI1U2vNsWygbH@E8@|)IT~Uf ze4h*62!4twDt?~ffpoZw4^wsq=qkQ4gIS+PsPTS%`zR^q&T~ejwaB*ChZY^4=L$nL48`Rb zf&jDCL%l*Z0eU>*bKA!*un)v_MpP)WL)Qf)M_v*&ghU__s^@7Y1GWr|o)~a7QZo-< zW3`S^zP73{5ZtGd8mFC2DA;VHu@{5E3EL`&O+&Os_p95uKohL(P zQuAfP5XX1S{}qn$NV24CG)~4a??X6-uXWdfjBxnQOo;6wugu^WZJH6UqPWP-k#y*^ zdrhEWib*X!ljdzI$=(q9&GXw+Wza`;SBOrxxrqUSJ242Nmm)w_;?y1x87>(`(@kdM z2fDx6>;a+>ZT5B0=*dMGHPcOW-!eX<7&nnF*|uSPN8MnNc&BkH&wE5gH&Q;l zPR*X+B<+?Gy;UF`fj4-iSX=f4JPFwo;o~m59w;ob!?UpOahp*(>BoyWSz;zljiN}X z%Sl?l8kd@LyKt1I@xi7_fl5rqZ>teAR2p2XRR?o(BMPEmRhF&shL>eo{A*0nODD6s z$cxRCvR9-7X)?ahyt}3GM|RG8a==bwjyJgA)|T4bz1{l4(udhuXKGgq&Ow(GyRfFa zy2tbAa45?)r^*r(#cFegX3l%6@Vq{hOJveM&JLN*CNMi@3_MRV*~cMi)96%CU9mnc zg8>wW9@Ga;(0MU9ZoT8HcwWkHk4Lb;XpE1zIf%r5fd#FIL(#=h*ldVPq>X5&po54c zIW>=bqgOjhc7C{7RKldjF)6(sRJes>C)m4@9A&nLlyCNMCgt^l^7>nABr6=dGQ@O( zw@T;sk?NKf1H;Ux7RP_V75* zwF&FmodyR6L>;5<@8EiaEMH+EA1cD|yoyCk%Z=o&!t`L#Y|d7KyR7x_I^lebk8f%> z7k77m&gTmkHugsFhBPb&txrgyZr=*I*p{cX-Gf8#c`6YJCI4vwKgWF`SpqYBI9<86 z^TV~h8`r?*yOo_EaNr*f{Y&SjhOs1{yu3`!WH)=rn?1`>E93K>;5L;IbSJ-P zf(44V$xcpG3vB&c0rI8v#A!qD=RDVxoyIS#;E|K_{FbbH9XElX_nK+!!UNh8ZKAMz z=@ZG^X=JV=v0p8rUr|<~FMVu3>-^-cSM&J8%~&;bxf*0@eGY%!UB+Ulus!Eex9S{V|u!jzVI)PV4po`EG` zI1d%*Gd-G0O%@P36=+EmFMNp3h+m`M0Z*D^_h+P{v~qoli|}WgWR;_Ytv9}BXtYsT zi6y17kswZ|ePRru@Pmj@nI?ToTR+o<()Bs*6K?T(nQC3;a0Lgh z3z3YpWjsp{Uf02P!s<^rOm^=UDKPIclHI(WAw20fd${tiXfUGDbrcthYdak2QM;+q zPG6rW?s-V;)`2Of+mucsdd)Fg=(QSG~yByQ@5LJ$}t9zeANEUFG60>IO_|64 z6;YNR(rX;S>(q=J)QsmJWQX6>DS~#aON~?Ght&7!ID0{(h>NVtcVY2t#e;(}1G%v` za|7(*lUUTlmE-qrOy!{MA+1zj3l*qDsT;!uU|eX3!mZvYA|q#JU~=d%)x*&NZY=jD zt%Fgbcp`O~ep{#rN&b7VA&OIlLZ>4-@YT-0nlZ+&c&;c)iV**kY{ z-}?LqC@kKz#3&i*J|ISDw-6y!!Gg);(@ls9N|qk_S$Dfx9^J#C+LSC-3&*qpqoJ?8 zn5nE^V@l6hwcG>o_3~VMxbjZm+oD>=9y|Dl(M`+TCQ&2{f0fmz zR{3|Rd#iZ)m6WUe0OzWw2|&$b5?PjrXMF#=Ycu0MQPfi7r8OiruN_uPh zhzeKvjrWZ7NjDF!onw!@`;MLQe}$fvRrz$bl9pga142T(%$+QcdJ1f&=Ird#YJ9%D zF36zF6DPOw_HI0}o*l(=cuh;oQlyB#)R11*`+P0De;lsv?fF7c6k6yjm(qxBl@_C! z*g_?$f$^(*w_0;O3FZu#D-z3~Z^l3`+da%yZ_b_XExTD>4Chq7qTx=t`{y_4pimI~ z!9tspo+|EJXt&78rI2iX&diyz>M#;q zSpG_NS)Z@n+&VQ;L$c~^WMV0ln#JVw(si;kC-)Fmw!|x;!O7JG9j!09;GKt@I1)U)=#9c~~SyS|s zIFF@lGAfabFvFD1&)6}Irxi;t#HuM&CF>KLHInJf8*J=%s$yIv{F5f5pdFL$`036k zxU}mHCy-=gPeLmhJ3sGXo9d-`x?~}S_Xp{9Cu8P4dbg0L--$+&>BP4cDb zn9i7QduOuZrpVG-xM^#@?me(X6BoF`NuCr|(@gFTVkJ*6I5lV(m-VMb&a!oJ@nN=0 z%2DrRcTEO1nr_jq!OutsGiZ@Ea7jjtjiV%@O!D4iwCo{7~y8_WW$@8^^g_eoD zT(m?DsZpDQZLU^RsnNCH1 z9kdB{csFR;Y_9^+=B5@I%pq+$uxZjDqSdH;@Y}oy#l)sh$&@rnDXw@6)-%pZxTwrC z;`@f8_v9+fL(>X-0b7BOQ+&uyGn1QeO~fOk+Fnq&lzf_XAzjLKJL#h#A z_7hdghmOzTVw9|40bVcj)LD%+r1&Wcc(`PQ=go~{Sq`~jQm1GB;^YQ8y1{Wme#Gq! zW86%t1kPldT1d>QGrkH~K&>$?`rK*D=})eUQWh-0*j-hZWHxXX93tl65HYtv?Qs!; ze{P9>6nSF=jS$_ew72;=K@Qo=I=VZHUh7%Jckam4U@{BR{&#opj?Au^2+W)AyI2vF zb*hX)pW_^{66l_Sj4PwjReUbWaOwUnpLTi-I2z2XAji2L2HPu2)rQR2AvGqa5Q5_< z{P6=TO7doWO*Pm`PkeDcC>x6Ko&@Jt&MiOroS5ZO5KV7C+?2_ELdGALIpR1a$vB29 z_QeVAV9+fi$zCo58y8r-37d*%G=!_qzbbArvK6C^vze4ttedfx4vQijWNb%6UCtQv zX{sO36s;N*bU2tT=8Bd-xW#j_u4VffyBYhMb77iWbS_Myb1kBqnP^YvD$=#wo=&Ge zA;fh>KhV}99hKg^ksG$XF}1Aji^d4GQWIa=DMuP0-M?+7-lDP5li6D)CZE)$eD?BS zQ^GjY)%-s1s7o={&ZqBW3$v!3w@~+F_omJ?N;IWpS*?)2tg4jAs(p;{eytSna1sCV z$O&Bf@XKaGSMdQ3AH@|jlRHb+Lje6@{F;;Jljr!qP!9XmlVJ`Ezdw`IsBrZq*B16~ z!Iv$~)hSOkpZR=#wfRb}p6U3#Jk`+jMj!J>FAsZ0_s!IWKU5TPQHhR)TcZnG*RrZV zn^9VfdGKWJdQ7l;Tm(x(+ItEGLu^TzdKS|xm3NvTR! z0dVxnCAcPI+satO8=_;0b-aAKle29xXE(e!^@^b+I!-Q2XOPvfOP0IGFpM9S)JA60 zPTuc&T22MC44z#MGWwY>*nQkMLJW@FnbFIn@mt51Dz&;#)#(}~;USxoq z9g7A(S2M2CFQMtEk#a`1?p$1(xp6IBo0BY*^lmMl#HOgR>SG#t0jC$uGQ9JkVjM$r zxp@GGe*9&GdAaYImx=2MlpZ^?cXp=oPG$L#tVm%~HwRg?Pm3BS1(NYQEd(4lB_pxh zyOUBMeD=-C&79Kww&QlfycstU>EKwGpCExtlzp$Ri}*ObY$~?x_ist=dHdh(xc66W zM_f6>eY>aQr*5~d-Zk>mW2a(=m7+dWH0g2Ej>MB(E2zpTAwQaPRXUD<%M{`0+aCy%ERW4(qo@7 zn|$tPmyNQ%MH5*u#cw5kxHtgqtX*uy%yes#mK?uOXLpv*%trm9C0CP)>#nXMO@y5v zU1HWZrh8c|w(IeLl=ooJyM?`Ba&JPGNa+cpYSBuGFH}lY1)LHDBlBe>?&PM)Ir|vo z1x=#4+RD5{lcd;e!i4+Rtkl9|!}Kb^CT_*JM8#%jj~v19r;+@K*fH5HEA%jh-OZ#WL%lr=Y&vgotJjDwj_LdHHYu+ zJ0Wztk-V`EvtfTqP&`r^O5V~RGwtDnwz#v(m4@OGcQO%G?)HAy#4>W~)q7AIAmq>* zZc-)HQMfi+JPh0UeKP2}lRIu)&2Dl}t-jT2MH5!#bX8`H#ydMTzO@5qhpSe^`cpx_ z_DYmuAy(6*2X}>+1@pvPxX``mr1zr7gY|nQ8?@7dUy&flZQaQo>n5h5)Qr_1Ju+g` z$^^N~740g%q6JI%^7+VO zag~Pd_m+b+p7LdrsZX2ltG*q47N!1|RpFRZTae=_yy z)gL~)@#W{UcW&Lb3x9rpEA9Y5Gv({Wmq3(K_eJFZ#jxDZQqNX z&#QJYFWUcU)bG04>*%jy7sxH_U@rE+i*cnxVaIVg+Um^bs~Pi?YFNGzg{vr2wA{>9 zSHKKug{*)c!e8)c9m0S42_#51k!4fgsUL~bVrXAP{PoPZkmi#j1(i6bFvTz{;?H&6h`AfC|UCYty{zUfkg-!Hl<{U+N-9>zoHNIjC(nh zRWhMfD@ma*)s_^#7t3|j9)9bo?P|zLc}ZdYhtrwZ(1O0jR6JcJm7wIf6~d~0ECpR^ zuoL(fxTCmtkCzDc^%_=jLSh{Zjb^j zo}&<_EYqf7%NA}0I++)y(~Wki2Xr6}&d%tH;iY2b6*Xj`QjI& z&n?aso`?#ckm0a>cwSYDb6mxy3HU5gX7dn3q+DEBCY86b`2b(ba|`^sWxrrWmEmG( zE_lR*y~Dtcf^jhH1-N!O(6inG_=xaoUF>xThR0FB-40N8d2skJ3UGc}1)a;NUHb@6y zvubF%8K6MNLsz`x==|Cs3V^vaQ!qkmEmTv*u9704=fR2EPW9S~4#17ZVz6--;D#KD zzJ>``*ut&J(KR9C8tE8fki4cEmYzCkd+?bAk6^ED6Sk1LM?l{>#c^B z6Lbx=ai!bqO3tVl#Vobu$Oy1Gym`z#Vy{l{3U~CDX%BNj^c5~t@B&8D3}^|qA1btc zs7=tr{gk|lSQ7d*1cx5WH}RDam4P83#W@6!rpBgqxiSOo%Nirs<43ER1gDT>PgizD#d_Gud za9_;S-T8X3b>1C@XMtR7BV24B*pm-IJi8wni%{GCbh|W z{M2rpTht_k>lpJN`605Z;fDz9QYwVXYC442(;?g&mk!}hITP~Hb))7g!8ooVf?)EB zfcwf-SVWirm;AzbHAq}){qn-)@p2mDC1b7-LJPqKPPvMyd zp7|7>dEl8(;h6`X`4pac;8{rFSpc4e6rKg(SxDho0G@>u9&EU5ET-@*0?%R!&m!O@(N$A&^&zM+tqF3Eh&=?M&!%3H>$` z`kjP+p9%ewg#I}bx+9^xyP4oU3H~7yx-X$WWumC7a(;KEEZK-%>umC6iwx-~XT+XkUR! zm+ePz&a!d2{GhwoxLkhF)J$By|KWHW8<)?|_CFlKn4`t^KPWW$IGbO-|KS1(lV867 z;Zh14m(S1kKd3yp{A~Y&@{^0R{SRtTKF;Qs?|%*3|DYP>)7kRn`(MNMKd4K&bhiIN zamvTp_RIIbhV6e)rgG_Q|AShUkF({=_rHeie^9mZ>1_G({jXvBAJng0I@|xCh~?vK z`SSg*Vf!DHGfn5F6jbANLV<%Y;)teN2I)d3zk(f1_ea%(a1gvc+2d942i3>$1j9|m zUPOTVd=dG8m!YM?4>~UqevjwJXJY7Zf~c=?`Ao2e_e?al&Dz-Q@F)`rTaS%g*Q+Em z0CCi>*7kyFArW)Ilb}+qR<5UM1I?tnde#rqpx-|Yd7-_X|5Odo@VEp4uBlBU*dBzq zRyRf^rEmaFf=kdu15}7l^44+hb%4;`U^>Q{O$wI;<8lLll%eaQl6-W}BAkW zhb?E=9=0Qx*wScCFwW5u;1b-gM!jO(t)0I1=a(u0`;{P9MKG@>osCD??q)>Wlh@sr>ZB(O22kvttl zr*y5#p#h{slpyLxXK6%Fu;Vy~1W-6!Jli*=I4|3o;(PN=n!8q#$-@Y9tGkB2kT%O z*+v(3QNKzF);<{FWHG=Zsub0Pno02FYbT-SQiV%UO)lVM{!Op}7OY)bz)8H5AS&RW zq==JvI6+gu#|fIt^r-|@Nxw?a70LB3EV3!)Oz;6*V>7jdp$ulqqiU`lw{W|tjD5mO ze#a-cLkuYoz!IdB+mg5nThY>WnOY-~lKQe}Cbc0^6ttdAKB22Hb-t6>#JQ@ySJ3~7 zqO5a3qX_UvKcjTtzt7_(!<2AGkAPkwuo9JN8H)-6H;rojtPB%CnMVnt(=bERw{)KK z6%DjjY>d8op3G@{5vMtik`|zeFYQ&5?oM1(WK5`sVV3XmXecEhJPMoz`=kWc3=9U!eRn= zRMprLnsC%xx@ehk-eM|{)Rv|Roz!B;cT|f2gL0Y%_AgXpFm3pxprX+y2~sS?EaHhu zgr$w{DP?>#dE~cP3dem*OAgI{_&S>{XVb)EJ-^ec;#$a2mv1FB0y;w@lNZs*@De1KlI51Z zGI#;=DOWqI9dF=(GH`qu z7QpA_N;f=BmuEXXnw4oaR$5QnM{>%8N0AB4@xfV!i5}xTh5%PA2kV#xr?hrD{8SNC z#o=)H$rK8wL1yUb9UWmc)mwS>sPRIJW~^~H!!{eDRR;*~_j#GQn@X4vr*>EV_HW>l z<)WR+l#KHMK>S{kfIvtwvR#;7`y}IWTYCY1%5BE_k~l%FvW)StdK9Flgk>!Jf(l~o z2t^3L@Ckl5Is@c4eg)`E$#n`wH@!T(i4>#!deJDYli&DMYlNZrH-2qsjH!v=_+`-; zuN=Se>q%o>9sOPCQAkru!Hgc%{+%yJ2z1#+_wSqtn3Ert-HRVk@<4V=J{}3}U2TbQhT#?g-_#u!Zv5_(Q*qEr1LI zOzqd3i=_Nzq+e?`Qkmex!y>|qhXZ2r`;o=udeMg)1;{ev9+CKrXOS4z`w*tZTt#|H z50m@tYm*!P{Ltr58|QK8hrT?w@v3wZv(LXa)^YHMK4aKezmI-6Dxh8UMv5=N(-1o3$)S6g|a!Am6|D zsv$k%Bl06JGChtX^5cA@4$p|&^-J?2K8EVXP`}&Yl830;X?I^D;vYOznXwhIzw=`4 z*p1+S@`49Zrx&u*{%0>RJs=|TpS{TJu*>~$&grMI!kdxc!nGJ|VP-{#z8}pN1!=Eq z0Va%5AI@?^Sjp*K2&X%`1s=gI5YB+ws64gVxCgxggyL;R|Xk)s~ykWOfcB(SxAdOM*U~_?= zGaQ{vkyq*qD@)h+aMVP4lM}tWYM)?Xe*U)~@D+dcZyp=BFGe;P+4!%Fl=I6O#H|PL z^{UU+13z5+!S0zztUdx@2}=`)2R*po+LD_B^b@}I2}V`Xb*~zOcQEM@->!C3^t+hr zGFr`!<;!8^7%5i!XK*8gy4h<%Gi4o138fHpXT!_FZsnfcnM<$$&ZoijG&O$BK5Bug zY12EBAUe|8*74~y4xE_D*fc184;=wy43TKmeT`nkYn6wvEe3XX2Bv^R99l!&+Rryl z#&vAQSlpxgnryeoGM!1@4Y6wSTF9Q-p#vey?HaoAyAN8?pAk|Ip5I{;rN6ue%cC

MAr11%KPay#?=P%2<#{bD)$xdaYlc0oPnK20rq?=TO>Y@4<3AM*}*`F*Q~4)3I-l9*B0+d zQIgOa+9FeT;bQnK8jc2VP^BO1*7mcFCtqQ)sYPdHC`4P&A3ogpe!Rqp!2<0w6&d<& zdUTdf*4I7UA%GgId@P%R7XBkEa?y0VRN|CW2nKNf?7>%99Isd565ETf2e7v+SYgpv zTv>T%VKM(-w4vGT(!HECDU=7Uz^+#tf#4$I=oO5>kkXC`(62E{!reQ1g=*meq6`1{ z!N(unB|9ztBeSo6{Lz}*AqB9&!V4yBX+oPd3J%^8e{ddBQ79;%0ROzQG#N(v6n-1l zRZk?O@bte35mJ7`(-y{xMOR$O(()9RTbm={Tn-OGe}rN6Yx=0uYhF$;;^L*c%zqah z1ndAayWJ-}6tD-6-jf)^LOg;&R~)I~S8Xu|^s&Y$Cej#5ehgbJkyY2kdm1Ae1Z@Xy z@&^!4F$TVwAea^(c_idfQ|jxExm$|hc;mw~G;sHdB5(;mhanXbGwJkr}jUHXYqr7V1Eg|gww1s_N>gt8|Ypwk11T7xhx)FOq-Kmrnj7sV9BuN*D)5+WEx6{wt>F4eAvvzQ0{$`>aE?)m$ef_rjdae5UZuRxO z>g)T}*AJ?%*Q>8Ls;?hbUq7n8eq4S1r20Bnef_lh`nT%q=hfHG!Yi1-55GQjjVaZ- zGcon9e!rWTQXuWt_Y+eRu3HNeQ;J;DTAY}=uHU;8Q#bUxG%@v|ewQbvK4OOTr#{x( z%EZ(s`dyuv`c$b*pVrjhran^|HGf|FV(LphM+ba8uT31S-F($18gDt}Sj*LNKI zsc9fX^uLdd41A7`_+!ieWX){b-+=~pEOA#zYPMf~LRC0WyY^wvz){Cyn?>6)dAXmx zoF{p?pGTFe-BR_Jt>iBgb#=dXPD!6WL7%iWXnj?V)2|a#Un%LK=Ukb3WqE3PSt34Cl`XlB|d9bFEOWo3!^%HTb1y?GjaIvVd+wO>biEJCNIX)!D*B|gX2U> z7ZnQ*svyrgDkTQyl#=@`K-oQOpqgWypLNz5Ew+t-_Dhq{bXX#QY!VxVmZZB7l)v2x#dGnKZ zxg<4n53R{X?;NK;Gs$#Ddl*i@W-zGk3Q|(PrGv%3B^%((*6J!569Q)Jn+ItdmqX`- zA1tnMj5pQj_LiV3OR28PlcB848PcT2E%Rw;$F#PzwZ6BpIkSZo1lq`&jEY!9NyMrV zA9i*h%32r)JDT_v+a*ig*%{aJ^4bpmsSgJw|B-jXmKBctJalC&o+fM~@uk3N*<$CE z6@*V~o7L`yWX7J0ALU}3Iu^d{p!b|9kAP>N(P&n(>)pqBaKOTSLZ(ypZy8?0$1P;p z87Au522Ri0p=ZO{cDH^c-%tZ)=mp~@_Tr3?7p#8US=!!W8(j9oKS#a24q+oqr_X_W z1_s?z*H;+j((o`?$UX;~N(K+X!+^o;3aJ$Z99dfpx>C)ZvMyK82a{o$yuP@zi_t>E zy*#tJvWVg;gIZepy$9ncaAOVYA%&|07^Z^V9bcJ7`3KiiC%BDlD)TUB9(8Atm84Wu z=l<()vZ=lJ%-Blp5J@hjd(+U+x_IB>J?u#L%Uos17Iun@Y>KitH~0bIg|jTG$!pGY zaAo%cJQaOODC?5Th&fISmaPLlXA71VVU1>&*;!fK#!?iLw;2#;J;WXgcNTMW-#8;i z70Sd!x^=>dF#ttWwi}-wFoh(Tca|16 zt8Cp;D%801)A|5iJI?Q|Y_iv1lFtV^v>k2C9XFQe`vV4^hdlSz<{vb;1JgaP&dmatI1A zOY{J)f(WF=tzC-1VT2(vE31jASw_nc)rhX0bVF51of+3+Mw$XMWC{6qP+^!zRkoBe z>RYh7L03`U8qU4)D`q;KkucEZwqv@FgfJ@1zeaWC!$nAIRZE2`n2FZJYFRS5BaUaX zkEC5VuwY5_J2Q$%5m)=1=F8N3ds+#?LZ%*6go2{mYc`u@?qG)rq=QapXKP8?B&qey z(3A*?%iRfZNt|P1+rNI{PEL~9+!KAB9brcqrTdC)%erfd-A3x#-IdLy`&u~8>y%BS zYII1sWPo3(H<*$Q>8@Ph6<#x1(JS{jMSDcIXcKV;AZ2nAcOJC1GV9IQm#nHkf5lLWy+Bit3Kqt$)|$MD7Z}D5K<41PhY1nIheF*VQKu)WHjtOQI->EIDu#vf-8=kJkC#h@+4YQEY@!7)0R}(gqM)L z-6RPW_q5qc&SVnwWehWoY(dhHm|7CW|x+?YW5~PamD%yvDQF zAF^9Bnya$$N!!p7ELfe2=87|kkmd%R=~wvDK6Fz0iQ-UJq(Bi~;0Mxh*a{TDMc)UW zT6M-*y6B?lK0_fO;AHdUGsi-gJSdBYha@+Lfn)BQPkVOG03U(fwcGT;+fZj__$acn zn+`O?>_G&k7yS;5U{xsb;f`g-Qd^d7G?@(%FB93>#!QQlUw_fA5PSspR{?YZ<{tTztm*t)c#z1 zKFmxEL=##-SxZ$r}?fH|W zzc~AB?S-q)ygpn%&}Ge@f0BkZt5Rq%8!gQ!d&s9(qL-oNGhF>*($?_eX%$shs#y2f zX&9jx!RJR!!0~HnWz9@IDD%&3?>l)a8OP6{Z0$+wx~<-4%h|+gKeN4uP#X4Z(({tt&6s4En$_wNHyCAyQxeis$v(wXCAm1^xtqZdPBEz*;7`vSnt^*@*>-3{D9{-};$Bc!Urq|5VYleod8W z>Xyf1VF8^L4n6{r7J)r3uWuVx)c>%yBC!iG;DTw~YUS&yKDo1prnXk+A{K9TLUAR) zibfT;Plzflw;3)U-?;LUZtQ7eyMbH%OLcDO{R?~7z!?X+s@MJkOhUuM=x?S3-!x!E}cI+2ILG5NxzZNmwvxFL((?&#QY}9RkK$|R@F8WhlXj^mu7$Z z90UQ)8c`taxv8u^{RYW;WwrGD(=*fON#ovv&DsU?UZ{!G2~ESVENm{Ab|w#by2|sZ zhTt96UnP)gn@@<)ifPAd)%=Z5T8Jfa61PYnS$@Mu!m`QLqVf^x(@QSvBhBX}wdh;5 z7*+AQsD4asYQJmQ$~KX2LrKbD!NcvMQn;O(MP_K~d$nbC)m!El`ynBCs^wGTVa@MU z`%JLHR9@j~@Wii_Cv>5IryYfNA{>vKblaV{sn^b<)6+18aDiZkK`HW)P!z5aB}DMf zz$nlrM+t4)TIOljAO-ZAW-aQ&hgm z?xOFG@}*ajU(1xZhAAJh(JkG#j4W_y1I;NP6-Aj|U-_A1Sr}YkUhO-yy@5f)6m1w< zDyj^r+UYUxPINlyy5#E=%~jd#BznSDH7wg?y*;RYqhH)|NBo30^LTZv^ER6DU4v z)<{1lm)>Bm*>{x*HM7b{6{MM{Uup?bD03&R5pWOq*W>@UJ>o0Vv(s0nuT8%@{oeHZ z(;rM6;aRPg{i&<9+3VAvkQ1-Ill+Lg^Iz2y zJB|e3OtNy-W=~Dc)~?q+p~ScI^HbOPo#Mr+W-0q@>Ro@SQC(5kK9(gwOGI4ROqrsb z*Ur}PL}G6lmjVTH6Fl-Y)Iuu|_%)VXba8sp8b{Bk|He~4mrY5vCVJ0O1R+x)<-DSH z)5LidAgSHTGqj6mNoqgiWty!cf=4S|SlWmwJ5jqvlJH^ctisi*nx24Z_bJ|Kmc@B% z=|hKl4UAA_TFu%shg4rDH8FLFH|traqsn?^WtK55Os|o#+f?OUxg)oHZ~6tvcIf+4i1&mNItLt!_|@v1%ArdUQW6_{~Ea;}R>Il(kVK=5HVzC3(9& zA-Pf=7$6jI$oMZZ_B!fV58VXlEjuO*5Dz%DTQterHzf1~WB)NwPxRnazTY*t`-mE` zE8UK&te|gTyy<`JNnb-$=?NGl^l+%{$P>a!KVcM-Yeg)i!BLK~OHhwgmaWg-qYuIr zx+NgA*abx>!Ax0C>&uBjD8@oeH8+QHb1tpfx|M2w{RtmC62DTSP5U~DHhK~6{ZK&3 zuTypFj)a8b*}_@gO{bM(0fLKR_eR5s-n}kQqcwTJ1_M8P??3Y46Mn@pfMlAyP93g zaF;S-UQHl_736aoq?JsA=b{3|(l8XM0=z(>mkMJs3Q+WAp9O~xr@_WKbdb0#vwT85 z^SQ&-0sPB;g~QAStM^rJWo}!&3hV6kZXFi#$D!zB`})JcEXnBTy9|sUt-~2_7~mtC zW6Z+Qd<3Ql9P0@#-a6E69BO<&==6LkG`;xJp-Qob^xAe z#TgwtdOupp)POV=A@SrNy(a8^L$wp$IF1&^zkn{{ikIk$-LS~U-i^6Y zt$e&+E3pq|V%)ctvM=N}<$ePR*aHfNI=A^5AC4>LjRjS!bua58SpCuy|IuQ}0P%gyj;DRn%8S)!7reZBel!6}Ebz z4}{3hXOBY`(ijE8)dyl@PgwRV5|BmA_B!8sDpC*8vt!2&J(Z0STU;9>60I2`*=J4H zY;|NKTyoPXN|$6raC?nTzITd6%F($H>n?|eDEHn4S&_>w93UM5cZu%J*f(^Gsc&BZ zT@}&StY5g`q&#;W987F^S3|b6kTHi0#IT6_a6{Xvn)yc9Fd705 zCSTGxa~j}bF&jetFJ*IFL>x1Ql^L-`NKAqZazY$q#-tf@Gqc8s|CYzRc>2?J9E*(I ziG`aov$gDi77Cm${Sj%PiP~2FGJ;M@J!0uzv-7u4jbKW z`WA(hX(VgOqgjh#$m~)9pAKJUHD32lu@qZRI$s{~sjHJup8Gu$*42aSp&W~~brBH_ zsvnlh826Hmi8mYx6G+4qtNod31M|iq!I?K{Hv7y=K^n7co%Q*os|{ieU78#>`}X$n)=axW1{x{B|YE;KpSGn+k}MugKH~3sYA~Eq=txQc=|@fn9^FMm|a;gi5;;wd=Q*!;7tg zIw08WoQ$njGC;u)OeF)0|LB?WhD_J2w@iu;o+%+)mX5R8e`Yy{l@690gr6qCKsGIT zzkZi`q|#$X={^X)E`&Eu!JSeg&+*<~m^^k%55-CVAHkyjoV$rF4B*ErGY%JY4EUc_ zTNYMhMPUC!FmDqW^i^xqh_U&J=#>LrEGPVlH8clH(22aaGwL9X7EZbPxk_0a6?9fyY`W*w>P1pkA&Q#-u;mNLQH;1!xpz?gaS%%b>wp42`dU;Afi z?`v00@6B^4+6F3hLUpvqg8Tn8;B|&%wcV44bZe{6$76?xEa6e=8*JV zK(rAaItfXP;dQdE9?dJz@Q?^OVv!iogQLI>qbSL2%raKVG&M`BaEGFI)CHoi6D=Q> z*9V<2yYDDvewLwH4XbG+$&;}X7LJkdWEsX*awS#*y^gFT%P>$0oeiAtPOPLerjjhf z*h(J7N_^mk4IEj9v6UFM18&85N8z@b2UCv5NrM4Jg>8*U7+P+%p5~JgbjXtluabTP z$g<8b)NfHL<|_q3h`1B;i78a`fw6!@aiEw_)4G~3TXWei#C(Fdk`H;ktgqLyd=rNT zGnHHe4`x2L4h>}~+xwGed15F_DF9D|Jobx7fE{MC6)M_EpUwBQsPbHk&+@n%>j5UG4Xj>LA_KX|Q^Bs7Z+f0^GrGwz8J^;Y_^PE0$pquhYS;x)VL2uRW+^Lk z?2xS?D%a*BF;?5GSi78Bq8=|%OC|nf?Hw1;d7+XsAe9UiI$?#L9w?;t%{1vmh})VV zS9i+hQpxig7rAZVm*v4%&CV?|vpvXSY=nv{!w1Q3S%A7OQ zDMill*~vYeHQY@i1QQFPyYLm{oXB?lOuMMRb(UgwosJI2>7d`*W{f@7n4e#mt54pM zXLh6Bsu#g|;!LY(atUxUQ-A>AA}@ca(3AA9H7W|Fchcl}DQ&k>=r%PEEc4*?V8`^Se$@ zJ<{jX{xo+kt3XMo^k?Md9%VAKx|IeW2o}-?qP}e#4V*@t%#Ld^|b# zSLjcRGg;)WYoO&AABN4x-Eyy)^FZcAQ2IK!(}E9TJwN~K$AF_7#;Eg|&>3g01xe$# z0R5~0ot>XQgJ;Y9{BLXcSLkQcj;iwX1F3`-vjMYSav12>H3HS1X%on^v9a~T*819# z-x)+ED!P1`V!{apHNdBZt5F}8VjLz7z#|*$N00ugA^82DSA4i1{qu^D|LC7K1f=Ta z(MkTwNs>Py+uS>+E}Z`EuLj_&RuhL6bhwDoxp?{1?5jRNa=6sk^4FX%qbH@oJ$Lf* zEHM9e3iu81rS&!C=RN~nHAcH?^3h4Pe)6OsnGG--a0bcT+{MN9&Ap9_ckY~b4Jzi{`$tHP@_@yBO~44{h8XrlQn?bSn&Y2B>Fmc*+)Aa!gUuL zeX}#Q!o7`~P3qq@YRlZwZr}MM{4l8H$47IgE?m4a`_83v-&w^MY%F(v=Dq@uTgj?v zz#({QxxhIQI||ZxT~GJadxk;dH{%qd`^(oCA;-qgdnz$^arVyKj7A}#{qj64E$~C* zk+3jQ@X4|>XqA~?9j=_C5~VvHlamt>XJK?;m1-8Z6;)Lad-pbQW#!3lZ|8v%lKkb& zv1i>_*}cD|tU89jjSH^v!MO{tKN2rpu)lNPy>sUrV*`^S>96{rKYz91`s>_phC5p1 zW;d>LSC8W)!ZUnp{l_&yaN4FEY){X3_%lC0cY1E-oE4s%xy%FeQ6E;fS61YcW_`It z{tj1m+xhCoB|bA%=1$Ej;~f7(O)2dH1gA8{aBFF8S9EjAh|B0#Pw#*BwG#Qiz4(tU z;cHg(K5H4A^1tLg9_LA3i?$w$4~jV^rsXH*hW(sNFD|wCu39sPIIG1@WI#w4?EDn* z8g#CZ$@akJ_T1H(Z<{l3eQ(o~DS4*B9~P;zj7^0mFI}Y2MU8^c1sx_>Ida6gB@UJ> z;a6EXPYKcNa)11~x#EkJJD_@^%ZOfgUI)pkqPQ582P|RK-sjYq0~zDkdNQp>asxpFGRUy2rT14JdqnC8u6J^XEBov@Qjdu^ zkcXNH18Y8xFui)|qxn6nDiNXUwgOka_}K}@>C$N{PKZ6tKiB|)Vswqz_pE5X#*fRO zmC$lLI-NCH4`N4sXX!q3rhHWtnVtJ90InP`lEK64sBYC48+O*%Mn*s zFL)){yyQrs4{F)FIDli?%L%9o`Pn+(a-!NG-oPT!%p2wzYxV8aUw^&MDM&HD`kB)= z&+?vuV|gU_n;&oD9`5vOB4CUhfs_Z9!!d~*zm=p*r-^lI%gY6Sx>IlUk{fNe^H$T{ zXo;$P(+`SRw3&GN!otOFy-|0Lvaf@zOAsY=!=AFnDP1(y;S~m+Az{BNWi|R_{AJk= z;tPA!w0Y8UcW+KC%&*?|Cv7f|vHv2Ic7%K*g&kVavHS~9D?{ygnZxw9Ub8l5#nFj{ z6XYq_0@qGRg{uP_Xs%F%wmR{>D@~R(aqiR_BE?~FnY^id9DOPS+ELTQ8`P|ApZK61 z@S-28HC$cmBCagHc*g{C$VLK=52m8Yqa>{_xh1^}0O|T|FX9L|D0eNf{;r4S5`H4SDw8-Jpfw=fHH6li=pw zYmT|Cmd?;Jcp7?iYa}k*T*bW8YA^7o<7)ErrqxoNHsB|u!C~mkbb1lh$1SO>isPQ# zv*bGy8*1hYMWSGMMQeV-tT?`47Ef~POVd=+dhrw9UP2Hh3Ek4It;{#z2m zyzE5!e}}}1{|`tklbfM1W($nTPZBeTtuRW`AmVliF2v$BrR>bq;>i}%>P5mPfN-d`I22LE((m7Qj;mXqxj6I~OREJzZ| zt<|y6)yq#zd>9L{;-M!TEY<9Id>=KS`o;K~Juua3PGZH9 z4jS(Yf!thgDh`B_W>aGy$g5<8qSj7_OP^@WxY{>~!6?IWJ&1?pH@F zta9@WjRhmxO2M4_5yOQY71R+N53tm}A}-3CFJ)I$QU|;>f*MJqwa!x-mTDa)N{Q|` zwvk0=`QCDd2~e~aPO4$8=Iy^vr1{zR?+pJ_f%oDMX$3_ph0P>n1SN^`jJ&JO;OILD zP|>QVws`1_ZcfF9TjwBbZ4(7 zu7F^fc&){@2P8;IL(t)}L0)_@Mj=8D9r_BI+95!wfWJJCpQQcV73ep&?UGQ{!c-^rN3#BD=D+t~eHOL1#v%X5Zq9 zFH|HI1zG*Id^f`F3$G75&ezQbWnluYymNNsO$Z@? zZmQN5Ov3_WZfvv6ZiCZ`50!M|%5nywr&Y*2+MYskvt1?Mdz0cpTD73@R`cWu8IIep zv55#dT9}e0=V@<}<$LC=Ri)XbU8bh+ zbR?Px!6zJkvm(VEX4WMWttDck!%p@pMRu~Va59-BD_5|8L`5TClJYOJ(FLu4Gz$d- zoE!ei5T40;P|-M>LO)nF+#usNJGazD9sPijDcMOPG@0fbT(|+_*R8DwQnCdD!`U<>&A&i;>j5PGN8|ZsLmNdnF=r)x5N+_^w?@DVw4ev z;ytvQNK&lD5Evp`1FGn}pk#Cp1d7sXE>he)b~`*7tr5m<)ub?OkUJ)YrN}G21^3}m z)uKt;giLyHsrM%)k6CU>Rn^b8PSpM+RS6Iv;@Lj>NK$@8O7!lE{`^TAhPV%`yU|l0 zo2Wm;Lx=a9iQ2uqZf_hBJt;L)elyE?5~n!Ry`)f|mT|PkO^6>aN_h*?fYcc@f2*iV z;+TOzAu;~T0ESvbq{CoomSo$m#*7%b0OiH;m-*}esEWVmh zE&6J;_^4FMJYFq%#cGk00jp2r{UI_6V)b2oIi#N`K0It65J=o}^B)ts3I@Ltf8AA2 zx~5(sXQhZlbVw?wXY2x*SUZi{E}bC;>EQ^lBYQr{1Q(DI%c4g^~j}922psviK+*^UlE;EL(Pk z<10dC7COZbi>I#ht&X}wsOrQXclHJ<`Nw{h zBn$v(NA+~oJFsb#sWaDQhgfgB!jOF(8u@POD`olyLpLYHUZpOOQy#2Gp7+z;0Vx7Q z-ElCG#3`Eku8#?7LD9?U&rZ$L1;B@TDA(*|nC@jTcDvTyR29|gXn3`@)PWbD5Lsm% z;^_H49ol?C)rFQ-vX_{`b9_pj8Eh|+@eONFw}dzr-k?+(2~c2X`3*lDqAu&>i=CLz zm(IIZhn?EDoI^uqr}ypCf@Ljd>bH4w70%U9DEY;!5B#Lr-p3de1@9)L$9b>tqydP75r`LVL927su)9ezL$b2&t0S?8lms!D{ zdP3rjEKvu|ON%uA5Cb5QiUu+A(wFPWXI0FHvbG>u_{Ukz>cJw0}yy@=eF3)AH=PbXt3E zpaMFwsOzU5DU$`|GjR1W2RH1HD%+<^r&W8t&B1znN)62M*IG|i^F?jW>5sf`$YMDz zU9e>Pd+CCG;IGQMd!u$&05-eGI;t+ zFTXNfOt+^y)7|Obv?(7r`SK=AuoW~7s>KqJ3|b)qp6e|ZYHxlG|3Nz|p2`27a#}Gy z-PR{06kG25N304{)W$^VYKa4d5|?0vfOK-oT9`ujR>U zczMnKjj2xUEfUhgDqc8IL-CRHqrAJJU#0m^@Ew(aVY_t65;#!8!U$W0r_S_6vQ{HJ zDFiw45#Y94sY6o7v_rHdH31@|cl8jXJP^JjwVnY-8P!!hTN7k-!io;mU8dtRU}|d6 zgNQ=^-F#-n)aQ1v2OD@ zQq;3fy95FGhaQir(zV+chrX%GG<2WGDtiZ2sbWc5T@A&$&4Y^3xvqEaca>2DDUB=Q zy3s4wXnvlm@J*q0$frWLQ{y&o+buEyRkWy~6hXF~Up1wilyHStZ_|g*nwq!B!i4Dh zeTEbWQvhUjTZa~wzoHFDr6_8mE`X=y;4TbYgsa^Q?YzEHQI;SMflUo3!5c&hrm%X=Is9u|8({>us8=Hkc zq9*riB|0zj=9!;nQV{r1Uzy_`B3g0oOfO|J{yX|6i&cMG_fS-9+4il^K2nQW(Yp4o zbZu046dnF`&0{~agu8~+@9?Ce_>4aQUcAL7r^VU9k@|mO21ub#|eznU;BoIl% zRpV*swb{T_4Hc}dGJE(9dg}Dz58Sb|zM@C0MxK)g-tD<8!V`&>IdcYb;?%_r`CK1x zxNl1IHJgPO%xXpO)rO{O}CE`G6F3iqC2ENEV%gA#D&Fs}{2#CI8 zwWRiO35;3`VnK)6d&=;Q_dOW^!Fd7@xSxw!mgOth6Kr0wbfJ{;8%>y(o*`V{?T#l$ zN>ltPL9E~g?kEXG+m*VS(5i>k&vXR>UCd@!&+qWrAPy`iv8#cP!5+h133a=bv~-#E zDx{Q8JS-&*Udb?S8xb4BA`$pmaGD$#1$47{hfMP^z!e+LIc^ za*GXQ)UkUqY~jx6k{nzmg~_(8tP6QJMfkUvo<4`mOPCrJz|g7#C&or9KI zi$MN+@TGkb3$~fABw-LmCG;`F2Zk(U1;~aPNW2hbopkm!>9paogo9rk@DL${YM8tdpO$lv}Co_HR zrRjGqGEVz1N`(*#{3^)iCTgNnknBWh*WDw7nL?n`M6knN)tJ4iyi?bB)8^KsLh@+K zofQMa1kXz7=$MwbcZRwc1}M~;)i<5=HrrQ9N=q1;Dq zLH`|h`pjF??EqoeIx;T}qX*efii{B$!U)cXth2=i?;{XYn!J9j7U(?SJx&)#4X6|x zvI(}cO9RD=M!i*12v-bkYUg!h} zX-hu42=xcFNva+nH>q9hxduxiJdsYqNB-4#*adrN*)2k`Jd6QuMmUth{Cc~9zDs% z$|Q`Euk+y(v)FwaL2WChv13_y8#7^2xxdA7gKOgGg4RznZQ82zXQJb>xKi8a+|B3Q zp2iada*ffqL9l)CObZ07UMd36% z1I*GgJ3p@mm`_Opd(&|PWT8?e1oD3jfImvPHH`l&fXzf41d3*hh|EJID(pK+-HfEs zX#z{22bL$E$a9OYEOIv@g^Oqv7}~~9Vn>IUqV=?l&1Jy-s_?bxiy1j8a!NuWJHGx% zGz1a*-yAL3wp|bAVT`?-x4oMae-xnKOdL5mjFQLbJPT&oc^pc-^I^b8_mk#03E;El zSpo=`v@v>>CI7cE|LZCLK9gMZNFnZ@je?j@a-Xs20teCq0I>cv!~+x8rvIIU#(x^l z9F5;aYVkG>B$uDm1I_hfnnT8^txSOSb_RswO96V{SfBh7qD`9vk^ z!L5lK`nl(oy~Ae*?g~#CWXf}YT3 zRU3`J%~M83gF|Xa%cF=|RAlei!wBe70+c$(Di5Nxx|eeAD@I7&V;=41{Go2biJXhwD(T z6U+73y=EO9CRwUVpoM7Je<5DRSaOZKe+1n?tk3YY53w>_WeYur>!ZhM;c{x>oqwZ+ zzPGUVI4#^yEvy~Tf-$X3PH%QpG|jKLUHQ-Cbe3Z|2t`uw6UKY6y)MC}|CjBRoJ0E= zZ;x>TlEe;R(j2KP8}-lawAd*#v%2P5W|q_e7CV?fY&E2XJH3tb!xSX%^2wWob)Of2W|P>Bd6j%jIF)V&eYwW{J+7AXHq1;?Xm-@>#U z*rw!DjQA>JlsE%r89##7M^i9*_|;cus3>?a*+rSb&SjUMdR&qiGb|azf@7*ocH`{9 zGFoAk+uQtcQ&+5p645FfVw$E3hdff!mtX)?gwCBAyC+nq`GaFYa3a8kcOXCZxRBc% z2ZE>W?{X%P=YoDI6#Wvy`AGMZ;Jdj>{BnOqUfN5$+uSefJ_`+^oZ-q;|Ly$izlE@r zyt*famD$@Q`j{ejE-lLE;_UqV_X_6Z@lkmAVQuq=Mb&0a>D%rgv`gZZAqNZoto*dMD4^F?33?Y_08@S%mWAhy?=7^GFrny|WlDSjh2dixH(~ne zK+CV>iaLwS@O}-_l*(*8*nMbu)dE#hE6I6mNBg>uw+TL2b9D=x82y<$4$n{}RUpmz z#r>MyUyfk`1_kQ!C;r-??GT4<%>u0k*BKQW;ra~Rq2Fp~ZS`V62v4BgMpPw(pEV&P zp-Dgg%1Ki`Y_II@ZHuIgr1^co{lxqTO}{R!JlGXjYuvQF4#tFL!_1K9*T&lB);7*y z9{3CDEIo(PBnSa{A}v{iJ0a9?NpK@`?dL;N7WHr}qw9C>?e{$X=d#12!JvAD@xTc|~&-rio%2VwjHnex`C%8G6L|WDWdt*4o3-WSMgo0YoN^qDIc=PsVVGeCayF;BS#<*#!&wm~X~srwh#Ht}oGk$XU=t&4j* zD|c5GMG$&}Gzl}Oh@`kM?(Obe3>O_g)T9juLlg*kG&qCM05up&^x#ai>ZCwLfq*%* z;qy7nPMa0L<5-SwK&G&pAylg{BUmi-Dt-6Rt9tOzt2}w=RUROJ{(9&~9z66a4>9zr zw^KdEBG3|p(VP_;2!wm;y9;;3mMUoY{ye^*UQ0N$LJ)^WnAd0Omie{$22Q7E&-2o% zzy8KhVo`rxH06x@x4ZC(9~&h=)^nvw_Vxp^fkQinz}@KyNRq$i~h+{u0k(af9C-tCokd z8sW;07a2-yl>;l=96^EPf73e6k5vtH1l-}xh!CWOMKRWu1q=WYev!JZqQ^;^%Yk0tWSp%v{VmYI2J_S+_)RX0L z@W!&f(Y(g0H>v}nvAGLZ1Zd6|4cT)S$J7x66Z=Uy)xty@;9_e#Gm`06mhr>FZMG2( zwZ$VywklX)>q^UU(HL?qJm}2OKy#!0uyCV%o()DZd6&QJI{Z`#LcAFZPkP9uraKtF zG;!qCaYXLo$%!L3!^2s&>&^Dp@^_FVz8O99lk;!pAnUwbF1noEI&0puck1nNp5BB+ zm|0n0*&rJBPJJ}+I@}cO0zl6OVf=rAiKYsbI_Tkif@onn5T?u6k zPhG>C2q2!8tCCc8!F|L77PLB3R~MeM{i_9)vOteL%PNCN^8>jX72FcUU%Y9jboEg2 zCGIkY0k&zLJ&tGGdmd+C_VR-wV`v|}~uei?b-O&w3SDP(Cr;EAGOXF>E`9%^%GHg4|HJIS-AC_ zs>@2?ogzP~uzltuv_{Iptp#u*I&PjMI?(j->5pSggaiqP%{l z$kJ=aZ<0z=g`Z5a+{YQ5*0=si=5?Pa*R5E%d@uEdta8M1@Oz!whqwnrq&ORit~syY zP>W%pIdw-`9}}GsM!SD%>e@otSBz@S+Pm`CDlAH`NTYqIk^w4tPDr*x{8H?i15L9x z{RwGBZ5F@MDLuBI=1-@_*uQp-G#L;fNM`EaxuJ$M0=x@SX#B#a=*F zB$&^Iy8DS>A_=W!Dax^C#WB$u)%?iSOT-tj460fg(g@)(CAf#{a|VtKwb%h)kUVVn4Sm15y=WJ7e9zgRzJ;>ZR>vN! z6*aQHb#HBJn>&`m^*oA$-fq`>g!gQ4fPc4oj|l1(cBk#4-Wd@}FTonSgi!bM*4lF2 z{!nSUXyc5+Y8wbkTN@IZXza?b8`_5G_M!6g^2!o7oh(XmM3$3tOUsM9i*sbVbElHe z(v^d_?y9#^hbNt__lk^sy7avAta)sHB{p{*2(XP>r zR3(JZ)`_wiDefSFjkVpnpQttBR`={dg|dTpcBnEQh8b~)(n7-<+}t#w+e%6#`TI<{ zjb(Iq2&w3LpEBQI5QnY1i`(0a581t&_OHC1;(|XKfG%@5BV`#KJjEh(zC(*2_9?!-cUMXZ|JhmjX=Z1OdCETGS7;hW+&=O-LZ5GU zEHrWufsNn%8gaHCf*ZqtH;lnlC%BI9vDe$RsW_su7zDWa%I2f6w9ceC_XC#-(P{tD zW>Qb;>@fLJL~!^B2vM$lHQ>?+mG@&%NknC=kKaodV&WJgf3SCtZ2ng_#;x6TlK)Bk zh57N*It54F8ld@VX!yxfpnb4<<`2H}2QBi5I8ep1w4FdHS8{D}!6c=^M6+ zwZH$v0@6&YiK~`Q#>xK3&d%H_+qWksZxJA|_Msj7RV3h6(>8?tsVkCrwRbyKyHtC- zc9BJK_ODOP&-&N9}+~~6lvF~$OA5)KcsTw5f~_8 z>MGI+&)S^(fKOebIgP=^veAI#D{8FWw!QZiVw=(avh4%|ia)pSz6JZd@;xG$li(%1 zjG1lVKusJ&-p3C4zXh?zFN`v5%-~`gWGP_BqL!RcmmFj~bqlsr=I;%W^txGhd9~v) zY*uA~<{KG}>ZIlfL(f>zmpHPjIGiXVI+@|gVuS!0^r|GN{?fN#e)XnM-Y!&CrzKh^ zL}{{(-R`sX3r4%CpJsKqg@mkfT!bQ zchNH0)?C1JE|TxDC!MPC8SuMT6Y<*looawfN&&%j!y=J)U1M-3eKVNJqXuhs!#O=1 zJLm?vcMWoBT8rttR44Wt%(U!Nm>u@cURM~6eGhe@cJ@>!Scs--%p5N_y%${3W zy3ha1hxh4G+mv&@7NCBE0;et+o5|+Ans9R2)kfUo3mUob{@)|Zs_Z%nif-F_5h;n0 zA?1J2i2U|7)tZEhLjw~K&Z{~ny_5Rm8Au6a4QWcJnNxC{9z90se*l)zbLSOXzXI>$ z#rXM&Y=t?&JclWWr)#|87#TqeeJKuOdq#@{>`d@E!Rvdd`l6~)1*u?VX)zpq{s%*l zQQGI^C(bbl>9;OFQ@cXB&NW+>_cR4n%{8{g;xe|PZ8$q(N~8B>+ShKJmo}%eC6)0v zZ8Cq_!);-?ZlDps?g^ugoP2kcFlS1S^)2Vams><-_3hY9vrZ%#;Of&9LF##GYTMe%>Ihw>xWKZD zb$j&9;e4x5L?r%;oX%T zf@HMz6=g$^XNSn>A$22lEcVo!&3l6It0*0vC!yD7@3_%6F*j{#yg|HQW;?Hl#R~Ay zhexCNl^5PB2HG(T$W zsG{_W0?_W>Fwu%2ZhT5&t3tKuqw#gt6EiLpZTe;!XfARI8Y5VQQMr8dFAGSHCS}Y~a&ms7>D_`#9)o)9B;}5kT#ZsR+thK`$JjHFFvo zrm;lEzQK3pN>H6C_r8uaet-BuDwFR_sWgL)ueuqIx-nf2{-(H3U;Jpuv{`C*;@;8b zc~t%w3vlLeuH+ZSJ+jFar&2zNjFX^J86Q)}Sa7h{k1#vd|D8DcY=5-z@i_Y2%rGX7 zJ`o2harC>k_E;Q!a}SL%Qkd2n?q@_%j}=G%_YXtVxOtH;F8*#DOM*EqT$KRCsnZ$^N(Os6~gb z^ip=_tcx|3s`T%KZ?r{2Hs15|Wa$WHT~1nJkIv6o-ae!;ih{qa%bj3xGrX{m&9GGM zK=qAE;?}Qd7t$MaTP95J*mGgqGeGiBZTs{u`_w5vQOLt*XeRIi@)9^2DF1`Ir*T6#hC!C^|Fk^yi#vy(PW zi$1VAmv~SixA|*G1y}EB4Oy@6A!xz0X>kM)l&lQ>x=rqq;IwraIUu1ujM3N!(?wkl zL%%+K!>IF3AQGhgwsZ{vQYBWY^EfFPsR&Sjv8th%RPZ&j^}7qa+Z6tmH?y%9(xJqe z6v|5bLxhCXtcFQsZ4#a5?Wl=EXH#EGbnV!1l-%aFO}v21+l&o$dr$=*oq@p`LiDh>a^c@gp# zv1tWvO;uLE>$rxisAA?IET{aRj|btE(6vhYA^+I+V|}&vzgD02te;=l-!CU>?=euD z3#UPYSQ1OwdC{??&m>5g2v>%t$IvSAfDJK%r~bOPtyxYyChCj{p<{N(CT-yIy!i8C zY2J`^ghd?tNr(Z@!-AY}OVfzHBaIP!Uf=kiBC#u<_TxhpkO^19(g*Mz#Mxl`N;T1> zLb(%6JgZ)byoYa|H}eKGBR2L&-2~YxOadMeH#Xb3C*f*1Mr?>K%e80?I*dT=(d>i0 zNQO9!%b80$?!_kmFaSTUJk-T*m3?`DL)&QibYt7e;08&4*>Zx%QZh$9+y4)ajWEj| zo(t+MTx~Ez;E#QoSQrI#^sAA|N7gNN58)R_hvr9jy8HS9Y$9z8G(q zB1>0ICe*^s=O>RCFT{Bi#?Y$;k5bpS6XPqNFF4! zH&o<<+r)1)-Vxq;v-j4U;zC@5)b~#&YA>9q zy%0XI4Ok@_-Er!dvLnV%BC3TNh8#GNZqML6;fBI zswir7uV}LnV-iHJD!MGIhzUB{$azizyUeeie~J>u%I|X+j=K$)jNbJt`rlbuw|D*O z{pZDP!?khp23t?;)oFGadAsZHqqpIs(om+4@_$&{yf;IpmCbTLOQ9ifZZ?Q=cxzUfP4E{l$m}dr(R&Wy(Sf+j4C_HOt+r z@9u5WvEBN+H*eOh-n+U+eQ|qjW#|0pX_e@9DHMft%N?xr$%as&-5zM3*`^tWesIB* zgPoe@RQCv~1?dPovV%8!N6P-kO+{>JTXxqj~TJ?@WYy z#32qyXw%dX_G|`lQIX{gF|t0IIO^AqBjrHK^=FP8HTeOFpVRP>*iFCTjkcF);91e= z3a!T+$ds~L1{f&Zat0Fa-u-Q2p@f5WI&2$rDCi^MtR0Xcxbr@gcWlZl8VzIvNZ2EA zXKjGWii4I_&6a3Y?Xmk?1?ttK=dMw}*wv`Pv7qZ3twi&2{01WkS2HlK<$Tbg)#~S+ zyBx+CoMrNCdOJ%TGrNYP-&gD2R^@XnvsqOJbT*3>lz#4apV08+PU6XLb^Bv^auOrL zO5wCCS`~rv-yA!{gc(rdv)bb8!RYZM3r4GO3qAf7qT&-8d84i~Mr^z)dZ5a+S27sGk9R;5(jBt#{i?Cl)PCB-p0Em@ z0RZT#;97G?{lvss=oLy^XGZy?*o;xu(RS9?(lO?>&ApW*a`>&5Zf9*_RojiOa4DPh-SEXavDcxHD&>5wtFqJa(W76UFcXN>miZ+{QbCtd2zj zkGVT{$vP2~SbG7Z{@k(5S~p-dBCm zS-N1i2^WK)(6qN&(e}XQWO&CyePzP@suJ2EA(e&)##qH#y;qMNxpgXzrb~iIYI0C@ zAx&$BKZ!F0fiA(`vUPM=P*lH_U%#qBzg~I5pso`w&(5Ue5@UE8V!Ofv^l{LeGLKS+ zM-1ECu=&(#F?DT<26~3PyTl|5b6LVhvuDahODt@DENBY1=U18BOl1tVpbsgq6}*2m zbNXo_%_|fVE83futnsqBbkvR~F}){`Fc+K0qDe^Nj2lT>W!jOO%2dPzIKJLH$8LEk zNlKgP)>)xhDAzt9&BHim`sn!gSvk0sgTlvB_gE9Kw#zhUj=Uo_3+0&WDW`@s*v6{u zURm4Rjz27>8Ze;BK~V!-kuq|bf+0ZFsL1`|)QuNj1g*{XpBW0qQ<}cE-J;PpdHx5k z`DMtyQu28XlbH&GADAV?eDNE)a%DEIJowGcC~a;i1cp$5EEnqhIyHjM_)5w{2oy2m zmJ-@H&j&!1r_4m1NAern<5V4YcW{Y)EY&vuGy*bC*^K7bY{)TDziC)fS&iDj+OGvv zYdrtQ*pb6nnWylGv7&p569nxVE|06fmf(8yjwN(Jg;rQ3Lnd4LE?Z-aN+5KpP#`2D#8@!$pN<6GARt(S+GkZ7Y|`MSO$qyiPBugw z?@YX|4n_3meGRN7ah}mb;}okwNdu*wy@%n@)`}f)Je5CV&f+U@{>LD;cWUe$lXP zDS?rGMM|r{`}mf-ir72hc|#FLH*UnSkrU4b1p2+~vqK-$WGdcl|HWEVf;ZT)gx-lG zp&kiR+Cb?df>pmX-d`$^vvgm%0+0@4$beu)wNe9x3D^0(gho*QIB~?GREEJ%P*;GI z8iLb_I(g!V?E-!P9O~#Q5~z92_!B$0Ycr(BIhZD#PpwERVQ}^#k(^7ifE++7)Vu%6 zY|Z~yw9&Z$h8Uz(3AIKpVeID{hB_Os3t-f&ATyOTHntkY4JBsuRvk5cH6H2i4xx4| z1c4h$^TmyHVaO!(IhPFS<#@4d*?7q|p2mw88?Rq|u!te~zZ|LmdVJC<&XOg*p-J1} ze|KfUcd)2jc(o-5Zm(6g=cqYyGmb~IT}KakS7_psF-N&lIZpEtv)Nj5yOR?~CQb0V zB827X=<=*xjklq+UdhpURn-?qPR7lN6iRXbF+ln1)b76QFfKUVk5c*Q1r0erfvU=~rHy#+$FzsZB?pLf2yTYDx}5sNIBRDTOcP9i?zW zUWK#(QlGT;au57VtSY#+~3KBE)g~&T_ZM8q`amqHnm??B-V@pS(XYOxp{kSu% zt{3l4UjC^e11$fP0X=wnc4brdsz$Y3I-BlT3T(0La>!lwV5X9BywDivEg(OqtVp4- zc4K&^4JcqK@EG(eJlIW(&F=Fe=+4TrO*WMt{Vi-o0$xdjajiCWDI$ggV6W0 z_m#~ZU1%s+yj*}PEI%^hig9Z~oc(_kP|CuG)n7~a-P^2|5YrYB!ufrFBf^#{t%4Ex<=!nlm5%viC_?Vw9gp}40iHIGrtBkVt) zEav?M8xcl|V`7GTk*q%!$Bm@_GO;kfY5N$-X04ElDUyuso=I?43j&&n#cwHB$EN_x zWB$s}s`~bO167I=j;me7y|BgY>F_Nnw^UpAIW??YMl*kzu1}wgU1;@=A>OM4TKT%l zE(26&iWRw4Ox0Olp*Y#6^Z_Y=03yWL_zRB`0YvN+Bvv~KdN4r*xqw&1(D=P&>$JoK z|IXK*)zK$sXx{W%X8f`itfxwAH)|)6GRz0D*+UoJ>{xOUlFpFmcXTc;-r1 zt$N3+U6#XIXja)IZfCtV7}WC-Ei?QQP4EwPnAEsn3Nn$tzJ3-E#Q>6Q9k(%&s(k;R zI7;BFYn$tf4>M+M?=iB-sO^rlyOrfn38obj2TQula@J?m4s%hUKHQV|#{>1OZ9an6 z-P`;f6WH9DIX8x3qDyc_V06`ACaz;*mtTH~)W_no@qj&o*#q%jrqn^6_|Q0eW~fu^T)O#7CjF>A>s@}xwOR+M4k)&j}N?Wr`(mlqgI3v8(3%N zA-)`JNlhBOT=L1mFAYtnZQQ5EXr|zAofkAH)M4ch^Flav3jcv8FWEtBZ6E)XJ}L+w zhj7p0@~*w!YgVlmsm{qmt^l&r`b~D%;OAT__lA}GHc(0cCm@B!Qg>~fxF8famgK}0 z=-rM${>bh@v&?+^vM1&7Q)6jni_ej@>V-0_9gqA`zjlDt_@fS!g+M$U4sGsZ(Jc8+ zm9YdHsB?#I$scWt_FzkaiV>yVPHGX0$}Aynkrxdwa$<|okFd67k(`aW2x!DHh2vTF zas=$zT2geTgpia`Udn#Z*Rzhwv$V%9aKpb3*I-@EJRefkI;N^Ia)z1*ojO+n5;>cU zjR=q0$rAeczu*4Tk z9Fn@3GFATS@mElz*l9`x2a|fxvAh(t6s_kpHC~%IR(r(+J~Jv?HB&n3S)jE-gfqVl z<^@_;P5)NgxD%SZz=-{nzTIVR{NsCN>gc;O54T`TVT)u&t?4`LfY}xfvVO;Rb-}+E zSY6=Q$IS5jEUE1+M8yE+&mk)uE&~((AQ4WR5LhK(ex+i(N&YFi$4q(8#Vn=p6ArTS zNr)p@5c%SFE8$6f37m9RdgRI5z ziNsx^*kxoGj$Vf|%waWmYkHzMQLUYuHYuuPFQZvYGN{Yv$pU)~P8-XSPq)G8Xc@wZ zSA()slD|zn%b>|KFkO}IkXHDhCP1i@6aITdnahQ$d_$#~na$g>F+Z7Vz(gf_!cUot zbF6y-CJQ9MZaO)k0MWto&owk-=ilJe8}hd?BgdPD0^-J3p0u7e2qlx!mUYMqt@*soWV3ykjPRMN@!Z#V>R2{2#5dbN z>6@o`+)x*Blw33&vP_y1wL<=d!U!?5e&ZrL@sE&pgEBN2H&E@aM>Wd!R9tvd`!Fj3 z@R={<1sX8v)gHux=}0F5_y(t~BBvPcG)39239bC-@LvTGlz z-O3vKDto433k_s=@&3^ViyquHf>79|L5y@Gwq%f`atq`R@H&uX7P@l zHw@b;1?TP2^_U#afnHX!x~|+DwM3AK3liOJdrW>&pRK9==O0PbnO zC3PTTfZmJN(XR~+Wt?|zC~kw##4*FoYd7a12C;j-J#GPu>g5YN|3BTW#YdFmTVF@YEIoD zXYoXBexBWJmjfb`KJ2g8?g(2#q61wrH%q#~*VfWRNp9q`&XBx3ArkYl%ErNU>x|Zq z@AT#9VM#<`JdYCLNJwZo68J`uRVzZzeewBTrB3IiPFG9ujZ*irh89%BM}xM~xnCP6 znj`o92qtNISEyZGep*}n9J+Bep2k(FY`$X`cm-#qbC#Abcy@;=_v>MT;l6KGZ+O+D zyiem{z<)IuHwi$*x++<)Sz}F=t4fRex2bB&Kgki3w+9oip4a|R>Mz&&C$oib2Ff#+ zNp&k_)xT#QIxr*8N2mGY7tEY# zTsqBhBmT}SPUfZ4CpmQ3taJa9z9{7a31=FwKH?|d1T$FZufOSI$W9@BU$WZP?C%48 z_Pcg2ou1Wqs;f6nS)Hz1=eQ*IbgVt#CtTHY>GZ3-6D&M8Jw3c zShD@SbiqFGmvfYv*c-Q3h~C=E?eA<9&WR?x`ly5>REFGvPZh-bx!h7-4(D`7mE+15 zg|J=Ob}9Od@^Ea?0xbWZuyt~Rm8)((x``t7qpM$Ez4`8!AAWv|mm9Y}VPoY08GfRkmqar!sC+;DVRV&S|fh;Ay!hKcJZe~`r z;d1F-t7TbtqSb6TpNQTKuLoy~dwI9O4cE2D@xA@q;&e4SmIFajwrJfQ5Bl;NCr)?Q zFi-E-D6?$e?@X?JzlSk8sPCEk<$lm;D(~A|IlX6gxWNvy|9;hFxkqFhYx2*i%Ph%U zAG3m5%bH4#HOZ)L9y2;rnN7V^gKaKHw4E}P$Lsg)Nl-2YHnP8NDKeDD%eA=41%MV5 zxtv9@wV&4U1K;(#@5-;lAfEYYZ$*bH%fwJ5kfk=_XBrRgi#_Y+#IvXXQUgA`1EO5}gL&jUtm)DvKTG8n5?ul|SJx4#%vzH-sO|-T zxE_xA5A=8-rS|i@4nD-6X(2|Mb5iLNL7ZDH4$$YBL&vZ>pavsrZG~EH zan6p-@(Fzg4Bz|Q)@S11Ak9lvhoXY;%QsAtR5OyWRbOdzm5XbkYeFmz()a?1YH>HG z%dSxZs7#+mFmKX`OLci0DBe;Li-;5||8NMJcIq9QOW9FE&X0z3YTxHO#iA$2tB~{K z;hbqx3_=WG$HgbZIm@momR+jz)8U*#bJ(Yv{Uo&hx8a=Sc3Butb^1sIg%VrnrnZ;5 z$pwL3k#9JVN2xBqHaWo7j*eiv-dzsRE|IqStUNGe~5ZLz3lGjfJ|J}_u#iK*o$c3n@%eM22X?~*p;p;!b$i-=cfeBFIqj0bC^+fH;Lp+_=#~>U zQamze*iz>T1{G2DwwoazXtxS_zQv{b&sF+KD++`@Kgpz+yw!3ULMirziXDa+*wPF9 zPS8Sr>D7_m8!V5)!~)|QZNBwH?WVH6MHO5mq`ApvoDTHUGyZpAa`lGeBXZ z*n`^#p1Ov%+AUSLq@3kUT_TPVTR15Wh`hvIKoL^qB;u8+8J3=)WXmiIw1yc#s!)z4 zmq@$uL`kba(Q6&1mBj5lC6f0bi=F;z`s?Z2)89=0efrx749#(6&UG_TOldz#72W>f z+PAY)f3JOebqd8qx2XNS_Ko_~TAYY8w{>?ysY+b(#MQ9G`|4K00ypP)Qh*f( zXYYY;-ImvR@KJ&PJ`uD#_`n`Eg$jeqV?JKfT*q~1`nwF78@;DHOCT zO8$;fbhG_l5ccd@He~IQWS5X?;c??P*^yNC=SluBN6NhB>X!-tL&2XEU?}C!B-fGk zW#22crV1n$udP0eF7kk?t2feTy~cnd)%~x1snqGgqEb->^%x10K2!>(A`zGv4`hc+ zYwXUA^41x@S;nvC$nHhi_WMt=09a@U49%{J+3!q2>CWWfCcC{+1)-x7e4)?K3NFTm z4mOwrpGomg2P&RSRdAqgs8=W2)&4|~3&Yufhg)J5ChI>cAFz>npEnc6uk8EKh9KMl zQ*OIPisXjGN(imgoX0yGuuj?)KLcqt%vRBG6s*Rnx#rAUi!-ZNXFiZ$R?ob$ej7+d zMU1c3Z`=3oE?yyaL%g+kdF|fX?!`MQ*LuVASO~5+{_8B-6uqvypK*fomA9OG;no-^$fmfAOJ}Oh>TaTA(pKX0fv}rt}?~1Xg@G!!-h^Z9>Qk zJ!uiruNETii}rVZZDCqm+b*YM;%hcvcFb+lrioF974#<+O;9XtS<@?Jit353GUfvs zw4A9(WZP`PcL))X(yidYkza*B890%VEoZ(lA5f}Ft!1tUf-_TLRP_w!&!5lMtq79P zTm{IxZ2c%{oWp!vRlGdl)WE5g)-xf;qt%hbX8vnn0;~b>g-FCSFg@;kW?o7$n<2E|6U`1RDX$p^!+J*aRoF! z_nPq|#=Wq>X1#c-*jmtC27AoP?K(!*`mgLDSf^$}Vyk%bd=p>ZEiNKGS8twg^PgyK z&GQ^jgHFbj>e;S2&`Slyyg_eb zzKYy(eX@Kj`uSU%Z}L82zU>3cxiH_>3B_cWh{}*?+g(WlG$R+zwYTOx|QzarloRVT{))=s+NQ*K#qi8ZBdm zTEvb0DN*dtKRV0R1ei?xFEm@u^1t|d8OH_GiqTE;R_ ztjYn$bA=pV+5RGI9*6K|K?=CA$56%s&?NXIxHFVl_##jwK}J}yU%i_VBuNKHhH$fQ z&xc71PLZt5CJ-mmM95e(Yh!YZ9Un4oOvmG{d;gv@eVYpW*0hT!Lf|IrsrMWi&4@*G z(#m=s$Oh6w&T6*b_Mi_Y6PkdSsuaJ{$+^INhii2`u4v8JuGZoZebvmxyyKj;6}pTWx8~1d=tfh znq>%vwq9BH_Bz3Au6%sT@qXBD*nk+fE?op_J_W|UH08Qix(eqp}U3~la* zr_leJ`$lDCNms!QPq!zOn;H*c_r(h_^enuQ6K9dGUV+wZbO%P(cPWVlPfo)_Xt&V7oUA6`wIAC55scK8S4eBdwnIbj} zM%a_^(jMpZ*u3$cEiE=C*b>j5eFmXiU0$o! zU~$|-4PWk8Lq84UJCz#b<_t6@g|zW|9ZLw=6#uGPgUQyR25=$#jH9NklJ#mOias8} zfPu-G!Im`ml?nU$6}Mus&MFb=tM%vvdZ;H3)>vS|5%cj4RWjJ3P3v*h7bGDA>=nLU zR5)LZIWo#UOWTTYX$Xpz-En#{mCfNig?t*`6Oh()6w z?MO=xv>!NlixoGp?*-v6>MO?m1_!k1X^YuGiGB?Y0&D_BPRovEaqnMBcJ*yItyOg8 zJe3uI0a-8+cCpO@y#>Rf5FD*GLA*}7n#67f#j@Ym#h+Je)3Z9_;8E;7(c10a7Be&F z5IUeJwnW^Rs+0XWNgMJm1XyIrRJHf*6x0-k;*wHmR_Fxo%_>U*I-%x_@c`)PXDH5%IrLP%2 zTWVV4>e+OEay%sHL|v_NnZyB+HN&ptukxd3OkYmgd`?fC)a%jf{KQV%wfP4L$hr z>dd>zRhxX!y$odBj2ue)ID(pO<36xPhjz0=X95;MOoQVc7KT8pW~I*Zc)j~Na)-V*{N@)6wFi&) zO%S$D@NZoM(m()`%a8YVFJmsgvU&Ob#@6MOzOaBv3~n6u-&lFPzg0-Veb*=7MGVA;oN5Sc!LySk_BJfye+Bh7b ziLr4uxf$LOwr-zBuJsvJbw1>c>E&qP_M%@;#ME%;>bF;71F4da-?v<-VmWx}w)vVoqxcyBn`azLvsBzm_UaEXcE$pdG zv9AxMwggxCzvZ~s0~z-6bRfj0m+I5A)2~dQojwo5G~F$s>-yUm@{0oQy{ww1Uj=g7 zpI54{E}kPNaHS0*xOdxZbN|~lw;YY?t2b0+N<})?D;L%x9o3^B=KF(mEKJ!iLQD2Y z>==29YF|9IJS8Pv4iLNd-Ll|Y;%>NUU{zhms-6XEv~C=W%nv4fmsG6e`z>I1422*OcK6bb z*^67p&awuqb;K438RN5Ut1`+6k&hf{V1vV@qqH%{@85(Fw4u$c#vbGgNe^b%W@n9E z*Dd8n0#JBD8H)!B-pab04)OE1oeY@6pQT@rT3aQ&62gNAnDTO_KUm|m7X4V;uw7l- zsyS&$zf7^Yu&}yqUSs!HHZ~U)YUX73+nSR1H)sc!vfS-lSb%=yW^F(py(?F_OX=ui zlm=Pdl|gN=nA#Ho6)5vT>6$hX)RCPhCx8bCZ2s7hBRG+55F1_sHwlyqtDyGhB)C=3 zZy)KWRVg%3Jr^9Aol?*2Gl%KojXNqsMV;Ww$A$>>pS9*yx4PVs3)W^U9)+4MTj~e< z-?DUCLGu73fzc0vLq9M_+x?`~A>vmu`vET8>Sq9O6VQfI3mG%w9Kl z@8!K0YmV%WzT#`DXJja6)O%*h2nmXR*|n8@{LGFCrRY{20=ke7pffy9yeKYxG&+W2 zPFcW^Ha~{syYEycPVo`fZQS&?vjXa+;dgglWpVHj&N?X|M#IrP!6eKZ^gCKPLvSA3 z#9+sbdt!-Z`wuL%VNpwh*a=-L4s3$1%3e+sC!WZBfW_C4FnrN5go})OZQ7m11yaWF#SZwCxWE0Cg383wakYx}QqEviGtQH7F{mQP9)52@ z(y5BFPh&Li3HMy-3isg19b}K)&7&P~v@X5wuB||%|IX*_8nncI?OY|0bhT8eiER{5(%N%MdH8&AG{Ugjig0hn`bd?eM=)WT>SF zt0U?sd#szHzBO94cQ^I~H%HhTt0CtP+#HMA03)}C+jvAk4_l+@p*vJ+XlJ-=EEf3J z+!+s1sujTc&)yjXP7wQ=Aa(raxZ1t~T^~X0e{T+AUpH!Z3~|*GqEci_B3(;{5o7I2 zde3%Tdj!=q=1@6wkpm|b4jQ&g6BrlH7s2cluZe@w3x_~j(tt9LfLsGns?#=-v<4mf zL>P!j@=Bw51-pjv1ey_=r7B|Y?L_;PcDrOQCabZ~)cLE9$q);T12RYkf+-K5lwwqR z8eL>#)uPkEBR`3_DUrayuX^bavi0+)050u7i{c7a52CYF>F^z!l#Y}!;yB*28U zk1DH*Ks;DUfZ=f(#gKhS6eFGrq?7-1DN8tzjTV)kd2`o*R|y^(8xpOyYiw_#YV*e= z_9mJ&7w(p(yA%?axL^ZmqidOr{Ectap@zk*d(y<@XNFfScL=t0OS`K-U7MJyO`fdQ zPR+YO2J*VqG~VtW5wgBhw>;!ktegn0GYC4lLbLqE8ObvnJqa+|iWU~0JO2)!7GsZ_ zz76oiopWmEUg29+0?LK;-R(yNG2v-{J4pI! zM5I}dNHOdiXYmq3O#lQe@7H8&M{$H6s~l|u-c_vbU@APGsT9&S3C3I!VPu9-`sz~E z?9x-{!ypo~_R0bevczL74$B0eE9>$n6%1$%AB1PLiFK}|pzB)O-QV~-iVXgL*vXLQ zBcsG#&596zaq$jMUH{OVnAI68$UVO^%rv{%-wl`Lb4h@qy>Y52CY~e$P zxhjEde*Ah0v?R*PSk(ihSr~E`R!1*rS%tQcjLSa5e)S&k0SokO$xAr4OR3m#||fg zJ&Yi4i#p7>vv6TGa^$6eaYa#y3Xn!7T9@|vk=C7EY+iL;MwWjJL7(N2@FAo82#jZ< zAftXo97*Jyx(ElogJueM=;F8oFIG-Wc@L9>l!$iDv@3BSqok^(4s#3?luBeU+@Gm> z`=9HU7zgZ_r2g%;YInX_TOmLe2D*F536UCe7(LqIEYbMC+1P(ryL01hJB-2!GiJgc z6TpZ`lQdY{96EwnKiUpLgr}fA8hw-x!aoE>VAk7H!6YR7w$2L)>a(Q1GPN}CwEp8C zjo>*sRh^i6eq!q6#MG&YDbX~o>Y1pCdAp)#YGL<%p!)ds_LSOf7nwfGGU=v~zImoj zk?CQUX-k>-=9#)hroUSz(Gcbxs>vtU`vnx0g$ha}e4*ObsYDx~C0EW}KhfbvD zke%sW_-133CE={zT3taq=_kKY*BGuy#lItIn(06v?<^2xdyh++=^d^1W;tPd>%q!? zDT$+b3mXlJrS93?WN%7=9+80+-^`KVxNlta9`i}J-|66(ud*2%^U0Hq)-hYLM+lL* zaP7K_D|j;MxZI4(alb>|eEBm%j-hpqb`1}Z`>pPBzWs0+K|Ii66<|5yb#X;cQO#%q zp<7|Eh6j}(m$pbW0Ht%>;;nUct92kqbO*-B7Ab=wifIAc}50OH{&SEZB-{)pF5F zjjM?(rp(wy(Qc4F23M3@9W`-GP?!VoMh!foJuQWio-m0p=0`edx%3LiBut(RCd<50 ze1CcR;`GAwrRmGljcIf{Zb`XjY=G%en_ZuFscJ>%H>WO=t2J#EPIF!~+BijOFHW_p z(&TgudGxC+ELM6Typ~%J-mO$yQw!C$E#8!hb>695up+!PjR~QKnJM}}gijtW^U$d_ ztC!Um0RWm?y@`9F1IgI)c@)O2{xY11GcQyZ;%zR^(3%7~{@z-inWCC@dwJ%LnnAm& z&(EXjrdChBL`tiu(JrdDT_Hj%>LuQGZ5F5r=kH6Z2zwz*y2NAa3o09~Bl&a}7uBbl zPHddVt|qq8QL~-6z&;{tzZ3nCp@PP%llabNV_8G#y1Z?9s#$G>g|^RWP$|QuD(6I_ zd+k_N$AEs-OZ{rZ{8Cw~+Tg7|wZJngz<4$3A+Bn9_8YHU(m|wS_ooa|svR6|QKZeN zIJc4H`02xw>QpXY()#l5Bo}7tBiYD6K<_PJtRAUv?0#9vN~<)^kXf-fTe61?!d0=1#ADwK!1_@x1eJ zWea0PJ45JOO-AZtPK-eD+ARywnO`j^bNS>Dn-~lbqWO=D_Ao~j--eNa+v}VLw}@S9 zv}A(V=${11HkSG0E*ZJ3PqJ~=*v;s<(K#iNZ1+8-BOq#YzHvMaa}EP7l;-B)GK7Pz z2A$X$FKZ>k=jFy^r5!8 z{SEXS6EnPd0;rT>$E;bfSH4_Ns6jW+-AHa_(_GnJTL_mx@F0V4fe=_3AliTMFv@Tm zNMF-B_wYSftaJNHTxaVTWS6aX3c^zp(>{(ZEib!~p<~xwtSYn?tJ6j{*=!{kK$*c! zBhtGc@W)R$3yBMB(rEosYubRYP+W)Zb-fv@+cBRscJzw?Yw7B?Qw+A;FX>fxDrJNT z%Oa8vV6o*U_e<$ohAkyAVT;AB$5qmuAbbj7dNX1L)2>Z3RfMOEXnbg`4qvL$LiIZt ziPyYR`$(P#HYIoSiT};WFkmtg+)6nkyT^>1@q{^#kUYeKghG`#tha5e^`vDn3RgLh z#O6jdGqw_W4mM;d$0g;E{2^Asf|N4Y?K+VgDZ@Z7j46zShpgh*t)&`P>xy3U4wyx)+mmQVi`Z*d9P%FV+<8iYM%(1TlngziBC(XMNN%=z!3Yu} zM17KoI-3~qmfhoMH);`8B;bha;QWw#^${BOCms22B~p(lGqZ0kZ?2euKnKLfa@0~F zi*nwSgWw2>#j`GC)fZpzaR|G&zd%THxYWPWKLwUt;O)n?lqJtYRyD4bqw&#T+r^hVKyg=^eDmH z#kfusMv)(5TbOkui#SaxWb@e|!hHJ2oPq5(`^orjcCpv5eHx}iLz{aIrd%Q!d-;F= z=l?N}V8&G4&^T+mcd$?wUz;;!<1p*ES7wbC$B1 z-C;v_7Rc7_Yc_qW1MKG#GJM3%hDUT+-2Vc~Pr?R>3Wh2x$f%eAy}=AyCIy95kz&E3 z71=JqZ_{zL^Kiv{8P2~J53rP?`^fp}MVTh^hksSBL=@tKD~&6?cyx^t(v{#O08ut$ zOoMn*lT&H-FmE&=mY+7JdTVI@?1aG}HZU@nFjl8jcKQXCozzvSP!?BBh~-gYTkFr_vH``+<_->Dj+Roxh|cO`8)-$}91 z+}fqDF4bNICLiyw{kHb%Y^&Y=t)w2W&VJiyym$4tNKauA)@uLH|2aSY=!|_xc;=@7 zAXYheOzFCh5v{w9H#41W3PgHPKW_Tk(J2T#tXE$!iluo*0JmK^Zr~+qM-eUsC0jE_ z`|u`E6aCb3N8hWK!s!RpT2OQHwaf!Q>M8+Ix{^|^!SY84BHMR>JEPf1sskj6`+ z;mgV_Zn38mmX zv$U3J64X0Qq&uSiA;=|FQCi-+uU>x>6jPpZG&D%dgY5Wfuba&-WL})z)yI$S*PP@y zU^)kAlJc%T@{F!8GHbZlzwwE7a7z=K&#tx%Q!3iDHT?r-(+M!|qDg>%$b@oOw#Fc5 zoxLo+UAQL*3SNXUg~0f6;Ikt&eZlFz|YeE(hH!9K9@8lT0zHsWL8N%*5_&bAQ!um%|01i-Oq- z(lAY@w#g6u=Qd>?zi0ZL>365!oBrMO`)gBgYb~aP-Wx(vR`1k1Qv_YLXr6pqRFhJ> zwuqSs3bXT}%`H?XN>b{~scjuHTs5uUd!e}&fZ(i}&vhTjbN?wEWf#1HN7Pz$sgp&+DB^#ky%`1vlE{{EoI zL#-Aej;%pDU?YJ1k-*1H;o7$p@}%Yd9&S-t$l_LZqLc7oa~r_r`rQYH(NQnGeTTW^ z$gRE|I01>N+KuTy^0%4!BZ83Y_ZT;UNKoDcja5uTsNnbPTn?$AD9UO)+06TxfTEu! zBnoM4pe2@#gg?;1_UN|Sr}eE<%Q8~F(+I6D@Rd+KBYUZDrIO9o@@=w*E6LpYD}P2) zgmP%vQmemrEthgsf3JQ@g&tPFSf+c&1b$%^I$d9--kPUo6G>EGh2s(6(^bO`8>K4q zK)p?zKA~(HgqkcsFND6bG|3`Z2<`h4$Kj!S>ypV63CaU#2!1TF+a6VtNIfA_TOnvd zNrxC9)e?!!Ymg|8u6t}v;5OyZ!g#75d7rBv(K+n^(FIIuzi~`p1t@?edt$_uO0*!& zfx-q8Wp^pgqY5j$t`+XE-Sn>Jt+KPvWHmX2oqQ&nN@Y%alK{R&v*JIA;X07HpLQHk zdj~UL8_W!9@owCCM%^Zs58Wnkls_3LdxsU*$8&zeOe&ymze@?5UQ+Tsri<$R9-Y$> zBJ-41_r6}rgX*X0+$OY(MF(o$QPgj%lC*&;u>kq3a!{pGAhaJ6#Fm_&SLiLsP6@zi z1Y>}u^-R9RECsp$q}*X;TMCA(ctnlnpVge!)zTEky3zbM?eYTTNfO3TjN#E6g5Cg6 zLfmN$fs@WN8FCd8Zhnz^bOf- zD0hA68xC~Bw?7PhTTb7Wma>oP=t?EuJXXNcOu#Ehmb@MJS0)} z^|opo`I&T#1U`u0eU|}2ji04PSh1{;wSh*8uhz)O&sih-KC+R1KWl{W$^zVG90{ST z;@60uwP#2q(^vF=#_DW7tQhtD?z6G;v(FAskK!mhILEK0=|LjppF4|L;W)0ZeQw_k zpGspczR|1A%IWF{wo}zd$N>IArt^2ZQq#{4KXq-v=G1$1GU1L@s@6Vlv>raIID?J; z2UG7m;QlRjjnCa@J#jZCvbWmpXNe?6<$Kmm=7<#SvFTf$dB4bv8}4V7^)YC|yK#$G zDrxkdt=?KZTfKEdjtqLO>a8nh_`=rYi%LAv0O|CaV>b&9a&42ikU$?^H!ws@J zank&EVr7xqgp$)y%Q|v5oQ3npX2l1@D-I1rktqW{w-&==#|#IR*p-mVzxV9Qq7wT; z;+BXfD(e@iGRlF^==NW{^t|$5?BM}sjGw}_-B*w0R>vJnaqszw_$%zxc`ydao-!Ie z802Aw_e9#-`Urh&!NBD~w&p@mp*rFZG`k*fYACjm0$A0hSaiEVWh4?w#-b}O2^Iq; z2&#vNx`jvaVKwa;E~DTaRU`#V88n%wn`hMlABK@pbdSGZ<_slav?Ifn&x)#fyC@S__*up0o!%Dtv-bq)yI?71Lz1|?`Sk`F+98N}Y9=m>)Wa6oTz}P|c|LTV zh&q5*obU09SW3Ni>0asG7OWKR++bajIZ6C=y~2J4OWQlLui2}m{UR9f4Ps9@C|H8k zqMekw9z}MhH7`<=lJN(bpGrnNWMg`e{3SIw=)!o|9#ykYbo*%byQzAIm}u5Z$apQp zdHb79K8te^F6IxJL>^y@eZly;wlJ5Qk24Ci?`^Jp|pZ z$DP|l(L!1ZQ&+}5kGB7cpOFU}+mFk&yC8#d=T+7M-3>J`SaWDFYoOd;+tg(je_9N+ zy|9OHN(R$@f#^F4kY!=y^X+AXIm*x#aLLf_4c1=FT2N6La3Wm6xu&l5n?T>}L#~(n~4j+4h6Qz$P;Yw>3z!u2asp`5=VHbs3T4!RFdZj4y9z=(uSqbxyr6 z0q>~M3SyPfVf{#8H#92?&DymBNBLupzdXe{el6jvIzVWGt-OwwxOydva3(SbB8zN6VveG;f))k)9<7=T>VVH8{d%H)Tc#>TP<>| zHH{c8ydfW%hMo;?2-2oaP^k8}O;w+kIMBr$4r5s5|FPoXUfFo_be8M~MO<5TWN!%<#AK8EI`eytYw-dTg7>jVoR4o_y@t zJhuC1$p`=4=^)GN_u4`^-4u? zk{XJ3%*~m2iB5;F-mWg|8h_EI&q%v`snt7rOiD1H=Al{3S~e!5hNKD^m8_pXxdpS* zXp>^Vz$AW3dN5T|WL@U<8;xLN>eJ|+wkvT|WBN83`w|>hR-%lBX^w<*Q1P)>#m2oMy4 zD=pzOv8oR6VBP6wK%i;sOFW4DD!8OG>0&=$di4kPMrI%a6CS@7@1KgW+bsjB1}e>t zy>7xa)feyEI-jj-GZ>2<sE{mq%a z=bl+wzmt_V1`UpTOpSY~Mq{+u*xH$`#xrUTMjO;4wUEIgDNibco?1J;Rrv-RJrZXB zNRJ2?J^ii!*elFvI*s>nVawW28#I#C`b z{?PSoliRl2Ddbm%*u~U~=dU}K9mddfku2bPav1a=ee<+l#ddM$a!lxZf>t-LPCqSnk1}!L%+e-a z&jBpqiOnD*q{5zWR(T5#(|~Y9Ld!Vg7^IeF0t-ROl=5##)ZHdi5l%J zGpuG)iYHB>HUw?mUg>K@V9%MvObc|BL6h5&GdMZxeyac&Z?!wv{i5$t+|=Ss4Wz^y z$juyth+yFk;SdT2bgKmlLwqB&evz+n=5Rt$nmPFky?J}affrdCq)z#~b|E?%sMI`7 z_mQ3DGY7<`G#^oz=8k=cW6(9X06#m=R`FV=tdW8 zskX~H&xHP21D&|!A@#PmkSBY-mahWY{QW3PtfoA-Q%1|-E%b!($w!E`zCZfGi876` zfQRUR&SddUbk*S|%TIt@|kNh%cxX>YEV?ZIrGBJ6fG zr8Y5uX{QzB+K}3;bl8{2elZNw?PI@)L{+z&O>Hmj!|Gji_mk&@x{aJb9L#fbdTD9; z-t?DgW22AK8PlBlQu%L@U$cZ;T^%AMn@C*g?1!qoG*gj#UZkpD6|&77&f^|qQI$%! z{VC00=h|~AbK0NnXP-+s6E@0o+7wx}Qz@sok}z*Yoqe`sKm>C|PCK~iN zGxbyBHQaEMaYwN20}0i8%)u*6jJm_nFkm2I=Iq6EmKEpZzx&*KzOZvb1STWyW~rk6 z51(*6Q9#JG`^-7jnuDUyJu-yzlP_D9zW|shO*EI`=t~H?ID>HA5v$ea$Ts+2)F#Ym z_qhmw1@Z((kRC8FnpI(!Jk5K?9F6*rPQXw?Q0E2w5Q2Yb(kXywS?L0yDxGO}=Tnc$ zn5+5@jC9*>&QfK+@m$pkZdF9ZdrE@g;`|->aML^MyEgP^U`G5PLZ*-a;-#>)&ix{- zJvcReUev1-)*-# z^f9AAkk*9WIqTAhB@KIBfEnVa{utH6-VHRM7(8Ujgz_$0OerM%r57&l6F zu|30B#61bstxVrPF}0$x1KKR`NKT3E)%``t!!D()$pt(GqUW*twM;cOGMO9*{@WNv zS-ns`)fM!U^(h8`OS+g00Thy}`p}u02$1u|MD@N>+V5G`z-J(_i42RUgIglbFiD6r zgoZOh2E;oMS;82qs*ra@LMt@nHib3ASx$r%OC%!6M)L&~aAh=;YXpdt%q6XR1FKz| z`dzXIw5Z$gao%l0pq35-O3_ED!fqq3C3f~%ogI#!94?Vx9ayIUM>u%8R1{#XFOQG0 zpAbwD)?Dk#QU-d?|_vkA=`lOvIQ55uW^4s>qOLW zPL7sXEUaZxr=Vg=1MO;{+Rx*vD@OX;P~Ci9T^eKP9sB#h>WZUvB~ z)@jkX0l+kZNdVvPIPsp-vL>t)^^iIW@BYWM&GQe?ONWktL)@yeUTv3pRp1&HYI;>b zR5^A+=vN4TN(mxwxZ_h@b-ACi96P4J&m5~FRnmDz7TvL}uKG(0LpZ&FmHh;g)nTLg zvt!^^u&0PE2JRGEXXgDc&c;IticpM~`l~y=Q3U936nYkMXFN`fhzo251i2MRX(EDh zdGedOrPBQQv0@TQi7;egGadGyJC^OwU&M*faW6?eRrts!(#ShiJWg^z43Hn12b#0N z{Q7vdwDuTeVUx#PDA%#tlhEAeYH4fKWc4*!#n9|XIesj{#oug@OY6rlj5%!Ek=KU* zkna1?PsE{vxYM+1*uH_PsTuG_&suu^*x{hZ%qh1|HCQG!cQQ7onM!B#sbglwEmPb$ z>3+nf<+L$ld>oFvpPB6X%n^nRP<3dY*3KTK-#?90gQall@9E`dFfvrt+cP^_ml~s^HN$%Araf&Xm$<-LX1hf z0UNx0*jT65T`>erEQhVE;xr4RJ&vicz5hnLwQ4c3Kt~wnTB`3?g3<&`CDfu%3kZx@M<<#1qrj-@1@#bi?wUU=Mp~b?4%s?VbpPhDx**Og*53P zfhGznzPt_sAEgll653EgWD%-u=}{{bg+fXwBc*`_G(2@fE!a5y5NV-cE1}-EP%J)}OGjC;-D*I7fJ~aS%lWi6j#5phs=+l6+a_e{bgF}(prWl~ z)eq9K{t+qdWvfz()ln<*r)u@1?5O!@VEU=C12~MOthwV5Fm&VjeD+x0cFP*>9bwq) z)<&ZmcRv2O$|Dh>z;`9~k5F5?@w~ELIm#rGbxV^3I5n$ruU(DHRvOWy)r#Y=LlItk z^7+A~@k8dfX|`Uo%1TpPp83%gaA_v-fStD0ag=jPn~mHy(l4Hm!+awSQ?vDE+Vskt z6G1uo$D&%Jjwjy=gbgK{O-oM){9C^1vTdnG7U_PYc_Vz&^H#1_9I@Gzr;O5As$M^? zT1$@sL%y94=bf>`$ukPwQG{|Doc5uG2TELM%Q@gB# zHtCU#>Dx4>57L-uvIO=8@(DW;L!4CXW?t;WG9uEs&sz1{C*y&_qeMfVhFV=zP|8c6zWHI(&$qV`+jU2#Cp(Z-l8M* z`S}G3$OL_5RZ*|Gefx0ZK2h4-B_Qrv!%MPETg?`fhnqNiu=-+3 zvWUbA-wgWX4KNs_j`C#ad6La~VPagEy%sj2BaQ4+i<#A{$7LaSvYZEDW52W|>+^w} z!6>z8TN&%Gk(YsSMf~=Ae|Ya5Y`VU``O)q7KGnm!q}+LrhtF=kd&3@n_vy!fQHS~BCoEV?2Lh)wnI-!O4iCDr5H%bYT3N?7v`#?t?kX? zG})>a8`Ylj9$A9rwkK_wXq_5O{%vNG!M_j?-oqd5)R^ACX6F3CL%Pi8J%DA&|E7}v z_IPbqUhQS^8WEjYZOhGoJ6u^^*{pw<3J`~S3h=EUsD%I4#>arIe_ zF>RR-Pjf`cl&pQbQ*`hkhuC30+)NmMWh^4sh*sqC)9TVxXRme#MGI{YspsCMO=5k= zxPaM|hyKb?e@(HLTR14%$a(=#VwLF+6 zB$v{XIer!jqCjUQ>-^G9lh$Dt^K{aL(#&3C88ZJ16CkCqDyqr?^odE)T$6GXhz3J(BK=jcg7OHms9|U0~ zPzf<8$j058)$Ir8si3DMzf19@?mOIUc6>L7)O1g%m>EwJPTJhgopz`6;8~Trx?Y!m zu|Z_0B}?Td5p@whlO8+;Ys+6I_;qz{edY1yzG2yVyf?6TpSX%&n{PYCfh8u3){Vw` zd1L877-}$mN%yg=yk>uvrq?#D>9x%b=&J8+8NB_QIJq-KDcBwyOG=ZeKi3!Lne49J zR|}oH;$?MVjg4o0&U*IM_Mz7q;&r*=W?TYQRmyUxUd_W*Zz@9semTq%7`=^KFU6AT zZR0);!m?w!{^jMj0Fce?ujHfYO0BM#tPH)FKN8mQB52E&IwL1dc4f?N!QJI7zNc$p z`ZORQ?(`RJm@?!x;+la5Ip8LU+O!$#KfOEF%fpbfV?hU zkGf`QW!5*=HdhI4klwd(Jh@xE?LLan51Z+! zm7dz^sgs_%>8Y2V2xMB+`tYmW?Z-RmTWamm%Eneq-C9YV-AsR684EHJ!gOG`wuPQ;Xndw*R{1ff7^am9xJXA zScWsY1Scs9RRp#orcH6z^6BNb_Mk%_(28ySK#L7rhN?e}nGOILot67s`pR8-mLaEn zukt30oQ)vAY^l8tATfnbKL~TfoLRmR-&XbneK%1Z_+02Ub&-!HQjtlw><@4~_~^c% zc9+N<8)99kA{-BvB~=0QHBblWkL=+Nm+wNygjhCOAM8^tEy$ekC64;9;%JCg!od+f zD`v);Zuecfd+#6fx)WHphkA`0PpK2$3Q@S+bGnKY7$W7e*&masKCcU>+0=}vGP{sG z7f(|vZ|&&%mU`Z?;q834{}8wBb2@J?`*++_6}_;}1Jk~?tJ$`zgjQ8J&@4HX)aO#U zaAWKyst0R%fbxetxKbmUL8@Tjd%WU!vlWggyLynEz@QL?L$H(TMTDbiB8m{jg+ zx`|0qpQo6T3VOmoF~7%2p`Hyf+`ja?o}@YhW3QAi`Jwg5m9zBK3D z_9bkz0Gj5seCXD7$W0)Kx@z?QtaM{jKb&PZVlGg0D^~Sn(#of7k zZ+XK@OWf(TjtJ!z^)d;Cn8UB81IBOMee>R1uh;}R>Nubf*{#(J-$Si3td1}D`sVgG zP&athUD&?=S56MQ3oEjZTu;A0pu*IPyRUx#*0t9c?x`bR#uuLb{`{9lN(bVP!M=43 z($9wd*4*7M=kHw*UQi-iSgStwx^AH_EO^2_<$n6TRn50iwCha_iEM=)LC(tW@*0#q z4uVCRQ{~;au7#fQFdAM`_H5Y_tUH<-l_johjE_{C17JGc8V>H8c=qnK!4Awi-TwZ2 zM)B&a{E5@U=+ZiO8m#1-f&+l?-UVOJu4D2y-UJM&xKX=`V?>rM;H?5O7A&OG$bFzM z*^ug65QTd+r8+?v2jDf-zkf?WU%yy%tm(k2e*dHJ4#@hREZJ%V9PKbNh>^0?d=;);Q{Q1f z-RA^jbC(mgPi}Ss2KB-NYg;7d72fOw-0Ghrc8aU(K0X;TcrGpNhyk*Kh){_tf#b&A zJsdlVpse5Q45Qv`wa9;yz)-gT?(gD0V{Jb_88S#1@zq7KiRUTsbP!o+FC!zZ4Mgs2 z_w%4LAz&jy7m1Rr2*@kdH9pj1?9e6wvNmh(ACdB~y$su=@mMxT>l?4R5SaVsu( zLVTh6qFFxSHyNda`3Ob1{Yy&q%&sMR4VCY6N`9a!&hpfiLWYYzJYpKrXuU7TG{G5j z`#Q;Ta2Jz96sg}S8D+I6pXLP{7s3LN(z~Uany430ewYSH9uz0=}&cT3wVPXgAbnyrNo)Zg_N`sD)nbk~An%H)zum2M~dnoEboz@0gEn$^M{&(IG%7 z-u=hZ`8n{alnVF_08upwg492NyoWrsvRyB)Dr$w^!Jib7ra4l?Ehcnhi+)O8 zW@|Wp-Cc$|By}BjkZFchfIwXOQNJkE11P*6V~M43R81mNDU=ty1JR`}6Jog8GJVl| zS}hsUbrjOe;)7y`tVEgmH&7qR?PKAA?Y+wK$@yxdfRN9%P*gc{PAe>n3RL@;#Q`70 zxDrIPalz$T2!6Fx%0|Pj4sA$DrYkhoYO6bQhVI$7}_lsQG%?jP7A!8XvhX~PD zo|MMKOqD$|I8hxfMx!lbL@gKw0&y0wcJ!HJy--)=1@ZqV<0vc^TJ8KU{L9qh9xn4* zN+r8zx!%MeWef_v2B6&^432cmQ*WfPs zmZ}im;s*QH9q<;$9c15{oq8SgrDZ2rIO}ss)xDy-^9dASRjH4a9Ry-6_K8d2Oh;5= zyCi(GkiZ};lX(R!6?6iw^lS`JCIiZ~bZQ{>9f7{;@{P2z@b?=FUo;l39_F~}x=GyY zwX40N(d^`m5|KnImBq`;(#cJVPKfE|yy>!tnyd>(*FdJxGh^6s`XF78)CXBx;N_+X zO(g+H4I&s#&pr`jSa;-;BMx#uH|wD{1R8>@dFu@bg6knE`n0NFM$|dP>&e3wy&g55 z)T=1Efq=B79VD3~LS6ZGp*SasH=Pwau)LQNkEAm~kfL)UH6wm{$SqX*TJZEyL6Sb% z3a4nS2WYDZVB8wxrp0HzXvB%&!PBVyVsx;N!)vw+u{+qM-I{I{;%``&Pwd3@SgfVd z6;;RnYcHfR7==Et4@SWderLvvV3fKwkW*Rs)7`c8jc=i>L|k}Ot{yfXe%nZ6&_BgT zQQEqYnK{&eTrvU+B1KvJFd#fCM``U0HMKq#{Q_a$hGI^Vlhn11UlNhtGrF}67m*L=vOD8JGmXmV=hyQlu$|eTaEIQ525ErO5+9XdZ zBJ7znY>pw1TN9$(a&?Z?wYB-gmzKK%Ub~L2&Y}{zI|20qFnnUb;I2?Uj$clMwdLcP zw5C$)xaY%N%v!XNqs(PW6OiwoVRH~wsA_@|rPyDkI&2b&5WGPQO33B3DjA|PPC3(+ zW@tPf846M{X32`pp05{*bhIT3hh>_d!6QiMzqJad4LA{dlZsuyL#{dY&<;P!AL}E?)Ba6NBnHAt?T<=w>P%<`R3u;u0EQw zt#m72y~|&8wEX=T7q{O_9EG5AKc~tL29EKtCd?quiX}?z zrvSJ%@xYobCm1$P&U2^J{5r5_Ws=!CTbY<=H@D*!%rM`;P#_e>ANwPe2|q>WyQR+4 zPm{q|nD3mKdP&f|w4@`Z^>XDnqdabdoHM_^t$80~cjOqygZaStBVLSnQiPKn&xSy# z(7e~mus|%Eafk)o!%x1@|396pLG{v40alWy>AW$JZjM=`F%s#YqWzK>sUVh4R9~Eh ziElQzEvJ+8G{Qr0_-uvWEt7}n5vCb|$**KE%$@m|-6KlquFo%xjo0DK5t~uNyz0|Y-VVi(K_XPDz7#Hg;+a3lAMrqeXanjU$Bf7trlHw! zS2)AnryhYbr~uF7TUCy%R(s+Lylxb|3(5Ua$z-Flsb5W2e`)6!Bz;5Ezy{~BS(!Y3 zG45uC@(EZgKjjm}P$DWy+)j3UW%NQ`i4hND#pCmsK+Dsygq(>Gi5$8chPj!7%lL!B zQEDrcY{U`@m_#PUaP4JvRvDELK*-6V0i0xYDY*KAbHhb9vQbE>Z zk4QqIMLP!F7FI~YNuqBXKwAQE-fB#9kl+xpfYr{2+{>r^RtrEaY9^9T;3&VzYyPG( zabEyVqSy{LKxjb;T)buOX`1nEu^b#OD zIEW%P5X_e&fnr=MXyOdME&ni895ro61m?rQHC9)@JAbdF;wnsiax)FrR+U6fBl+P0 z7&}19lHe`uvhi%v?x3MZK=GzM9%yg~sDp}VK#);F@Iu8BW`F}5{i+c!6SER(G$pNY z#BF*WR|Di93}A7w6!PNTQ^4X^WX!oy_<%2!;5IX)(hk6QuKMeF3qAn-%FNY zfDn$DhsIux+G1``l8f3+;zA6jmk~iVFPmx(cH4>makt*RWGMUr}8vmLm*Q3v0v^~ca|ZWK0( z#Qx`OYV>5y#(!c{pNjw*Xf(qN#ikCa{pwlU)Kg(oE4kRzsGZ}k=BOO8tI+~(RnJ97 z5=Qe$YkY7aQCwE8)I)8d>Qp$eaA`&8Xrs*JY-M0?>4^GIZ7W~P`agGL$pU1@K(p8i z*-rR=?b`=yJBS2~-7nu2pk#R)*jpL+_je^$$SOGk^an^C%b$*i{vjjLaG-^YeEX8T zv+P~)F~Ly{0Hi=jv_Gr|QN9Jy{0WSOOQb}8A;dKr-bAoDGZBfTw{>16W+K*MN0~|F zRW0m9{Z3X*ND>!cPF4Hi9BOnQhXbi8__hOSFm+7zoZ}6g!%YcDhDeBOmC5Q0UzkvmOUD!ja1JeW z+vxaCxmfqmV%us%VF_%puiN=kmV>t(h1QcuI98eC<0cT#K^EyHE z5N5;u79CuaDYKEeIw}@y9p0ww8b-Bw=rE!5@JprH%-YN}B~C6KgwD~lJ~V}DiPIh+ zW0scwavikEf6~Q91iJos%kC-^WWx9G_Pps{DyY}~E70@anju=!+H(8&6nD9AORgaMi>P+6hP??t?gZVTbJ8BBgphMmXv3DU!Ae8021@dSZ6 zkMmN=XY1nY5sA2RU$q*4dGiuR(|@^6lw!!kzhK9T)j}R<2#QkQmzF$teNdls*r7Mf z)r}(ooukYEFGit>;ZI!VAl9g}j0}!nH0Z8O2jg9?Y=ihZmqA>O-gm-*_Sh#&qcbaX zh67g6MeXU#DYhCeN!(o&9?im*;zn22KyB^G%FgyKurJwtaf;{0F*XY& zK}9j8@w9i@A6o~q@_X$8+bK>amI%Xe4QAvrj8h(12S&p6T(K5G9q}f`Y_*~P^ zzrMgy|AIWC*)Whd8Nr7Y;rxC_9RH_{K_O}>2v!|_$+y@S@Si!=dcbtHF;c+;ZkQ8U5Lw>lswN>`G3QN zRgD>$_=P%ve@vq%Rqj6qzc%_N$5ZHAj$HHBp?kW4Gsit=$^oSHj9!p#m5^G?snwz73mrji(+r z(4udza{F|1`@z=|+zOKIa@blXm(`W*u%VZIO&w}9@A~Ifu2ox~cPl4OpMWN8^iPnW zz1Kf+TTdo^71G3b$G%|ncd4=_^+lHTPRjbOvNkQNNX!hq#-N?%27lJocpKq$mr-vR87zfF4UZ5*y*fXYB?TpB3EL!o1BnI^W`A+}_s) z*TK_&dHUpu>PchOKlK^bs zVPSQ9e}kZ*9IzMwEG&#ygAB!|JIX>lf1>)lEyM={3(o*RY_0LDn`ijpwp{i}xdq2&r`vN%Hnv3&}HHIb?F9NcRD&E+K^JNbFhpt7E z$%i}aEJdMWVkfgV!g08aR71YEMV^>E;(4eqP(n;q^eiU*WmdzEOUp{4$QBeh`Wvj2 z65tGa712py{yK=idj#0D+sRpo-|^JfgYE6zjCx~`;bhYF{eY||eyi>q1=?s$%$%IG zcbR83T9Y%U*6y<-8xyxV+9lU-v?o2X%(CS88d+9j6f$#{+ub7#T)Y`?3IY`xaHAcF z>7?fKCuZ1ecpsHwH$q46}|4qL_fORawQe;`Lr>W-h(yooVj)B8CWE>f@U zfTPDGcuYVebBvOILDLMEpAF@~HVmFo>vAiVdgwy_Xu#JPZztk|WkLm2@~c1}!!$bg z0*)w7W-}yMw>73G+ROTSYEgerE|TOyAi9+aUYc&cKToG&R3>id>?Go$eQMd!Z5J=P z`Xp0>?saTww%(3<6LSj_dL`FLVi#j4>0x<8`!Hhe1u!;jpFzGIdHYU(j7PR<8kAk0 ze_~66(*fCN63wkR32+b3d}91X<8By%$(M;6kpU?W^C$yr+A%(U zcZ|0H^}!Uk-ou{W7B|(Cl(sJ(wfB-snX!-eA9|GMYuN`VqV+lE6a%K zoEJ6QC}DzT+em)lJ)#yYPuhXht+;`h<;TmZ^x1Wn{dHvOAvdm)=?Xn&2?W?wHTMJ> z@x%(*Z#zxSZ4SevsNp0?gex@n-=+FWX+ptJ>d`Po6bkp;&_SAmZet9LYU!L9-2xzh z@GJH>bkNeWJ{EaGCEm57pq&rv>V!xtvpd!dDE266VrCna;~JYk^2OstrdNtJThr3R zqzIUHu|>_QDFXut|+(Lwn3u>bK&4Fp63ahMW)vko5{P6+$zES>JQSigtiMTn09sC&GqC( ziE`2TP*FQL;{aXAI2-6;W9qQaj2h7%6ROOxXz7_v7r*bYq8yr_TkR-{B5NlU(E6CxxngLo{DXoUGV|#U3d~R!Y z>HoBl{&8u_({B%@dmp%8XxsQ1a^}5~`}26= zjzA*uV;l9*-~ie>G8mcgrX*pQp&eT<^8b!-w3i#}lVOqJ9@l}jU z7z@#IRV^H-^{T@iHT9}I==d7SaY>MSm)18;2-v|U1OvJSE+NJQZe(5zU5TId(Wj5= zfiYj2f!WzDKLRYW7G&-ZO3y(lfHFka~!YV;?2N$a*4 zGsh3-)V0@n^;?^h+A|o$h;;7Uf5vZW-eV;*cwpXZ%n9Wo3^VRuF!Yv}$AGXl8+<&~jjyr{j zMkAe72$03;>H^%?YYPuo_8#I(5Wl2E5MRT6?AqTRb4Buiv)}-HkHN`I@a0y<_VrnL z&ZAN_2bb<5+MqVy+Fl4Q|K!;b!$;*sgkgE(c~cyA^LC5ITpaoVm<}H0&B^@nhfJK3 zA<{F|<%dzJw)9Qym{^CCcqFe;{>Vi`8w%&l*R?0ce8TSt9J-T&CU%cYFSUSAxLUd| zIff|4TCqBixUdezVW~dYEY>7jM$BKbZ5bgywtBY$W$vRBA)$Koiy6+oO&$q$K~{-r z#I8Xf<3cicsSI-(9KYo@Qxc+6GPsNqX&P(5dy8A?vK!G!)~y_`axKP4AbScQHAV* z8?Eh1RmpB;j0DYSv6Sq}ibqQB$J|q|=-PbseDxJ;tw-2ynmI=`@J4~s;!LSXa%y@J zY&LJh!L^$zb7FStJUmEShX|yWy5D)TvN81fU6nrsIFAb z_@6Pw4mivHb8br_r{l`Qpcx#xDGx8@)<mX)m}?$ zFG0%!pXIGpnG4-;V;P3P$fr_fPT<?^fPH8?7Ehe@T!*q5sELKp`o6LKo}NYkzo z{}Tjrj*Zvob0o2&e_dIgy1@p5ihJ9?-uAC+M&ap&(`(g;Kn$Msa>w4<_NirLqQy+> zEmmBZt5&DpslHA1-3L&JZbDuoLHMlo;28z2;=l?_;#aEG$xR;mRv{Z1Ivb4gj+fwF z+H<5XB3TVX@_}EX7^*geAdvyH=*p$+&57Gy)Q~0B3I(^iu|CODhzV3#1FPk&G$-zq ziorng&W#Q0##w&)C&a~Z$@sqgfJZ~;VMm8MkFOZV=f*SAX?(@RPFvEuh7R*2;YR)$ zKIFG0zSESO_~d zU>)XpXjM8vMRC(BWi~BHS?8uI)v{RzJ+cmZwsj!dlP`i&;?$>{Onu6EML9L^N;z=e ziQhV+dqI@2Z{6!ME#AF-s?Ddj(=Vo1-&*76R+S7-Llo=*@ZOZBmz>5ux&tH)LfPVE z@Em}$C3e+-QW?^G#LSwHB69~%HDO9fJbMD(zU!obcEqt0cT|25I=cW(x08-qg0%47 zjSw3_w>t`SyCE(voq*c~bQMG~2|U#E9{!1#6X2#ds)C+v++N!Ui|wV=(kphYk|-Oy z(;KyrJxvC?e##ICvDQKtrob_&WPeoi{jl{edC9mg?MuQ=5##jPj`^Y*PHJ@CCr`g4 z^sLeKJFA9NiH~DKposDM10C-7muF7gHmtd{^bEajzE=rTEzDPHCw3sBJP8ZLhl%da z{Ld$Y5b5P3Z7wQ>4|tX<8xq^ssgL{DBL$QI`}pY3mF=f^14yq+G2|pTp%l<{)l7 zhJ~KL-QQmQF1?7kI=+^Bu-MEJq*6QDVJ9&#kW9=Adqbq$$D?aU^fl z_~74=j#w#lD}5kvKqL7Qa59klHu#1eW&S5l-h9iuPj!2yGJ^xYu~@0cg%kD?v?v){ zS?V#3LlpFc`cy}#E_{iv0BU@s>jKxTEmc=)B^A~e6XOgwFsjC4B-TYS$DU-FcOE0h zGN{2iQojq|Jls~Woiu1QS6U>?Wt(!X$mPT#)UCTjDM>*Fz7aBLdowc`37?BCVM@@{ z{-9w%+^{0MwfH_suJoK;#3%RfH>e%M*=UsMdv*+U>tOn|iWG!x)3BcS>h1~XCs;@b z*&2U3MCu8MZsaV4y+#)w?AKK3f@88_bXQDO+1RX=Pr0c^7I zNcGvWfavyFB8XZBa-z?3q+kKX%wuUv} zgU!dQ;-!Q9!Z_vN-d_;7H-E_dm$%`v?Lla1I6!a+mct+tS@RlJ(JW7VW{Pku(R@wh zY{*5fPBYpKo3JD-fN|d<@8E8I<6>SM9za$wt*WW`cyRuB`Adstr`WKpNK0X#(n`cd z^wTRl3^vVAcs##?4q`yruIkb@Di$+Ue!$9)UGPrAq#Yvp#04KE)reg;o1o3jm7Tpc zi8c;2cx%acL^eyT-YFdpxLliDT%5eID4H2|gSQ*J-To}fV+N?}bdaZXR*O6%y zybXLH?q9#SbH@Cm1{;<&vbv*YQ_#230<=2X9#-7=8o~T;v5&bQnUP{@Ie>RIR~{Hx zCV^dvAsJ-=n;<^dq9p*0AT$X5BLFvMEp;fk8d*rb%5}?!2+|h9AU@*I^8i61&3!2T*7l>BKR{tD*q25|Xng&*rX-JT*MCXWdwoT^s8T=uG z3Kq2Zc)m1zeMT@~DV{;(PMgathMw#fRQ7pHydU78w@ejoqtdyl>cC+Ilw@C3l^w|f zB}gMg^Z*_z%gKpXRM-4u#7RtdOWNe!{g&`g)1Pt6&cUnm;fI{N>G&*ePNl_;D2Fx< z`0BW;$bbUfkL3swX>9^0vj?M<5K9k7i3MUoF85A|-A5D|=fJoXN&K)a(XKfU^FyfE zPz53#j|+I_g`i_$PY-0YJ%YrFJyRQq0_o~}6|DM5P{Kw0?G z*c%hsqK=U4BX*7i zY3@oDuz97Mko!T@bDER`H>GGaCq$9J2Y=KCj_w#ku3Ckt1D9iGcA&Bi+(?kgGbi}* zJ1Q?M?^aMpToYt7f^N9%v1=zAdpXqMY<+7-qq z9A9Rk1qyx6?|HB@9TlO()$&g;)!Ng>I$4Ai7Ua)vGvwBRsM^RfDSb=lqVC6%LHf%^ zKb2J)KCITxJko=rdrK- zY?8^{MBq+VP2_?L;31sGURKOee*bF!>iif@cob)rXZfHBHr0Bje$Dr={pLClZapB~cXlt_MXgbcH zrY=p?$Qc?;oa3%8v{5bmMo4XT+qF;E_8;#OjnFrbMQs++z2xMQz0>YI337dreUESY zI{!a@=kew(7|{bfOv->k01xgqf@E*y5ofrXJCa) z2?3B89vn&G34$UNy*zzxdTROwURwqSK$0^>lB={n5fI2x8IPyLMnQBEuS(4F)D%Cx z>I*YdXyJL7nmJdUGU`tZQs+;V$p=&_09mX1-Jj9>c=!9kQ!)*q?QU25%7{gP6u@^Yu0jxi4H1dQjAuM z_MQe=1i)KekTdgzM`*5s{dfHiS*2im3zj$vSBR=23Cn=ey3pbjN3k^!Zd;DBF~;Up z-mdp{5Jz3RXORg@j?V{0;Z~ovg2toY1I${nC`~ln)pk1*dG}h*pd)O0loVqDJcZr1 zoMRV@Q=7ZKx$&l&ZC=03)1^z7#*hX?9RDtAxC++2q+S3L4MWUpmAkSiM!TRh=_wqt z?g9tOUID%q}k& z_-gGLJwKTGvi$a(Fi9Y>Wf$ktk_<}_ZBVg<>5O5DE4|vEb`|9<=oxaP;P^|YQh-(+ zJ;3A6e(f>d_iG#LwL3T7U-;<8AK!yW+jI6G4JWLF(475h_E)g#Bh$4p=-?B5S$FGN6 zu#E1xSKdvi%u+%IBf&{**^0gV@l=hE}^(AVnPiWcxIeA$1!3zt}7NM(uM&?tVC4TvWRw)qbH9m0T$dMtscI zxR*SHOnc%jly(O(LBqya7K-9DN@5fjq2QSle5JcgqTLM6vq&xOpF^PJ&f*1JIH|%;iZppAr1L?F9Z3X1RxY0AQd3EYGg_=+jbfsEJ zK7j;&tPp?i2ind;2_wC@ZwImgwh(voAlc{Kfc7wguUT#+O>jcb+A(9)#$%L+HRm)2 zEN~9mUuvVYw>(Y?7kLoj1!o1RL*Y`1ZxIN9c>XImFtC>iUph^|3s~H#yBS1l*r4SH zh);uMOQzR!NEe^bGHCu)#bQJ?e9a9gDgcrUKsm6ryk_(QunI3%_$y+ITJjw|QWn7) z{U|dSg5x$?*$lL6?`&@4$nD2Ukgf3O-EOoBu3P1OvTM_E4gU7FktrtN^o^jM@+?Ca zS&a#V?Td|5oC`*5dE_y2}D6Kf|X4WtQN29QT4|R3NiuE{vE~&6p<74VTVWCU8CB;y=4YYB;o8q(xOC$IKSq7||uF_E)c>;otOl@$|!bEUnNuhwMkYD#UW zP(^D(F32&ARBOXSGfLYhQQ_f?4tnI_s@A!9_!v=%sz|6TWef2mb@WHw^Dr?j`hfow zt#SxXLxNy)kn1siON2#gcJF?se(bb*9Z*ChvANItsVn#mNqmFavPNW2vx|+~ceET6 zkG^pji4aH~6P{yRn}IO^*=WxQmeDW?)Xav$jzNJb;2ZDVMP>%r2ymycij)Aw7;ex3 zEjCDaLeJs!mAKOsAqHn?MA(lJlAsEJGz0gK&E-^A)Pc*_Q}c%wKM)Z2A4-6nMs9PN z7GZGh#o#K?`huYx%L{w^Qvie$l|WBwy9@vj>Y1rzy8{52QS6UABoOXP6j(YX;yx8& z=n@qIhO&U2xNY$buDx}4;a={j)_vb{+b*r+APl+KO@2wUZT8dp9o6hOIS5_}@fwcY z@rc_}1;*{autPSPt19aZ^EuZZ=lo3{Hp!;9+*g?k0_cB2Afjay#T+ zvYq5!kVpCrb|*Rh?qmT1(1EQ>1xDOAi_O z)K1&7(9pUWv}Z<$^u z(;3|+Wil>Qz5?|?>-Y_+3yf8oI)210UWx zcp$0!(b}Q}tT8cS&I1-{{Gh!?hAxZqkqcy&D-)GvcBAn_Vcy+vcoarYRmyOEfV??y z(Yt3gd8iu~7x^_^;`l`_RS69VT|?R2*Zc?me1J|E%v{>v)+mEy&a@t zO1%YGAR28yJ#X{4tVuLjbCs&4LfMPf2miceSk=JLUk%a3uX9upmsY{hxfV(p?WLRsc43EV;$_Nc9%c8ICc zQ6tq?H=c0fZ*K5sg?~Hzd)U;Umj1N)^LUd#sKStf)j2LVa0jdecb|)R^@rs5h2sv@mD-){udvyOR#JPlCmVbB zH#Rr+zZ)aL*th)A-f#~%RNKN6J@d%VGD&C8JE6Pn%oLA?q{8$VXKb2pL>fiE!4db>(4SD+w1m3E{fn`1A4K9&RNRlRppK6nH(5O_t& zskk(^M7A>7arKOuomw#Kw#$X}r9O4Kde%-t)%r^1lBB`f*R#zxX0Ku5yRp8(J%~VQ z;!$xMQUi@(R5=>|u)VeUT}tsX4?G0>!|m;_Gw(+MDJnuQbB<+_iGgG7u{G8)@z)ap z!7*z_5Q};8?#;rx?Co#w;&I))bjcpsI!kd$0p#^*ckR(OaSr&mySeh6Q&|UC=G4|v zA}rX2-F0-aBMz@be}|DQSUy~A4O|K?#%I34LI-N`*9LD8X992SE|E&PIHPy9mAKha zcszE1!;s)EZtquUUgsnc5~*Aqk1pjkurxHzQzJT|X>?9A!I9?#s^`Nrs|r<>%cb%Q zqC@kMcZadQ~>C9NdEqIL@)^(ju7L~NEy=mhX>XTd>Y&p+q${wxRhMKRKJ-BVRhSR)YUf;}Y zNOFQ^MgO^RjR|rj!2|(FL?HCr5^d?C$C~LycvC^sTq1{5JDo3-r>Jf)6=xwd5*#I2 zTwqfisn@OUa@-X8D#ZB{nLQnhMQ}3&ZsAt&Nr3BT8+y7y?Tuz3r!#U6p&s)>6uzUT)>EMJ3?BfZMwtSHrqiJ1f2&ZXIo$CURO|veH7{fU`urw03Tjgv!AuW4az8@ z(VEB54z(4oG7RAhpThxX^RdW6xIy4i*T+GJacsU~moMAmU8vPAuz*93*DSRV3z+NE z8ux2tL}EYVd9Db2xkPXXlMG^(`0i#L(~HwLrr(}^XZqdhds@|g^*#QAPuN6wp?z-# z6LFUFdZqfid^xXc4O@JsHaq3R4e^Y z1P^Vcntmsx4pjm&sJ^efe^*{pC$tRNv}-d{xZ-Mcs`?A|n|fyh-)PDUD0eZRl*2LR z%B5D|k1jPBK_P`jv#|`ekZ6m#!^d`@dko!C1KHh5Qz(YYXwoJ_{g_%5%Bh`GEuGru zUW)~*Y&)50MrE34&H>>l=U>#}iX1@&$IbqJ8%CzxuP%yRxuJf`D_H1vyN`q74@hc$ zW{tG_O`HA>DA~DR7DlKU4~jSB`RNlob=2KwvT`SnY2tCs73w{SAE!>wO7usUc+E-_ zO!jM(=r#^2@uroKYbx*9n<~*#iEevz8=rXzaqWgfK2wRVmFSHwvFRlwIIt3%l;~Nn zdd<-#G;3A}?^bcfltek3vEG;&BQrD4r1dmu)|e$7Hg8g%dpQALC`S?%^)<47V@yBU zjaE*+u|hc|QNreMe7Sbt%cTt|Xi~Y3wb#wsBhePU&!SgvXtOl`Q2CPs767C7KLSgA zDO}n1Y=Bdw8Su*~7oS1d5i}9GJfkerH}wIm@J{tZ4h%{*rGdZt4VPmy%aC@8vZqfe+q>zRZ)7PZAtVnxtMM zYYqbp$}Y$1^D-+%8BW!qGWW}6hPq%a_HrQi}_zfxkSxsDi5%@YjT& zoxHA9YUh-^UNID;0v9Gp=>F_yllPOrB#6kw&@Zg46OE}h9IGc2i|#*i_h+LCtaKnF z`yH;PzP5XR1RX_ch(0IDnM@i-WC~wGMi2YAAm*f2PmM+*i1XL;$&yp?AqzqwgnyRN zB_w}f2Ma=Ooa!-)_#CMTBy}>xpsjEDJ3rD3x0pGRd#Q&})*9@clDS{Tmx>u4%bCh# z%cVx+oH`HmikP+T4vl_3ofSD#o5k_jTz&1Y%(5*A9O?D*{^`8gzn=fC@)1=UaU`Gc z*R5g;3-)!7{_V>P+*6}$YZv534YPBET6;)3-N%(a&!lq7@h!o4)!_A1Oievp+uh~| zJ41ZQQRZn;Mui^iuRX%Fec!)@3U^ojzAf44VrYMnXI%yjoupdLI1`MVbh98AE$BS- zW3d!lQ15Fc2~qkM0cmglJ4Ag4Qkp|$oDo5CfhFM}$v9Wvc_`WOUss;2;5=+&M{d(Z z{ihdwQ3gc8^ED?_jTSvXExm;qz|s;P?fj~STpR>lHi30Djk3(-PoQQ+)28q+%=zUo zkC#2G^D8mUAcai}jNo_9G~ci>a{>;fz4lst$lfWq@WUvU=}#}j(2T6R!}@_fhFxC< zh=%Q+lgWnZqvG878CmJ0+eMGSu^|OQL-y`bc^yT8VjfB|21jaX?-zCkX-Pc?6^!`i zj8^$(ve-PNx8nlOM5rq8-M`4VSn?wbtBj%lMTQ1LeuSYp3jN{0=-$(f-ZI#{^Irm% zvk1e+g$|A|x%!ys4+ihGAFy)&J;pb4gz@P#`&S*`QP%ITdlEZ`2)>{?kTVeX-xyae zEF5X)eYO3=hsEvtdZLaw4Rj=+gd?7W^Aa^UA@RR1vqp~fUvpYWres3GblyaN|FTGY z%7Nah;pBc?jFh-@p(uXD6zP=wqBKomhBPzM;Ud-v(>1Hma=&-r|SF)c$C6<=-Mx zDCBqW{T~0z005#kKtV>muFP?#C;r`y?aJTH_jvFFAWKA91BCJjU}TzyWKWU4-E8g5 zX?_0Il`Ya3(ux34zqffXRf^K_Am9MnyBED^d|S?bCuUbVw{JuCZ_KrXOD(w)wrchT zCICgm(^l3#Z<-Ngn7TNLtTM_uJV*2)%C$|zadOJ-c{0v%;@Yi(TQW!VVk7i|FondbJOjl6#@Hpu3LoO)NU5f*h20uU*l5~%m z&JlLz$;S5M#Lf?TzBtG%Azkf&$eufYdtTkOUuO#*t$eFD7`B61T5Wsb$|Z3+7xY+C zv;-zAs#_PJ=X!^z{tEqRB6i{?FeXCF?|MA5y)3-@u)4bc4GaT+RW9N*J1+9JR0+aU zYVgQ!i%OgfKG}^P2Y5~&(mdX*WHjL&=T5YIHYF^rpZJ1;9wpt106&7ErbCV%TNd$E zwv1zZ5YIBdsI)j#;fY3av4sXc7Vk`Mo-hU@Z{vjTAL3`! z(q&Dtdl~)X>rUry9}4&l zPP{pU8?U=Bu>SwCGq}G!M_R- z|FdUe#8A6Pd&dfVi=qBV@mhigs3gg@|M~L65kqW_mmU@a{E_mtf1LsTSOFXC@;_g^ zG-A~bkZKpJ_G6@LkU>5sC?+S$c{f`}sGol_DjGG;TK6a$@J9=K{<}ly-qr@rQTNRu zR(`{S_?s+L7k|;sCQ=>ot;aDEfJ?N$zlPs+OC;Uc(Mod4m-96pa)phHt zYNipKKVN^DF!1q5Xn^D<5ZRIJL{fa2U!q#pUt;BtYsi$Ompb!t=7xY{xek!35-dim z_S{SLxx1PxXi=QvXt}`+!nimB8bUO8{)9MWtj;2JHS_|g+e*ym%Qb|5fYYn*oV6Fx z5S7S})mi2r#6ofHSdS?Xr}kzm(oi7DNBB_e&}1!Z!S=Oj#tJ1Hxx>y`#TvOq&Ph-Z zWbO{^7DnGrTJ`hrZMzNxlHe966F8ip7LI5qgBd)O=W#5B6Gn)-`iF@MpYYWPd?ws6 zGtZnC{^$P|ZnQ2Q!<+O*2r(GJl)UgGynXfFIb48VJg0^i0j^yS#g9buD3+L zui%n{?sxr%@Rs7{^zn0rRmJd^y+&Xe z_ly{_^}1|*j#->A38pjwCc^|K-o@a9&GZgl1lhw(<>PAsz(G6vi0}bVD1lU|TisOG zeYaf-rZ3NJ^acGMaebo(bQc<_eaan&l;*uRzI`SF#C5=8X^x#@$$mTTq^ZsERCXk( zBhs%Puy{_y;gZM_8PP|Dom2C(Gjp>p!47g=la|cUwH9X#kW1>PmRT};=bWBCP)gCu zi{)@GJ){2pa&lECg6QGH$8sPCnMgi~4&(sg1_T}~ubjz!#g(Ryd^25>V!c|60Y`dq zQN~9V(M)5!(aZPD06Q2Rt3Xz>H+0|#pv_AtiABOR1?Y)S<{A&ycb95#lan4x zE>BGz0++s=-~dDu43ELx9IBMyA&4jw25620NuE%sE!QCw%IpyxBr1#4_w5u*bMF(K0_L5vr$OeE+c1<8ctF z)sMt}4rDYh1apTA$yCcKgQ&R8o9+L`LMa8L1Q@3vL2)*#st@%mC4eTtMoVL12_k)UyOah7<-x&8i${MViC%OPr%{Ipd++7(kNM8%X-FDYS5h2BNZg z(@U#D2J;JTQLbd6^_UrR$0BnDTU=uGP&q{?Vso229kKG@SXfa3l?XySDwn$jh%a$0 z>nvqB)&s{)n1&m>Sjf#Bb0*1B$-$l=7}hoJa9#C-crlPg6rT5zE-Xk)aAAocO~#cK zUm6oFkC2jF!+eVw4o1fNEygQpj+@CCjBD*pAPY&#AY9_o1tyVcMp)E9gHe`aGOlCGLO1C*xm%>Pk`=*&PZLN9cI<|63aBfIu z59G?+FrDTH7riOdhRHmUj1fp{{l4TYIzpmjW&S>b*GqgL1teP%c-ZWStRwzPBuMe< z3jRX+=0sCQC*t3Bq*02o&=^QksFLjq!UKn`4rUyZKx3pr8>zV^5_kr&W-zBQf*1Xg zEZW5PB2JQ&!81m__c?)#$aM69LJkU43iu3Nn#1{PZH8`Mxp#?qCn;xJGoR%uz^5e1 z=vdV%I94Gg5KMcCq^V3Hq;~izk%M0&rJSGV=THuzaef&FH-wXa#=U~ADIKQq#F@NA zmCjhv5~3tRL{DP2hz%XAa_)NZVSWA%zc9xypi7 z5udVj=9tO+J8;YZH-tdwjC#Af(KiU~nr4{c<#D7LxPim%4!b+SPDCgvrxLPnvrfbt zLqaDI+Zz665C=+*vuy>p`K>S`W*<$hiyW;?3=+B-*jm`7kReR=CX<{AE(pT`Gb}-D z#$V)gf`Q_%1&iTiW*nq@d~l7z3jQl{y+&hW7+k3s++EVnIvsZ@K$+&Z(c43cD9v*L z2ndyQIbdj=GD7LECAmxME26ii@T2UaG(Zwd2n`^%M%;i*;f<}1|8Q+2#D)o^mo{QH z=l;dM1~ys=xb+oonB|x7(8Fi+-eUZ~BeyWbmqUI=+X$x1XTX*`=4kxYG=y_?O^l*~ z$CqyHGd(@Lf^h5A!T`Z%xJj-J$pxX>8fbNZ>qAwvpOk}Fd4wd|7ra;8Fc`$Ao=N$@ zF5vsZvgGv2Rn5&s0=?7?1{uDR=niaqY8G}`pDQ#ku>u+kvP;3bs;q%hVzcx0svv>T z0n&o-zc7V>#Q&0J!Z?7K`#2Vz_!h%pvChI}Br}Om{NOmq86XKX?0n0Cwp8VA0HhI* z^42`k6U3d6oa3FiS0>H+Z-E|^tIgTO*(E%>?=|&%dNzShTES=EL&Z$eq3SS}@w;U< z4K`1f$(&RQHggpI;j1JG@w!t-PoSA(S7?VB;b&Y&cOve~=+k6k8=0Eg93V%dG~Y)? zAw<6{Lr3gBes_=YduHU_V|4h0zs zF#+QKIZUz4VPm$CK>)qNRr3DaAIO6ED~`X$KMQl12@4P`y)gH2{nPsIg_NuwBSXqo zkJW!y{}eFE=02%^dUx*A`X|enyEV2T`WWBI;`%3dF4jMu4ieBDsU5dwQQe3bS%T;3 z?b5$s`WZ+?re|GvKv#y@VT_m`tyk}@38L8FjXHc?aif7Gu*m-F7c!gw`UO!p)BJ@0 z^$R?L`)5dAC$b0&kniBV6;dQDb<)O%xqvH#pe`Qkm?Dc4VUby4=_#pyR{zue1&SK7 zb|<-HpU;14;SZ!x_&b=t@Cy;IvKM}F(!l(4h56?p%oF5?0K{6S6%eszRjPj;fb?_B z@&N3VPNqVY-+8mXLMX;B5Mc~b;-Ub%E6jA`7X(e?7X-+7Pa!e$^#uJ}TA6)ebS+g< ze739FQyuUd9V-o+vJN&v={K~Ae8cA1s`!SYf6XtWm<>8gmRT&{wYvfZ$Q1A;wt3lS zSsmX*jjw7`XJ(*Bq==gk9fIHCcILOy*`I3$vKQIEUnbYwWLLQ^-MLldYqN@ik#`g$ z?--1{^8&vd_%Cu^k8Bde==dHKZvLyOAzJWh0a9$q zr`^qb!gashAMPQyq&tVR&p2^~JG1>IYMfkL6Hs=G}5SzJ1lt5L?eOJ z0dYH!XT4%h5tug?OjSf-%3FX8tdg<_Ba;$(kiy8PlD~R?;Q>Wm9L?J#e45@6c^zP( zb|Q_H&{b=NIRT?ZTz&pNA*3x(wYnj&lOy+{5FH-MLv*rJRzaU`>o8AZc)Rdk+Pn3@ z<-;XxzM>j)mGJb!!&XJvC)NS||a=zl<2B0BE<$Cjb)PTk{6Xy&; zO|vFHap}3}@93)E@?hPF^anqTEv-MycsUb?eP%%My?MI+5^SVMs5c|`czacZ_i3N z^C#ki3JojN2>Utim~a&I@Zfl1#5Ngh@o#$ZgLgp`XF-gHG>0BciTe7V==SrB2%wP5j@=7^sfwNaY+2H z4C6Rdxwi@j8#E4Ip9LAep{tv@L*^k zNCpQ{-UP0x?v4V;!jv7=PIYGPHXorRpc{X9ui=+SUG^T^|COoN^xqHkUvxoxKnAq} z9)s*~2}$Ur3grl2yo#S~Q8>P3k~7r6zmooq)@yqcue`vNV7rrd`Y8I6KK_m^@fj#} zzk_rNJ;|L0w`;3LrID(5D~<`MjqdOZW)W2|VH&{$29#uCK8LxlNh9eg5gOh<#y4_* z8YM8XF1FDEpEbWas31B4lT;e;=iZ3}M5+c?^8(C641w<-(_B^WA0wQ(bh3Qu`^R?h ziR>i^{LMDssF23riF{A{RBI1Q84Z_NWo|yg9{vUBw=CN9{$6Hruj*Y}8+Gn1Tj`4LCPFS?igrqHSJgd7%(n zqVgha87cI^{2MC3zsull1cfe4(^i@oD%Z+c`_)56GqP&tER*6vBypy-l85`Zp{e9z z!ovaUxG2b*HJywwea0Dk1 zBhaOe<&Gu2p_=b0fh_tIW1?-WkLd}F9A3vCym{}zPfHMd-Rf`kA8u{qKgb<=vA4Y& z!&forIp~f?!^hY}yZ)7Nt{iU-ANxYHUFq4^hbWcTYji8ycSwCU+zwKIPm!|5>)k;< zpPrNu9uK#NYxt1A2m!Y$1b_||5XAy<B#J2B?U-(7gmt8azQ7- zA%!aq$74NK4yD1FhJ}S{xFrk+BHqHbrdcLeQ4id4=+KNl=#PZ2GQ!Glj4x388;Q42N7I46t|Ndq_d15(T2JrR=XsG&zp_?KdrFypv| zv@@2q5S@VNaJs`-988J&My(}(aOKuQp@)pluyDW$z7N!Y>k1MVLXU!q4ADP=^#f|a z-V>f=2A3UokRBG79plRtvc1wW;OZDGNMUG3TkWeGg0daaTO1M+y~=(=wyZ&+glmg8 zx7oYR>C3UHKRKb@1*11QDF@1%M1 z4ibjnelrAr<>icKPHwiwXhfPMI=p&K{8R5p^xp=}cW7XEiNBx0+0TeAIdfB?O$nJT z)WE8G5?pvUUh`uZZ&pVO==k(jJYj=J$CGC30=E}+9rK9&)65>bpSZnw2|p;FaSs)Z zK;aPFq`_m=MizppJ4J~#fF>tD+7#T-&vF)2)S7yES9X|T`vDghz%RM=WwNV%h-vu7 z4qv8HKkr^oqp~QU&2*K^pn5@5GaEHI#TIlPD&VTbGkKC$r3%559it4fuHD?wUQS3; zrI}DqUaYN#Yf3|&xxR2xIy6f|11?vSHxoiL5fO zd%#(!7vUDs^^al+Rc{G7A;>blvoM_{%q|#DcCqE$kcqDf%tXiH$!)U(AUas-^@c6f z0Sl2EFlis5J2)yTDFg&(XNW}cF96fD!}O0L zGgfmDA#<4jH00p&{FV7P=C95#&M(bhn}2iu*IW;n$Or^T2O$i_~sVzZx+p6 ztuL4Fgg5YmJ_K+w1H(Lv ze>?SGqoev2)I_LctMk8L?3$wkRq|e~&VO6yp!%lG)A$pkV8GY)Yb*67lc*?7W>Jhe z%r`iT`Rix{%8W?L`t{|x2AZYy2Et2O2#*C`#B8lo@*5T44#p2svlsWU7G23;C_=l> zX6x7Q2z1yl4$b4Fb`75wD5wt^YSKx7fJPWT03c?`7A`{@1vbQoy!eJVl8+Y!i#XiVGe;qies+xyBo)Js~HggbLm3g7}w?n`I0m;l+e zYk)WU?^6KK#QE2Nx#d@|-?0FXh#9wmkvPjP>vFT(-`*efB6cPJ_bp{EY|3*v{N*3F z$sL;J>`UgfT;vjmO064N$EswPmT?$&chnt>A^Fngh$t(ycBtO#hIk+%;b78qGL^4Z z@KWWOb>bCyq?)%??=r!9XMi7CkcgfvLW&lEbrNaG3Q&N%$cc6ODx0|oA0#*{OE!ZR zPPp#kL`TtYkxJ4xEey($lGFSCSj5F1N1?y!nq4+l6Q#wB#zSIE)Z;(|_XSwgqm zG8h{z)fs3dZMXXEEOoB8Sp9aiBKFK@S$Z`hPnW061=Boq!P?B%Y%HcIG~D2zG+aeK zQPPnIJ;PW<3(I@Uw`~>Z9eiNt-h+u2S4cSc=HOp-vqTWB+G*d+LcnFwANnxRJ;RQ9 z#P+$(qL+Faxt}1x@f-e%xCa;il~WElqDB3ZbQmzgrinC1t%;YH9R!+8a+@}krb0-H zc@%d4G~}8%!!F=b;O-ODN!Sx1t~ZypKH^XMa~VG$SV#*Sw?2J+s-K2sBs@@_E^2-U5 zn$syr`wZg*Y@HsU?3NTvsUWm3Tt!A5454nQC@Q}`>K=)CGM~PL)9vLmc;7mKy8+`i zl9z7Y;R^{aN3!0*-IJGOBVmEnf`zgbQ>M+RiD=LWdIOo{Am;ex?A6**{j{86ZR1VS zRGKR!cDrW9XK?2nAtemta6?kA^OS3Z@O2z@Z9x*2t8=%y<1KjF@T%Zj(B$@_-naW* z4FYyMQ{ib(!~Blba&Z!o7&ui{ z4#Mor&$n0?Dxe5so#UUGFL@V$ce!@RiVN|{b|%5PG7REGlKEDy+m(`5_=*mJ-Vent z-5Gd)@+Dho%RRhIIhfQ925#Zzr6l;tk2H1D=DgULRttg>8FEcCAgsK>2;>b8cio#L z*Cu=;q3y_%YuW(qb%bzb&G+VpM+G+=0o*oSn>OFTSHScZjE$+P#X~^H=HFoX@utOP z;C%cga#&A!gCXe~j(}Z52X19-L!_eDaH|dRyfv9i6@|3xw3*)@m&CCj3pr_s-yq*^ zqnNW;5qzf|wU{e<-ex9w5_`y>zlnIj7+j=u#k`2F(0R<|F~su^KQN8%Pb{{#8u>fm zmw8BrH_O^BlLE4dw7>)C#t{G5&bj>{Afv?HxrAf2;yp|LVkPN@@9^7R*@SC|hTD(&oZvmvGtM0K<{;j0B=-m1yLBCfYCp&;*l%+-@A819;yA^a zB0Z1w@?%cYm}E^5vzLi1#t7~Z#Px_^=#B0O0m;>lTDC4Gf0XZ%YdzC<<)qmh7$OG{ zqULg+r%~UZCW+aS#sqjwiKz9zv0a+&Q#O59vqQbNy~#vmO$1xU@d=*$V34>`?)L3@ zvfO0;Y@G^8x`noJdJ=os#J+FU>Syl?8-eKlg3cK0G9^WW@p)DBkO&EAFW|+)g|N5bWH@r z00&M0kQ_U?vku}KPK6d1Aq!mxYA!84K>Xk0%~XCpxF^5jq$NLp`ayoe0h?9deH*{* zrCfAqo``H;buXs!@zUNJG= z)sfVCwlp1k6nsX_e+JxvMFY5VMuofeBJQl$>Sq*pM68>NJAw$56%z5%+v)cV9ayE2`l4G(h^TcxS0Z4k{DXDDwz+mlUN#DC+gH(5*4xk z!xSwl@N1F{2r@|8ybUUYZO-%NWd23`O;6TeG!$q46iCi2QVxNRP!fk*DLw$o0@2=- zv{yA~E2g_E3dJ5rtT3N~Q!G3=Pl^{X(V6Q;E{EsgY&Zc7QLS># znN?y=vvnqaSm=<$bzUtru!=L(P$?A7GvFHEk~@ z>JQ_K`qDG2_GOg13(@cgkan%OrpBHx!-dgS}W3`vxVd2%yD1;JU_iQbp5 z>b}QkDEZU2lm86Bl=4d_v{AyaRR!Q#PMjBv=Y{|^hzEhDiVWokDxSHor$6{A?DrqF zC3a?^*gA8<8sdqr8@*jP_fV3ik;ra6k#Q$UHba%P0da$7Br&}jM1hHkPol9{BZ0kD zw{Q*56sC_Jjv}Q3*4AT-m?rMd#;2TDVQ5}JVFX90~h27=y0}EfHdlff$tG#|IldKJf6!oC%&m8}=d0;!EmZ>008b7&h?EaWK->O?!+1Tx-r> z3_M`zj0Q#sE#RFN4hxpRJxsG4BA`&w!7hLKqI3LeE(pox0T8Jc2s}8BLLp(?QiiOQ z@)gRo_AKwTY>`(9p7t3`6as{#N!1F5&MjJA8@^M>rciT)gL3PTgW7bQ_a#(0MQk$4 zGqq8Zr)i0HFYzjdR%^vJ=%S>i!(Wk#r5LNGK2r?L3q! zK(O1i6w=-t$L9pxiC8>yb3z57-C9dmMWVtcMwdcIA@qHR_(YZ%DsEP*eddHso|EcHaYb-AwN&tVuZ(!yE!oPXajYQH#P;wZgG4jA^&20mmKA)TPtOnlJz=CG ztcFR1FOUJu9RG@os(un!Qzsh;OTA9mOY1YI4A&M%E#&i;MWH22m`28vpMYV%W!cZC zzFc$(^hjLGc)XOWkDqREkO%~&zcmQU7Y@%+SZGO=F;@j2pkrIE|CzfoR!&!i3ZPMm zTB9Ps0qj4wntQU0+HMN}(I0585eTc*W5BHwcB6(0dJ&OW!bOxtVM` zI_`O}0}q;fJ#$=Cjb*;RhiIS_&(PJG1Iz zVu1h}@RGN#z3?rCs<6eXS`PN~E<<)>+UkX@>es?%ar3z?#5SHTY=2$ z;Eh!5ri5q#G$Pt@0SPA36Z|KBn)eqZ(;e4Xq{(y0gUnSG%fVj+$O62-)Z})a4E`m+ z1W4V0DxX3B0D4W@P0y3F6hYnoIY-O3$@BYLbOtZ;!TrsZ8Rv{b|4}WxYYHiNw|Qul z@|_M`Y|$^*mX3>oakX|5UgDx2fPyw_s@mSG&70NMgkE4X9x@?Cc0r9d^ld6OGK=HC%8Dvrv??M0CQ|kC*-1f|FTBwlw0}P+J+#;Eh0)_ zj>_aF`<8h(vmrZDjv;KB)TeH$mJMWDME^i55NGMk+H-RJ(QPztTAtzN~dpI5%H^ur*z?HbM;mXPdkJnzF0dhAfeC;1x$C(tF_)KZcU2Rga_qrlNv)$ za!iw%oTTN%>#z6*%N~l-nYfFgvvMffd3f#;0?(H|1zhd!t9RL-2HUj4-!9WW!E7j)MiO z*+RgGsF3e)9S}l|v8r7{$qIj-mes+x% zvwB{gG{X;gm5f=5t0O=F0!8Ws3L!W;EDf^&wL3fL}gG)@{lK~Kg6vI2)EZODMcXt2iBSa{WLjs#M6N# z#!ZU$6sFNce{<(Wk~Acl4mAj8JWug65~byw zQ%6uD0!*4yw5kSwJLd{9i#(O=QTgQqr;YiULy$8yWt-V&KwjmN>R^BZV`_w9mv1Oq z=&SU)*x^82eIwJIv7y+i#@6vW+Z7&GNR)pMIfwsB`&JIFRZtT#&CU40qd8%aRp*l0 zjq!plSvkOu+KT5*?z^G9K`{;-19OELXBPiJP6c_meH(N~d6qa&%xsH?}Atj0ik!J!v^g$&T_7rU@ksaBLTy+o7!&V9y&(%(V zK$7ucaN3|{8~7qMwminSp>u;MnoGVO+m+^Ura0SyxFvZO6UUKu<;$((Mf&G3v{Pb}-1#!)+sS~sHB%_z&Fo9!k3 za9!AlB*rw|g5&me#x3n_sWqLN4GR57j3^wR_`n7rD6LraxSNWISz2_KHgZze`P3 z90d`p)rTv#J0!N-p$1sequI%B@p(}bV(gJzidmELoFE4YKv5*^=W-zxmF9{8hwzy5p&Z)#8v&Q7X;RN1`@ z2R8o!-Ta^^=AO#)XpnLgh{_Rhi37;k4U%Ib`+}$#1h3i4FXcsUzfw-b`MK<4$SO!U z>^7o~v|=w~AG?Zn$7&4Wy|>@J_|AhjnMAJvuQS!s3@gfC(bkMe5kL+oBefwTP4q|_ z;P?OY+~Uu&yQgf&iVfbLD%>F|bUbBmAHbz^TiY?}aBCwCh~L_80a4YiZ4uQn9pP#; zBS2TCdf~V(k9OpU)VvT;iO<5YU^ zImpRlP>_SrLroPg(TytL3UdVSGY7b`8{zB3?rA;{F&H=e(%fe2@GDnqGbiPYzH2Ha zUX7f^os%*U8jQim)oGE+I7DYq2q?BrQZBwzeVp}#NSMZnr4u@1&}1^E&S)TGmomauLE&og0gJMSlTPfhSg``!5W{G~L+vL} zLK}xFmRQNgbl8?QD-`WgM`{=fMmpbTG-?P)4(h{KDr5d?7b!?m(xgJ2BEeQmae-Jz z=?%O<3LUp%N2b}K+H?d`{lLeNbuW5Gol^5o~AL5J>VI z1qBU9Q7Q*0Z_PL7DHQ9^_h<#Tn=yJq%ftqvn*Go>3TlO4~oG(qWG zEd3KpaSmroL73o*IET10yhLYB@PWCc-n>h~G>4HSu~;ql(M}DGh6u^{QAgcSzEn=Y zPHaUcg!9bc3CdMVLL5RUym=r|i!^wB31``qMDId_rskIWBPCu5`YH}Jabx22#ypDupYE`Lh*Ws}H$@ z5mZ@c4x_AT@PwF1Kn;1MNQxWkYfGxHT_LZw>KY>pnMhjIwR5HF8Xe5cd4wmS|#e*HLI>MgoIs9s%vI&=t+FCD%7>YJHt`~b&VCAx~6@ClQThuVbhc9 zTH&4PGf>yW(rVQ;*QaFa%JEbLvUfPYP+eo3rhyXGuuxq~sD=gV8o6+xdZ@KYF0W|{ zTd0UJE==lL&8>C}NKvJ>N$m->O;7`CHL12?l>b?3Th+cgh*wN$H;qk9X=XSCJrE=< z$dc%L0hOOZ$AemBgxr()DSh}#WnCPZ7kFD+HTgc^^qOS-yY2{*26AuWuRF(vXfrN#kMPrwHfw2!vjVB3KfytU!5XEF*}y=&*Q*YcppZok!(R4b=RQ(2OubRU!+7p7p&+G8G;Il@HW9 zFw9M=5wqwf5z5WFpx&a_oe?@etu{fKH8C2m$~a2T^uM@7g6kS^ldPc}K1JX7W*h%( zzGp*gsG&F|B$R_Th7v%ijyluaaQ+o`yUMM35C@pnu*d=e`aFdK2erybuqV({`tX&? zx>(HMRfN=hMgJseb$|_yCnoe!${m^*JKSM}^eM+Dq5S@1PtHDmJQ9tULzFjueD`|6 zHdpK{Pv@tt;3T2<;(C?a!gSb!)caFU?2W>43Ox*LEbxn@qM$sWgc9(PU9ygpl+cY& zrg~mxS7ZmmRH0ELQfk~UageAR#I>igeH!pa<-Z52^w%RW_FT&1Lk+i@|2EwV5{+b z;#V59qDwSnelHX5SxSxvH5!=Sacp3_7oU1W0;)tS@1-C4x_&Y1$(VY!_h#BN4*BSp zBMQEQI?`E)cn8XA&Q7NwEb;$wP@QV~M8ktHPgb{bX{sZjH*mPks3`|G8fNJG>y`y> zt{bAv;6YBMWU-{0v@?O35-}}177!L~CtpIq;jRmlc?}N%25WpzmG`+|Zvm9KP41xk zbg`>2LE^4roB0@6tcCa zZX$tTP=Xk)nm6&{3gm^=z)ox5s6#D`1LM6X+r15M+P%(8!hXcu;2MX#=4pj{Ddzv} zc7FP#gPZ;D&E>Wb%?Jkq1NUMhMxLAFE#igU80h_hhb;>>gX2|IEVJR%%8+o^Nm zox=Iq==gtzi)oDUZ{O=S{(h(Nbr^CmvA8zNJyw)6#FApgX}Q1m&MjE=A6!Gp?J28F zxWVsY11ZG6-zDuHh{TN*l+7*iq3xM_SYBb&otH@y5IcylY*qlnK|nebe;zn?zNhxP zIy=M*7>y-^8II3Eed+IuLb?7jPWM?2g_+ATlCP|!BYmI!y2|Z}$~-nk&v(Ph619j= zV8`Wp7XKwwCV_W7CrNqFViG~+?{bwZ#ti=@83sNnCTu(Gq+-}|+KtXJJf48N!KBUN zV45AI^-E(ZUUFtB%+T(KjWlmj21 zu!8Krg?qQgyWREPEnr<0<)uV4d7-hRR=JZox1W_77t{hK#z$^~;UmPzx|+VsE9a70 zl;3r=Y|;wzpFE$4ErExyWLEP(_>%n(1#?r4^u9P{kxl zV_Z($DXk)gMi9`X?7hmg6U?q?5zK$;wWHc!1-&^cw`)PP@-%nyZ-x$>P z-CE=i(Ke6dmzI+o(QkWu>s#*DLKFDMG}9H=b(tE$HoA0=QZnTSGLCrlqA(cHGPiS( zVAefPw0B{5VEN{nJ#eLj(SX!hmVPy5n3(th!z5@X28dxQZj<7=k(G@S&E5DSTu&X0 zFl!^;(T(tC0gzGJ5K&*^{R$lJ}E!N}9pj9gIAu}vbP`u0|g%+-AA ztzFVXDWuy;C*0hf^6^$9rvJ`UqGzrHH^e-WwzC%8a4b52|0$uAwR7zc1f^N(z>0#S zR&NIY4Au;CMZ{ih{`Jw-bLHYjPNeS%#7Ybj#^kp!bU1Ept{PF_*{6Y zWJu%OEUNBUwT#Jbn;g!yn^Ge+`N!0ZxV zO~MQT`lT>K^&`N{4%?%TVKo&ZsO3|-J1z{sQ@$6t^#7VSNq|-ajpzr{~oj| zj`Iir>L43V03gd4WD^|@I6vq8W&y)7P63Kt-w<;;ttO(P?TxF66*gqH)%C*Ufw<)K3IklU~0 zA6@U%fs8N2=dwkmKe>lPyOu}awa*yxNk!M%Ol-YDGv`Rq%Qsu1ZZ&h!8n9psEK!ds zYUCwtyMB=8;d$&OTGo`K-h7cPPHDzRFcqF>LtT~(sK`R(e|Wdo(n3dL9u9N((YX;Y zD<=V1REnMsM_lu1cp^kLl@*-#iz$z~D)R>TxPT8xBIqEG9vzzMIsYLl#8d^FsU95o zN9}33q9=XJR1!_aQhBtcij3y#TzUi}aCr#B3bx3Ni3T=jIJRQt&oAQi^DY9^+HWb9RVm z?gp2a=5E|V8iRio^22ejk~)2GB+y?q2`fxTe*|l zlp>8vZw*Bq{Tr(3cCmHNZsXYE9D|#9tIP0!9zmBb@kV8)n0vZ`Kb@ykrI+&)=Df<8&Ne6FU+`;J>e}#_5QC|_E-hyr-9fuU z55ix&rv*EfBdLA%!FBX5T$w9K&E+{jCC`QR}>B{nN!OhM-x9q2C#=rSU! z?TZIWPXo3>A0hB6&c?%UKhyNxDS-Q^$RHJ;6#`Hg?WCo8su8%X3-@g>@`Jzpl=BTf zJhA2#A5|#l9BvEDl-~ZrQ0<(RXF7fvnyyNE3nqTFWSDt73Y9_a9UBl_o~|C5=6}b7 zF^O*(*r8^mAOw{0M`IO~=xLr}ocrW`!XhVroHr zP!Yo?Cs>k$=QuZ`_+y3cY+?bHtXVKR$y=NJ4oHk-+W8%7vqn@oM3lLrP4Z%o@j?ry zRS4t4ISTKT%>p z(+&Es1Lp)l0*F=-kzhUY`}FYW_zE@I5FK9NzG}4G;%SUzt|ED#(If7>?~- zuZNqP)xGFPwHIRJstxqQFb z1=L`tJfh7u%w1piH*L_LnUbCNBn%WFc)urL-GlLon8SP`;bj8GPiK0bT*Ef?xM92Z zU2oe594dtSgRTBrf3JZAhXWk=+v^E8x_jN~i?$4{UgKI~@kR%&+YCU|Y^`3@T+$*H zGliP2qPbs-_d;P2HuW}(_%z`z@wq&qF;1k}X?E1%8lE9^;aTi1GtVK6K+lC%$`IYo zs}!*H_7aV21G=hnY$a6?U938`*??&CKNv(gT`dP3i+fc<(V<|26zZN9{LC@P?8(F8 z(5MHu+wN$6>p7tj=;wbps7i3j1L+yjNknQzrsqYBvJzq>KDI?-6ib1|FFhCPRHYx} z_TLoZT^cC=T6rg z3@Kblk_M3@{#jeM6pSSZ=mGfLa4^sxo;xP~riA*nSau-w(;8|ecuI0u3eysUi4sH) z*`uPSPs>+L9dkf_&MepgIghIUUN}Eb+&v6{dFZdQ&0#qAFDd=w#!37k(Ch_>5-{F5 z0o6fvJe625WWnLp6CZs|ycM$*uFz%&(CXAC0Q3BDoA%vnWqV#jk};`Xkz>Ero7fw% zs*#FwJ`&-pm^Nu$Ge7N2{HWXn<%<w)BX@1sG0^5o+BmTnBm#Q|Cx|P})|uL>b-Az@z_X9SwEUDT zk*PMv9EliLtgQIROk8ULEOR*@)+s874B&rFn`GY(hH^BI?uCL*QQr=kf##N z=eM#~Pu7LV7*o~7+A3Zp1dCGR(@gvZqofq`awRElt;|Y7IC`|g=r!Q6KuUud$d`Lo z3z!%+PuEV^bdr{Ufrr!cD{lfbG@vLnS?~p6!LlC&Dw-m~Z2h$-dp*#F4O~_SwnJlS zjQ=F~1pj8pS}hh-GG@L|5s((*?na}#!T-MNulJ(vIw%S~nHSv#gr&N%zuVxO;r?j7 zHx_dzYM3V5-JP|KuG&CXU=&^THLpf%-7!qcL)?UF9L8W|ez?y&_11crTrV2!4+eC1 z@9ysnN!M^U&|dHQ0=~ZmWy@+ki(B zn;A!c>5d2e-CYd4_kDjaBG_L4RhgU56I-#tiUK;A!PFS8xW`*DAQ57J2r4oMpZS^c zAQ!)gg6OAVKFMIUDEuwEWw<}s*u_oF8$t^Z_%<8_j;+|XalBOFsDhaL!G42HzYoSH zBG~ztDRs~zHEwF;cG}h~kJ!#|T*r=&Y`Q>hb|adSmK^k-+&^$;{_OlYy~cU|<@pQq zuhd_`gdyf3ZDRdG{nd};c*6a>!A|F1UY zPp47TjA*sTM3aOo)}DV&>bWKm3kfUy$2!fE8~7VvntN@j{+fJ5l1Ji2{R|5DDkzmZ zqLPcn?;%KBD`BXR`rbSK9?l(-c>_M2?Uo$5%`3nu% zu@9s42Y^zZ)5)4qf}r9I(E&_)ZsJJfc*iC<@uHn2?mR(qj80D5+|T~T_x3qr^h$#T z62@W%--mk;Qgm-}hXlk*kY1}G;RNWA$lmai&V){5%GfTKmT`I1hu`~qbO`_^hdq*z2WG|)e4_fRx9o`;`VtcgwTkfAI44INfxU< z2+V7?Uu6YiQL9}$xlEJ?isA5Y6Vc~De@Q&XgrG>Uy$K>hBy1*PHfp0__T(M5KZin| zIiWv$nrFbo!@A8rD7u?waWe8+(sU4Bz>oeml5_|y`>W5-^T0n|M;i9~_pdHQ4jv8t z!k%4xGBjTB!{WxEyMsT&fvX+eY~ex!ayx049~h#dhv2kh5M}Gxj!hR&^=v2DZ9ASu z@Uzge2n~Y$;`!0cw*onUAOE6ol8#YE;-**NvjS)|1qV=|OVR);r_sJ!;YvlqI_tvDzjdg;3!?bD3ka-EE=@l>9?_LFY_^kuWky zIzd<@b@W<#SNWG&yO8m8Mz@!YnoZG;6QU zm1(3c73}bVHabh&l21wS&lYt|k+~=Y6dmyo0=Sdzwu?*gJC|-TBTz$WO@xE0@?l>O~J%T@QfYh#tL7RKLh^ODyb3F{9K6~8B#3Moy*PYfH~ zeAh>^@7{*Kkq=sO5$$X^4Bx`F)_+H{F7iAvg^kB{LwS|AM+?J8$Z+~-h(FOS{8zDc z7VZxg;2)1`po1EIXD$2s1u-h4bLu{~%VHZtfAd6R-7Ju*bAxhgXE-*SMNMfdy8|z(A zvp$@KgtU1u3?ZJ_zxf2n=tx`AW;`rHaVRkxC4lUcYZoniDDx#c zs5GqufNX4p>qcW^7!qwaXIHVe4QCsO>RiiWZIz)>178NQF1&U^w&@EJJ0xT9TKC%w z8cq2X{Le_`g^pA-FBD33JIW=Bu!t0DIaIMifiV1Xgee!yi7&avz?$$kjc@et0GV&P zd#y=P1!uyVe)V#t^by0RM=TR46%~ly_7iNd?%;`UP`%vXA>d?H%l*F5`8jJYx?4^; z1Pg~T7Lb)`CKE{Lsiuhjj{Be1X{Fy!RE|O;UjrQ~+3WTGdfP+=g#Qr!@pAU=qgC>EPSkQ)?9mn&p zqdQChcX8BTUxrYIu?&{$!pNYs=(Uje#^8OH%|-Rs@37e%o8dL?XTHWZC+Zi`_wSLh zAJ7BKw-6!c#88tMa)btpliwDK;OvEb^Q=J;MKlqp1=8rfImjPLB2owv>(5=r+93^` z!W&kN7F8D7(82c&$B!=AENphOVuy~oO+8NOoA9>~aXly4%yBBMsu|IY?x3cSg;DqK z!x34gYV!*qj6HBLI+*m=_Qzl;s=zu-MgY^OtA+=9HjX1hR0h_|p;<`mF46{Or()8!nY#_x4!C&3JulfAFZWjY;iodB{v##^98}s-g>x`}eOk z40F4sIVu;u&eNdEgR3SVT$6f4`B1loenSOh7m{Khs#ffWVL+Xi8LAIy9_~XbwqisV zQQ#rf4YG34}CD3TxOiPV+7csyS&>lEdP>X-v<1cUv^b=H zgmq?lRw9LdTRVP-T~LLJ)A?8MH=9s=P)Rh_^i=(V(nNNXT?Ij;xtYX~x)G8kfUx7A z;8P@Y{%ij@%-2w<>}#t+eyO+V+(2CIM~m~rEBPqLHGAhboHFhRX&>g}=)QyRg9iz9 z#t)RVkKZ9H0@Cv39f}d=85MIN!8)Y1Yho?R&K^^c%ojj%=9q*2{lT$AfSC|7l2;hlb?Z?8{(RFqVY*y9{k6ce; zKBj||5|-zwNr=pjf>=RF$05Ra9Xcjb1$qJ!$X(^7Al)ME1{O1?pjov^RKSI6rg!M8 zhW8cpN%vJt_J$ttJG{ zf~0>q6*44q0h>`6`86@r)Tp;~&krgejSq;lWBMy-tz~kxshOwaG&XVB)!5WJ51TBA zp7?Tz4TeOb*+$S2MdxOUWD58vK`9Aq3*vJe!~EAw;aan~jO$L(`g-m736N5~LG^m= z#PX^8n?hR8^6hK2YcrPr8QA134~BE7s8?JFBCp74)$9k0+1-R@(-rJ%Rz;0V{xnP|eELFhWJWF&u0^ad@t6 zV04ES#GJgD*0wk3i*DdEl4e7~5U2qqByQH2HG*A}2YZvv1vD^e?e4>1D@g%V_~0mL zm!h=Gfm6?hbL< zy2GPT?q@2!h**At^HR)ur~h}DL4LLBM#C?TtL*MV4`fV}*59aa)Ln0BPahjgJAyiv z>rmK;;Jak#5TPh0ZQ?|V*LUa%8H&i&?H$!|YhQ6+)J}UZCRpm`9qDXc-`ZTnzQ0YO z2G+c*TM2o57u`}Z09gQBnRYDLhCHCtqx>Q$8F;W#GXP}@5keCM7FEI1K( z5u(vR5Db-?sH1A)MawBA%>qQs?fo65>xNMS$c>XE5p6>QmOx*RU&^Qo8#M;|J8PgE zdVHI=q3*%rRd97)c>Ap_Y@K%(qDChYtxCQeGdnmw50sK4PyE7(#2Uu9vjcG$=mK<> z^Kuz;8tub6+mKMKXyJ>&qrvd;Kyi}zq=rzCJ7;g}NIDW@fH7=j8(S5<3L!-R81}Qg zP=5X~F`d6*kb%)kx5AC+^WOFl7CMWb71qm<*77u}Ei?+Un4wV}%GFT#)q){3ih^uv zX_U3~$1Te56vZvR0VUDNxjCpsNG$))AX;8K+#eXrB^5kUHMg2YU+Gh*Ef%Og`w3cflxd2#Q?6 zfkKN7DdeFN&%f)zStY=8A}72II3rAE6$ji@9pHq0@r_?%vT;HKptyD#OB~`G(PUn% zi_5k8>1F-|c7rD3E*H}gj9fVLpS_5G+N% zTsyqK(QXGhnvs0U;!Gb@f}|S+Vob8Uxi4_Q+0)woLk4hGAdkGy;f}!?IW?zUIHpvj z!W*$B{E-2#PFiZos;zodzsOrTfg;q$+j6UFC&J;Z?SZGU^~-8%rHRC-!uU6>UlCg| zE(`#xlpm&=+E(jtP*!mLV7G?9Q~LZ!*e@JNuHrGCUnKsHYW2nCxvLlvzJ<%5^$zE> ze)VGg>hJYjxW1@J%=+0^g2b$6MGj~Kuoz448*4g%wBz*MzPNuGxoJ#mCA)7N+H#&1zD+Np@`>27DkF5ut8NCry zq>}MN7-PJ0Y^fjEP%DIOgT-q>{qNEZ;>3zg$8vnnYAvRS5&Vjvctq*4u$l9CwW4wj$s|Y7;_lC6E+P3_) z*WcBuVn^@Op=_r+dL(5_o?nm(EHvN&^3{j$H9q;{2OmZseE8lMA4Ttd_z}oL11}Ax zfU5|Sfy`VdrLm|$vcp>45o?I0T_};zJ$VWVpA-;~+RUneC{T)J3RD;yKN-Up;8ye) z$TWOx``YY3)W!=~;32=dDFxA*{%y{uP=;s6 zxasXCc4g~wZRYppUuf}ZOT=mvf(96E9arGdr7Mxb_qhL0^DKwb9%OY|Lq)Tb<_5;FhWH8gev|NAfuQ5FTKFkB-r68=N;HI`=|1~(EQD~D~4=o6%dFYTFt eP{mr+zex_%aUAF-B1T*eHV7%-^>f~_zxw|Yy>=M@ literal 0 HcmV?d00001 diff --git a/init.el b/init.el index 0c02bd3..d789a4c 100644 --- a/init.el +++ b/init.el @@ -51,7 +51,7 @@ '(magit-diff-use-overlays nil) '(package-selected-packages (quote - (multi-web-mode spacemacs-theme flycheck ac-emmet markdown-preview-mode multiple-cursors git-gutter powerline ample-zen-theme monokai-theme dracula-theme auto-complete neotree all-the-icons spinner markdown-mode lv ht f evil dash-functional))) + (web-mode multi-web-mode spacemacs-theme flycheck ac-emmet markdown-preview-mode multiple-cursors git-gutter powerline ample-zen-theme monokai-theme dracula-theme auto-complete neotree all-the-icons spinner markdown-mode lv ht f evil dash-functional))) '(pdf-view-midnight-colors (quote ("#b2b2b2" . "#292b2e"))) '(pos-tip-background-color "#FFFACE") '(pos-tip-foreground-color "#272822") @@ -137,9 +137,16 @@ (global-set-key (kbd "C-S-d") 'mc/mark-all-like-this) ;Seleccionar todos como el actual (global-set-key (kbd "C-S-") 'mc/add-cursor-on-click) ;Añadir cursor con clics (Shift+CTRL+Clic) +(require 'web-mode) +(setq web-mode-css-indent-offset 2 + web-mode-code-indent-offset 2 + web-mode-sql-indent-offset 2 + web-mode-script-padding 2 + web-mode-markup-indent-offset 2) + ; Cambiar de modos en un archivo que tiene php, html, css y js a la vez. (require 'multi-web-mode) -(setq mweb-default-major-mode 'html-mode) +(setq mweb-default-major-mode 'web-mode) (setq mweb-tags '((php-mode "<\\?php\\|<\\? \\|<\\?=" "\\?>") (js-mode "") (css-mode "")))