X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f X-Recipient: geda-user AT delorie DOT com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=TQtYlBRsxNw8m+ZgFHCEnacTGPl6hcUiBKFi8rcAhr0=; b=o+NQIdEk6i6s51cFC9pDJP727F8L5LE/HaG+egGHhMz6xDSq0FRBvwlW4iH5U3pzPT /95l2OhJwFRVUpPm1VH92kM3ys7ndP0ntFFyvXg3GwZYYXkwGXUZY4RzF5h/zyHFKRJX mX7x+/qAefxIE2R3bXggUBowikq73dUWt2LdMPjCy+vre7TA69OqmYbm1GdSqYmCJnS9 /eGQWhCprTlWKsgK5YmEqAsW2UBuDynuaX1g0uP9n45Oz7cFBsAWiNXQmI5SwQI0RkdB NULg2aU8RzAqBEZSJIUJ8gWOqEy64Bvj8EBU2xkM5JmHBtNkUTJff0OMjCw2M3ssHIGE SnuQ== MIME-Version: 1.0 X-Received: by 10.194.235.99 with SMTP id ul3mr5729515wjc.6.1370871903266; Mon, 10 Jun 2013 06:45:03 -0700 (PDT) Date: Mon, 10 Jun 2013 09:45:03 -0400 Message-ID: Subject: [geda-user] ActionResub From: Nathan Stewart To: "geda-user AT delorie DOT com" Content-Type: multipart/alternative; boundary=089e013d1ff8d3dc5804deccfcaf Reply-To: geda-user AT delorie DOT com --089e013d1ff8d3dc5804deccfcaf Content-Type: text/plain; charset=ISO-8859-1 Ok - here' s my proposed command, rewritten to use regex. I realized that there is a usecase for regex based replacement, rather than just simple prefixing. You can do: :resub ^ S1/ And it will prepend S1/ to all selected refdes. (ie, C3 becomes S1/C3) This is handy for doing board layouts without resorting to the dummy schematic workflow presented here on this topic before. The regex can occur anywhere within the name. The 2nd arg can be blank, and it will replace the regex with the empty string. The replacement string is fixed - it doesn't do any incrementing or interpolation. I'm not stuck on the command name - I just needed something to get rolling (they won't let you leave the hospital without naming your baby). And yes, it compiles without warnings. The gcc/regex.h/restrict thing took me a minute to figure out, but after that last email to the list, I wasn't about to let any warnings through :) diff --git a/src/action.c b/src/action.c index 1d6d8f9..27a07ec 100644 --- a/src/action.c +++ b/src/action.c @@ -78,6 +78,10 @@ #include #endif +#ifdef HAVE_REGEX_H +#include +#endif + /* for fork() and friends */ #ifdef HAVE_UNISTD_H #include @@ -3219,6 +3223,100 @@ ActionRemoveSelected (int argc, char **argv, Coord x, Coord y) return 0; } + +#ifdef HAVE_REGEX_H +/* --------------------------------------------------------------------------- */ +static const char resub_syntax[] = "Resub(pattern, replacement)\n"; +static const char resub_help[] = "Rename selected using regex substitution."; + +static int +ActionResub (int argc, char **argv, Coord x, Coord y) +{ + enum { NOERR = 0, ERROR = -1, BAD_REGEX = -2} ; + int status = NOERR; + if (argc == 2) + { + char *rawpat = ARG(0); + char *replace = ARG(1); + size_t select_count = 0; + size_t renamed_count = 0; + regex_t pattern; + ElementType **renamed_elements; + + if (regcomp(&pattern, rawpat, REG_EXTENDED) == REG_NOERROR) + { + // size the elments to be renamed + ELEMENT_LOOP (PCB->Data); + { + if (TEST_FLAG (SELECTEDFLAG, element)) + select_count++; + } + END_LOOP; + + // collect selected elements for renaming + renamed_elements = (ElementType **)calloc (select_count, sizeof (ElementType *)); + ELEMENT_LOOP (PCB->Data); + { + if (TEST_FLAG (SELECTEDFLAG, element)) + { + char *origname = NAMEONPCB_NAME (element); + const size_t nmatch = 1; + regmatch_t matches[nmatch]; + + if (origname && regexec(&pattern, origname, nmatch, (regmatch_t * restrict) matches, 0) == 0) + { + regmatch_t *match = &matches[0]; + if (match->rm_so != -1) + { + size_t pos = 0; + size_t start = match->rm_so; + size_t end = match->rm_eo; + size_t patlen = end - start; + size_t replen = strlen(replace); + size_t origlen = strlen(origname); + size_t newlen = origlen - patlen + replen; + char *rename = (char*) calloc (newlen + 1, sizeof(char)); + + if (start > 0) + { + strncpy(rename, origname, start); + pos += start; + } + + strncpy(rename + pos, replace, replen); + pos += replen; + + if (start + patlen < origlen) + { + ssize_t remaining = origlen-patlen; + strncpy(rename + pos, origname + start + patlen, remaining); + } + rename[newlen] = 0; + + renamed_elements[renamed_count] = element; + AddObjectToChangeNameUndoList (ELEMENT_TYPE, NULL, NULL, renamed_elements[renamed_count], origname); + ChangeObjectName (ELEMENT_TYPE, renamed_elements[renamed_count], NULL, NULL, rename); + renamed_count++; + } + } + else + { + status = BAD_REGEX; + } + } + } + END_LOOP; + } + else + { + status = BAD_REGEX; + } + regfree(&pattern); + } + + return status; +} +#endif /* --------------------------------------------------------------------------- */ static const char renumber_syntax[] = "Renumber()\n" @@ -8104,6 +8202,11 @@ HID_Action action_action_list[] = { {"RemoveSelected", 0, ActionRemoveSelected, removeselected_help, removeselected_syntax} , +#ifdef HAVE_REGEX_H + {"Resub", 0, ActionResub, + resub_help, resub_syntax} + , +#endif {"Renumber", 0, ActionRenumber, renumber_help, renumber_syntax} , --089e013d1ff8d3dc5804deccfcaf Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdj48ZGl2Pk9rIC0gaGVyZSYjMzk7IHMgbXkgcHJvcG9zZWQgY29t bWFuZCwgcmV3cml0dGVuIHRvIHVzZSByZWdleC4gSSByZWFsaXplZCB0aGF0IHRoZXJlIGlzIGEg dXNlY2FzZSBmb3IgcmVnZXggYmFzZWQgcmVwbGFjZW1lbnQsIHJhdGhlciB0aGFuIGp1c3Qgc2lt cGxlIHByZWZpeGluZy4gWW91IGNhbiBkbzo8YnI+PGJyPjwvZGl2PjpyZXN1YiBeIFMxLyA8YnI+ DQo8YnI+PC9kaXY+QW5kIGl0IHdpbGwgcHJlcGVuZCBTMS8gdG8gYWxsIHNlbGVjdGVkIHJlZmRl cy4gKGllLCBDMyBiZWNvbWVzIFMxL0MzKTxicj48YnI+oFRoaXMgaXMgaGFuZHkgZm9yIGRvaW5n IGJvYXJkIGxheW91dHMgd2l0aG91dCByZXNvcnRpbmcgdG8gdGhlIGR1bW15IHNjaGVtYXRpYyB3 b3JrZmxvdyBwcmVzZW50ZWQgaGVyZSBvbiB0aGlzIHRvcGljIGJlZm9yZS4gVGhlIHJlZ2V4IGNh biBvY2N1ciBhbnl3aGVyZSB3aXRoaW4gdGhlIG5hbWUuIFRoZSAybmQgYXJnIGNhbiBiZSBibGFu aywgYW5kIGl0IHdpbGwgcmVwbGFjZSB0aGUgcmVnZXggd2l0aCB0aGUgZW1wdHkgc3RyaW5nLiBU aGUgcmVwbGFjZW1lbnQgc3RyaW5nIGlzIGZpeGVkIC0gaXQgZG9lc24mIzM5O3QgZG8gYW55IGlu Y3JlbWVudGluZyBvciBpbnRlcnBvbGF0aW9uLiA8YnI+DQo8YnI+SSYjMzk7bSBub3Qgc3R1Y2sg b24gdGhlIGNvbW1hbmQgbmFtZSAtIEkganVzdCBuZWVkZWQgc29tZXRoaW5nIHRvIGdldCByb2xs aW5nICh0aGV5IHdvbiYjMzk7dCBsZXQgeW91IGxlYXZlIHRoZSBob3NwaXRhbCB3aXRob3V0IG5h bWluZyB5b3VyIGJhYnkpLqAgQW5kIHllcywgaXQgY29tcGlsZXMgd2l0aG91dCB3YXJuaW5ncy4g VGhlIGdjYy9yZWdleC5oL3Jlc3RyaWN0IHRoaW5nIHRvb2sgbWUgYSBtaW51dGUgdG8gZmlndXJl IG91dCwgYnV0IGFmdGVyIHRoYXQgbGFzdCBlbWFpbCB0byB0aGUgbGlzdCwgSSB3YXNuJiMzOTt0 IGFib3V0IHRvIGxldCBhbnkgd2FybmluZ3MgdGhyb3VnaCA6KTxicj4NCjxicj48YnI+ZGlmZiAt LWdpdCBhL3NyYy9hY3Rpb24uYyBiL3NyYy9hY3Rpb24uYzxicj5pbmRleCAxZDZkOGY5Li4yN2Ew N2VjIDEwMDY0NDxicj4tLS0gYS9zcmMvYWN0aW9uLmM8YnI+KysrIGIvc3JjL2FjdGlvbi5jPGJy PkBAIC03OCw2ICs3OCwxMCBAQDxicj6gI2luY2x1ZGUgJmx0O2RtYWxsb2MuaCZndDs8YnI+oCNl bmRpZjxicj6gPGJyPisjaWZkZWYgSEFWRV9SRUdFWF9IPGJyPg0KKyNpbmNsdWRlICZsdDtyZWdl eC5oJmd0Ozxicj4rI2VuZGlmPGJyPis8YnI+oC8qIGZvciBmb3JrKCkgYW5kIGZyaWVuZHMgKi88 YnI+oCNpZmRlZiBIQVZFX1VOSVNURF9IPGJyPqAjaW5jbHVkZSAmbHQ7dW5pc3RkLmgmZ3Q7PGJy PkBAIC0zMjE5LDYgKzMyMjMsMTAwIEBAIEFjdGlvblJlbW92ZVNlbGVjdGVkIChpbnQgYXJnYywg Y2hhciAqKmFyZ3YsIENvb3JkIHgsIENvb3JkIHkpPGJyPg0KoKAgcmV0dXJuIDA7PGJyPqB9PGJy PqA8YnI+Kzxicj4rI2lmZGVmIEhBVkVfUkVHRVhfSDxicj4rLyogLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t ICovPGJyPitzdGF0aWMgY29uc3QgY2hhciByZXN1Yl9zeW50YXhbXSA9ICZxdW90O1Jlc3ViKHBh dHRlcm4sIHJlcGxhY2VtZW50KVxuJnF1b3Q7Ozxicj4NCitzdGF0aWMgY29uc3QgY2hhciByZXN1 Yl9oZWxwW10gPSAmcXVvdDtSZW5hbWUgc2VsZWN0ZWQgdXNpbmcgcmVnZXggc3Vic3RpdHV0aW9u LiZxdW90Ozs8YnI+Kzxicj4rc3RhdGljIGludDxicj4rQWN0aW9uUmVzdWIgKGludCBhcmdjLCBj aGFyICoqYXJndiwgQ29vcmQgeCwgQ29vcmQgeSk8YnI+K3s8YnI+K6CgoCBlbnVtIHsgTk9FUlIg PSAwLCBFUlJPUiA9IC0xLCBCQURfUkVHRVggPSAtMn0gOzxicj4NCiugoKAgaW50oCBzdGF0dXMg PSBOT0VSUjs8YnI+K6CgoCBpZiAoYXJnYyA9PSAyKTxicj4roKCgIHs8YnI+K6CgoCCgoKAgY2hh ciAqcmF3cGF0ID0gQVJHKDApOzxicj4roKCgIKCgoCBjaGFyICpyZXBsYWNlID0gQVJHKDEpOzxi cj4roKCgIKCgoKAgc2l6ZV90IHNlbGVjdF9jb3VudCA9IDA7PGJyPiugoKAgoKCgIHNpemVfdCBy ZW5hbWVkX2NvdW50ID0gMDs8YnI+K6CgoCCgoKAgcmVnZXhfdCBwYXR0ZXJuOzxicj4NCisgoKCg IKCgoCBFbGVtZW50VHlwZSAqKnJlbmFtZWRfZWxlbWVudHM7PGJyPiugoKAgoKCgIDxicj4roKCg IKCgoCBpZiAocmVnY29tcCgmYW1wO3BhdHRlcm4sIHJhd3BhdCwgUkVHX0VYVEVOREVEKaAgPT0g UkVHX05PRVJST1IpIDxicj4roKCgIKCgoCB7PGJyPiugoKAgoKCgIKCgoCAvLyBzaXplIHRoZSBl bG1lbnRzIHRvIGJlIHJlbmFtZWQ8YnI+K6CgoCCgoKAgoKCgIEVMRU1FTlRfTE9PUCAoUENCLSZn dDtEYXRhKTs8YnI+DQoroKCgIKCgoCCgoKAgezxicj4roKCgIKCgoCCgoKAgoKCgIGlmIChURVNU X0ZMQUcgKFNFTEVDVEVERkxBRywgZWxlbWVudCkpPGJyPiugoKAgoKCgIKCgoCCgoKAgc2VsZWN0 X2NvdW50Kys7PGJyPiugoKAgoKCgIKCgoCB9PGJyPiugoKAgoKCgIKCgoCBFTkRfTE9PUDs8YnI+ Kzxicj4roKCgIKCgoCCgoKAgLy8gY29sbGVjdCBzZWxlY3RlZCBlbGVtZW50cyBmb3IgcmVuYW1p bmc8YnI+K6CgoCCgoKAgoKCgIHJlbmFtZWRfZWxlbWVudHMgPSAoRWxlbWVudFR5cGUgKiopY2Fs bG9jIChzZWxlY3RfY291bnQsIHNpemVvZiAoRWxlbWVudFR5cGUgKikpOzxicj4NCiugoKAgoKCg IKCgoCBFTEVNRU5UX0xPT1AgKFBDQi0mZ3Q7RGF0YSk7PGJyPiugoKAgoKCgIKCgoCB7IDxicj4r oKCgIKCgoCCgoKAgoKCgIGlmIChURVNUX0ZMQUcgKFNFTEVDVEVERkxBRywgZWxlbWVudCkpPGJy PiugoKAgoKCgIKCgoCCgoKAgezxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCBjaGFyICpvcmlnbmFt ZSA9IE5BTUVPTlBDQl9OQU1FIChlbGVtZW50KTs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgY29u c3Qgc2l6ZV90IG5tYXRjaCA9IDE7PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgcmVnbWF0Y2hf dCBtYXRjaGVzW25tYXRjaF07PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIDxicj4roKCgIKCgoCCg oKAgoKCgIKCgoCBpZiAob3JpZ25hbWUgJmFtcDsmYW1wOyByZWdleGVjKCZhbXA7cGF0dGVybiwg b3JpZ25hbWUsoCBubWF0Y2gsIChyZWdtYXRjaF90ICogcmVzdHJpY3QpIG1hdGNoZXMsIDApID09 IDApPGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIHugoKAgPGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCg oKAgoKCgIHJlZ21hdGNoX3QgKm1hdGNoID0gJmFtcDttYXRjaGVzWzBdOzxicj4roKCgIKCgoCCg oKAgoKCgIKCgoCCgoKAgaWYgKG1hdGNoLSZndDtybV9zbyAhPSAtMSk8YnI+K6CgoCCgoKAgoKCg IKCgoCCgoKAgoKCgIHs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBzaXplX3QgcG9z ID0gMDs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBzaXplX3Qgc3RhcnQgPSBtYXRj aC0mZ3Q7cm1fc287PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBzaXplX3QgZW5k ID0gbWF0Y2gtJmd0O3JtX2VvOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHNpemVf dCBwYXRsZW4gPSBlbmQgLSBzdGFydDs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBz aXplX3QgcmVwbGVuID0gc3RybGVuKHJlcGxhY2UpOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCg oKAgoKCgIHNpemVfdCBvcmlnbGVuID0gc3RybGVuKG9yaWduYW1lKTs8YnI+DQoroKCgIKCgoCCg oKAgoKCgIKCgoCCgoKAgoKCgIHNpemVfdCBuZXdsZW4gPSBvcmlnbGVuIC0gcGF0bGVuICsgcmVw bGVuOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIGNoYXKgICpyZW5hbWUgPSAoY2hh ciopIGNhbGxvYyAobmV3bGVuICsgMSwgc2l6ZW9mKGNoYXIpKTs8YnI+Kzxicj4roKCgIKCgoCCg oKAgoKCgIKCgoCCgoKAgoKCgIGlmIChzdGFydCAmZ3Q7IDApPGJyPg0KK6CgoCCgoKAgoKCgIKCg oCCgoKAgoKCgIKCgoCB7PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHN0cm5j cHkocmVuYW1lLCBvcmlnbmFtZSwgc3RhcnQpOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAg oKCgIKCgoCBwb3MgKz0gc3RhcnQ7PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgfTxi cj4rPGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgc3RybmNweShyZW5hbWUgKyBwb3Ms IHJlcGxhY2UsIHJlcGxlbik7PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBwb3Mg Kz0gcmVwbGVuOzxicj4rPGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgaWYgKHN0YXJ0 ICsgcGF0bGVuICZsdDsgb3JpZ2xlbik8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCB7 PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHNzaXplX3QgcmVtYWluaW5nID0g b3JpZ2xlbi1wYXRsZW47PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgc3Ry bmNweShyZW5hbWUgKyBwb3MsIG9yaWduYW1lICsgc3RhcnQgKyBwYXRsZW4sIHJlbWFpbmluZyk7 PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgfTxicj4roKCgIKCgoCCgoKAgoKCgIKCg oCCgoKAgoKCgIHJlbmFtZVtuZXdsZW5dID0gMDs8YnI+Kzxicj4roKCgIKCgoCCgoKAgoKCgIKCg oCCgoKAgoKCgIHJlbmFtZWRfZWxlbWVudHNbcmVuYW1lZF9jb3VudF0gPSBlbGVtZW50Ozxicj4N CiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgQWRkT2JqZWN0VG9DaGFuZ2VOYW1lVW5kb0xp c3QgKEVMRU1FTlRfVFlQRSwgTlVMTCwgTlVMTCwgcmVuYW1lZF9lbGVtZW50c1tyZW5hbWVkX2Nv dW50XSwgb3JpZ25hbWUpOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIENoYW5nZU9i amVjdE5hbWUgKEVMRU1FTlRfVFlQRSwgcmVuYW1lZF9lbGVtZW50c1tyZW5hbWVkX2NvdW50XSwg TlVMTCwgTlVMTCwgcmVuYW1lKTs8YnI+DQoroKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHJl bmFtZWRfY291bnQrKzs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIH08YnI+K6CgoCCgoKAg oKCgIKCgoCCgoKAgfTxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCBlbHNlPGJyPiugoKAgoKCgIKCg oCCgoKAgoKCgIHs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHN0YXR1cyA9IEJBRF9SRUdF WDs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgfTxicj4NCiugoKAgoKCgIKCgoCCgoKAgfTxicj4r oKCgIKCgoCCgoKAgfTxicj4roKCgIKCgoCCgoKAgRU5EX0xPT1A7PGJyPiugoKAgoKCgIH08YnI+ K6CgoCCgoKAgZWxzZTxicj4roKCgIKCgoCB7PGJyPiugoKAgoKCgIKCgoCBzdGF0dXMgPSBCQURf UkVHRVg7PGJyPiugoKAgoKCgIH08YnI+K6CgoCCgoKAgcmVnZnJlZSgmYW1wO3BhdHRlcm4pOzxi cj4roKCgIH08YnI+Kzxicj4rIKCgoCByZXR1cm4gc3RhdHVzOzxicj4NCit9PGJyPisjZW5kaWY8 YnI+oC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLzxicj6gPGJyPqBzdGF0aWMgY29uc3QgY2hhciBy ZW51bWJlcl9zeW50YXhbXSA9ICZxdW90O1JlbnVtYmVyKClcbiZxdW90Ozxicj5AQCAtODEwNCw2 ICs4MjAyLDExIEBAIEhJRF9BY3Rpb24gYWN0aW9uX2FjdGlvbl9saXN0W10gPSB7PGJyPg0KoKAg eyZxdW90O1JlbW92ZVNlbGVjdGVkJnF1b3Q7LCAwLCBBY3Rpb25SZW1vdmVTZWxlY3RlZCw8YnI+ oKCgIHJlbW92ZXNlbGVjdGVkX2hlbHAsIHJlbW92ZXNlbGVjdGVkX3N5bnRheH08YnI+oKAgLDxi cj4rI2lmZGVmIEhBVkVfUkVHRVhfSDxicj4roCB7JnF1b3Q7UmVzdWImcXVvdDssIDAsIEFjdGlv blJlc3ViLDxicj4roKAgcmVzdWJfaGVscCwgcmVzdWJfc3ludGF4fTxicj4roCAsPGJyPg0KKyNl bmRpZjxicj6goCB7JnF1b3Q7UmVudW1iZXImcXVvdDssIDAsIEFjdGlvblJlbnVtYmVyLDxicj6g oKAgcmVudW1iZXJfaGVscCwgcmVudW1iZXJfc3ludGF4fTxicj6goCAsPGJyPjxicj48L2Rpdj4N Cg== --089e013d1ff8d3dc5804deccfcaf--