Bug 497722 Address auto-complete gives random order, not based on frequency after upgrading from Thunderbird 2 to Thunderbird 3 (autocomplete). r/sr=bienvenu
This commit is contained in:
Родитель
2ba9d592d9
Коммит
ed30efc057
|
@ -115,6 +115,41 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
|
||||
// Private methods
|
||||
|
||||
/**
|
||||
* Returns the popularity index for a given card. This takes account of a
|
||||
* translation bug whereby Thunderbird 2 stores its values in mork as
|
||||
* hexadecimal, and Thunderbird 3 stores as decimal.
|
||||
*
|
||||
* @param aDirectory The directory that the card is in.
|
||||
* @param aCard The card to return the popularity index for.
|
||||
*/
|
||||
_getPopularityIndex: function _getPopularityIndex(aDirectory, aCard) {
|
||||
let popularityValue = aCard.getProperty("PopularityIndex", "0");
|
||||
let popularityIndex = parseInt(popularityValue);
|
||||
|
||||
// If we haven't parsed it the first time round, parse it as hexadecimal
|
||||
// and repair so that we don't have to keep repairing.
|
||||
if (isNaN(popularityIndex)) {
|
||||
popularityIndex = parseInt(popularityValue, 16);
|
||||
|
||||
// If its still NaN, just give up, we shouldn't ever get here.
|
||||
if (isNaN(popularityIndex))
|
||||
popularityIndex = 0;
|
||||
|
||||
// Now store this change so that we're not changing it each time around.
|
||||
if (!aDirectory.readOnly) {
|
||||
aCard.setProperty("PopularityIndex", popularityIndex);
|
||||
try {
|
||||
aDirectory.modifyCard(aCard);
|
||||
}
|
||||
catch (ex) {
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return popularityIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches cards in the given directory. It is not expected to search against
|
||||
* email addresses (use _searchWithinEmails). If a card is matched (and isn't
|
||||
|
@ -138,15 +173,15 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
|
||||
if (card instanceof Components.interfaces.nsIAbCard) {
|
||||
if (card.isMailList)
|
||||
this._addToResult(commentColumn, card, "", result);
|
||||
this._addToResult(commentColumn, directory, card, "", result);
|
||||
else {
|
||||
let email = card.primaryEmail;
|
||||
if (email)
|
||||
this._addToResult(commentColumn, card, email, result);
|
||||
this._addToResult(commentColumn, directory, card, email, result);
|
||||
|
||||
email = card.getProperty("SecondEmail", "");
|
||||
if (email)
|
||||
this._addToResult(commentColumn, card, email, result);
|
||||
this._addToResult(commentColumn, directory, card, email, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,17 +212,17 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
|
||||
if (card instanceof Components.interfaces.nsIAbCard) {
|
||||
if (card.isMailList)
|
||||
this._addToResult(commentColumn, card, "", result);
|
||||
this._addToResult(commentColumn, directory, card, "", result);
|
||||
else {
|
||||
let email = card.primaryEmail;
|
||||
if (email && email.toLocaleLowerCase()
|
||||
.lastIndexOf(fullString, 0) == 0)
|
||||
this._addToResult(commentColumn, card, email, result);
|
||||
this._addToResult(commentColumn, directory, card, email, result);
|
||||
|
||||
email = card.getProperty("SecondEmail", "");
|
||||
if (email && email.toLocaleLowerCase()
|
||||
.lastIndexOf(fullString, 0) == 0)
|
||||
this._addToResult(commentColumn, card, email, result);
|
||||
this._addToResult(commentColumn, directory, card, email, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,15 +276,17 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
* will remove the existing element if the popularity of the new card is
|
||||
* higher than the previous card.
|
||||
*
|
||||
* @param directory The directory that the card is in.
|
||||
* @param card The card that could be a duplicate.
|
||||
* @param emailAddress The emailAddress (name/address combination) to check
|
||||
* for duplicates against.
|
||||
* @param currentResults The current results list.
|
||||
*/
|
||||
_checkDuplicate: function _checkDuplicate(card, emailAddress, currentResults) {
|
||||
_checkDuplicate: function _checkDuplicate(directory, card, emailAddress,
|
||||
currentResults) {
|
||||
var lcEmailAddress = emailAddress.toLocaleLowerCase();
|
||||
|
||||
var popIndex = parseInt(card.getProperty("PopularityIndex", "0"));
|
||||
var popIndex = this._getPopularityIndex(directory, card);
|
||||
for (var i = 0; i < currentResults._searchResults.length; ++i) {
|
||||
if (currentResults._searchResults[i].value.toLocaleLowerCase() ==
|
||||
lcEmailAddress)
|
||||
|
@ -275,12 +312,14 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
*
|
||||
* @param commentColumn The text to be displayed in the comment column
|
||||
* (if any).
|
||||
* @param directory The directory that the card is in.
|
||||
* @param card The card being added to the results.
|
||||
* @param emailToUse The email address from the card that should be used
|
||||
* for this result.
|
||||
* @param result The result to add the new entry to.
|
||||
*/
|
||||
_addToResult: function _addToResult(commentColumn, card, emailToUse, result) {
|
||||
_addToResult: function _addToResult(commentColumn, directory, card,
|
||||
emailToUse, result) {
|
||||
var emailAddress =
|
||||
this._parser.makeFullAddress(card.displayName,
|
||||
card.isMailList ?
|
||||
|
@ -295,13 +334,12 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
|
||||
// If it is a duplicate, then just return and don't add it. The
|
||||
// _checkDuplicate function deals with it all for us.
|
||||
if (this._checkDuplicate(card, emailAddress, result))
|
||||
if (this._checkDuplicate(directory, card, emailAddress, result))
|
||||
return;
|
||||
|
||||
// Find out where to insert the card.
|
||||
var insertPosition = 0;
|
||||
// Hack - mork adds in as a string, but we want to get as an integer...
|
||||
var cardPopularityIndex = parseInt(card.getProperty("PopularityIndex", "0"));
|
||||
var cardPopularityIndex = this._getPopularityIndex(directory, card);
|
||||
|
||||
while (insertPosition < result._searchResults.length &&
|
||||
cardPopularityIndex <
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* This suite ensures that we can correctly read and re-set the popularity
|
||||
* indexes on a
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const ACR = Components.interfaces.nsIAutoCompleteResult;
|
||||
|
||||
const results = [ { email: "d <ema@test.invalid>", dirName: kPABData.dirName },
|
||||
{ email: "di <emai@test.invalid>", dirName: kPABData.dirName },
|
||||
{ email: "dis <email@test.invalid>", dirName: kPABData.dirName },
|
||||
{ email: "disp <e@test.invalid>", dirName: kPABData.dirName },
|
||||
{ email: "displ <em@test.invalid>", dirName: kPABData.dirName },
|
||||
{ email: "t <list>", dirName: kPABData.dirName },
|
||||
{ email: "te <lis>", dirName: kPABData.dirName },
|
||||
{ email: "tes <li>", dirName: kPABData.dirName },
|
||||
{ email: "test <l>", dirName: kPABData.dirName } ];
|
||||
|
||||
const firstNames = [ { search: "f", expected: [4, 0, 1, 2, 3] },
|
||||
{ search: "fi", expected: [4, 0, 1, 3] },
|
||||
{ search: "fir", expected: [4, 0, 1] },
|
||||
{ search: "firs", expected: [0, 1] },
|
||||
{ search: "first", expected: [1] } ];
|
||||
|
||||
const lastNames = [ { search: "l", expected: [4, 0, 1, 2, 3, 5, 6, 7, 8] },
|
||||
{ search: "la", expected: [4, 0, 2, 3] },
|
||||
{ search: "las", expected: [4, 0, 3] },
|
||||
{ search: "last", expected: [4, 0] },
|
||||
{ search: "lastn", expected: [0] } ];
|
||||
|
||||
const inputs = [ firstNames, lastNames];
|
||||
|
||||
function acObserver() {}
|
||||
|
||||
acObserver.prototype = {
|
||||
_search: null,
|
||||
_result: null,
|
||||
|
||||
onSearchResult: function (aSearch, aResult) {
|
||||
this._search = aSearch;
|
||||
this._result = aResult;
|
||||
}
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
// Copy the data files into place
|
||||
let testAB = do_get_file("../../mailnews/data/tb2hexpopularity.mab");
|
||||
|
||||
testAB.copyTo(gProfileDir, kPABData.fileName);
|
||||
|
||||
// Test - Create a new search component
|
||||
|
||||
let acs = Components.classes["@mozilla.org/autocomplete/search;1?name=addrbook"]
|
||||
.getService(Components.interfaces.nsIAutoCompleteSearch);
|
||||
|
||||
let obs = new acObserver();
|
||||
|
||||
// Ensure we've got the comment column set up for extra checking.
|
||||
let prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
prefSvc.setIntPref("mail.autoComplete.commentColumn", 1);
|
||||
|
||||
// Test - Matches
|
||||
|
||||
// Now check multiple matches
|
||||
function checkInputItem(element, index, array) {
|
||||
print("Checking " + element.search);
|
||||
acs.startSearch(element.search, null, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, element.search);
|
||||
do_check_eq(obs._result.searchResult, ACR.RESULT_SUCCESS);
|
||||
do_check_eq(obs._result.errorDescription, null);
|
||||
do_check_eq(obs._result.matchCount, element.expected.length);
|
||||
do_check_eq(obs._result.defaultIndex, 0);
|
||||
|
||||
for (let i = 0; i < element.expected.length; ++i) {
|
||||
do_check_eq(obs._result.getValueAt(i), results[element.expected[i]].email);
|
||||
do_check_eq(obs._result.getCommentAt(i), results[element.expected[i]].dirName);
|
||||
do_check_eq(obs._result.getStyleAt(i), "local-abook");
|
||||
do_check_eq(obs._result.getImageAt(i), "");
|
||||
|
||||
// Card at result number 4 is the one with the TB 2 popularity set as "a"
|
||||
// in the file, so check that we're now setting the popularity to 10
|
||||
// and hence future tests don't have to convert it.
|
||||
if (element.expected[i] == 4) {
|
||||
let result = obs._result.QueryInterface(Ci.nsIAbAutoCompleteResult);
|
||||
do_check_eq(result.getCardAt(i).getProperty("PopularityIndex", -1), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
function checkInputSet(element, index, array) {
|
||||
element.forEach(checkInputItem);
|
||||
}
|
||||
|
||||
inputs.forEach(checkInputSet);
|
||||
};
|
|
@ -4790,9 +4790,33 @@ nsMsgCompose::CheckAndPopulateRecipients(PRBool aPopulateMailList,
|
|||
|
||||
// bump the popularity index for this card since we are about to send e-mail to it
|
||||
PRUint32 popularityIndex = 0;
|
||||
if (!readOnly && NS_SUCCEEDED(existingCard->GetPropertyAsUint32(
|
||||
kPopularityIndexProperty, &popularityIndex)))
|
||||
if (!readOnly)
|
||||
{
|
||||
if (NS_FAILED(existingCard->GetPropertyAsUint32(
|
||||
kPopularityIndexProperty, &popularityIndex)))
|
||||
{
|
||||
// TB 2 wrote the popularity value as hex, so if we get here,
|
||||
// then we've probably got a hex value. We'll convert it back
|
||||
// to decimal, as that's the best we can do.
|
||||
|
||||
nsCString hexPopularity;
|
||||
if (NS_SUCCEEDED(existingCard->GetPropertyAsAUTF8String(kPopularityIndexProperty, hexPopularity)))
|
||||
{
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
PRInt32 errorCode = 0;
|
||||
#else
|
||||
nsresult errorCode = NS_OK;
|
||||
#endif
|
||||
popularityIndex = hexPopularity.ToInteger(&errorCode, 16);
|
||||
if (errorCode)
|
||||
// We failed, just set it to zero.
|
||||
popularityIndex = 0;
|
||||
}
|
||||
else
|
||||
// We couldn't get it as a string either, so just reset to
|
||||
// zero.
|
||||
popularityIndex = 0;
|
||||
}
|
||||
|
||||
existingCard->SetPropertyAsUint32(kPopularityIndexProperty,
|
||||
++popularityIndex);
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* Test suite for increasing the popularity of contacts via
|
||||
* checkAndPopulateRecipients.
|
||||
*/
|
||||
|
||||
// We need the address book details for this test
|
||||
load("../../mailnews/resources/abSetup.js");
|
||||
|
||||
const MsgComposeContractID = "@mozilla.org/messengercompose/compose;1";
|
||||
const MsgComposeParamsContractID = "@mozilla.org/messengercompose/composeparams;1";
|
||||
const MsgComposeFieldsContractID = "@mozilla.org/messengercompose/composefields;1";
|
||||
|
||||
const TESTS = [
|
||||
{
|
||||
email: "em@test.invalid",
|
||||
// TB 2 stored popularity as hex, so we need to check correct handling.
|
||||
prePopularity: "a",
|
||||
postPopularity: "11"
|
||||
},
|
||||
{
|
||||
email: "e@test.invalid",
|
||||
prePopularity: "0",
|
||||
postPopularity: "1"
|
||||
},
|
||||
{
|
||||
email: "e@test.invalid",
|
||||
prePopularity: "1",
|
||||
postPopularity: "2"
|
||||
},
|
||||
{
|
||||
email: "em@test.invalid",
|
||||
prePopularity: "11",
|
||||
postPopularity: "12"
|
||||
}
|
||||
];
|
||||
|
||||
function checkPopulate(aTo, aNonHTMLRecipients, aPreferMailOut, aCheckTo)
|
||||
{
|
||||
let msgCompose = Cc[MsgComposeContractID].createInstance(Ci.nsIMsgCompose);
|
||||
|
||||
// Set up some basic fields for compose.
|
||||
let fields = Cc[MsgComposeFieldsContractID].createInstance(Ci.nsIMsgCompFields);
|
||||
|
||||
fields.to = aTo;
|
||||
|
||||
// Set up some params
|
||||
let params = Cc[MsgComposeParamsContractID]
|
||||
.createInstance(Ci.nsIMsgComposeParams);
|
||||
|
||||
params.composeFields = fields;
|
||||
|
||||
msgCompose.Initialize(null, params);
|
||||
|
||||
let nonHTMLRecipients = new Object();
|
||||
|
||||
do_check_eq(msgCompose.checkAndPopulateRecipients(true, true,
|
||||
nonHTMLRecipients),
|
||||
aPreferMailOut);
|
||||
|
||||
do_check_eq(fields.to, aCheckTo);
|
||||
|
||||
do_check_eq(nonHTMLRecipients.value, aNonHTMLRecipients);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
// Test setup - copy the data files into place
|
||||
let testAB = do_get_file("../../mailnews/data/tb2hexpopularity.mab");
|
||||
|
||||
// Copy the file to the profile directory for a PAB
|
||||
testAB.copyTo(gProfileDir, kPABData.fileName);
|
||||
|
||||
// Check the popularity index on a couple of cards.
|
||||
let abManager = Cc["@mozilla.org/abmanager;1"].getService(Ci.nsIAbManager);
|
||||
|
||||
let AB = abManager.getDirectory(kPABData.URI);
|
||||
|
||||
for (let i = 0; i < TESTS.length; ++i) {
|
||||
let card = AB.cardForEmailAddress(TESTS[i].email);
|
||||
do_check_true(!!card);
|
||||
|
||||
// Thunderbird 2 stored its popularityIndexes as hex, hence when we read it
|
||||
// now we're going to get a hex value. The AB has a value of "a".
|
||||
do_check_eq(card.getProperty("PopularityIndex", -1), TESTS[i].prePopularity);
|
||||
|
||||
// Call the check populate function.
|
||||
checkPopulate(TESTS[i].email, TESTS[i].email,
|
||||
Ci.nsIAbPreferMailFormat.unknown, TESTS[i].email);
|
||||
|
||||
// Now we've run check populate, check the popularityIndex has increased.
|
||||
card = AB.cardForEmailAddress(TESTS[i].email);
|
||||
do_check_true(!!card);
|
||||
|
||||
// Thunderbird 2 stored its popularityIndexes as hex, hence when we read it
|
||||
// now we're going to get a hex value. The AB has a value of "a".
|
||||
do_check_eq(card.getProperty("PopularityIndex", -1), TESTS[i].postPopularity);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
// <!-- <mdb:mork:z v="1.4"/> -->
|
||||
< <(a=c)> // (f=iso-8859-1)
|
||||
(B8=Custom2)(B9=Custom3)(BA=Custom4)(BB=Notes)(BC=LastModifiedDate)
|
||||
(BD=RecordKey)(BE=AddrCharSet)(BF=LastRecordKey)
|
||||
(C0=ns:addrbk:db:table:kind:pab)(C1=ListName)(C2=ListNickName)
|
||||
(C3=ListDescription)(C4=ListTotalAddresses)(C5=LowercaseListName)
|
||||
(C6=ns:addrbk:db:table:kind:deleted)
|
||||
(80=ns:addrbk:db:row:scope:card:all)
|
||||
(81=ns:addrbk:db:row:scope:list:all)
|
||||
(82=ns:addrbk:db:row:scope:data:all)(83=FirstName)(84=LastName)
|
||||
(85=PhoneticFirstName)(86=PhoneticLastName)(87=DisplayName)
|
||||
(88=NickName)(89=PrimaryEmail)(8A=LowercasePrimaryEmail)
|
||||
(8B=SecondEmail)(8C=DefaultEmail)(8D=CardType)(8E=PreferMailFormat)
|
||||
(8F=PopularityIndex)(90=AllowRemoteContent)(91=WorkPhone)(92=HomePhone)
|
||||
(93=FaxNumber)(94=PagerNumber)(95=CellularNumber)(96=WorkPhoneType)
|
||||
(97=HomePhoneType)(98=FaxNumberType)(99=PagerNumberType)
|
||||
(9A=CellularNumberType)(9B=HomeAddress)(9C=HomeAddress2)(9D=HomeCity)
|
||||
(9E=HomeState)(9F=HomeZipCode)(A0=HomeCountry)(A1=WorkAddress)
|
||||
(A2=WorkAddress2)(A3=WorkCity)(A4=WorkState)(A5=WorkZipCode)
|
||||
(A6=WorkCountry)(A7=JobTitle)(A8=Department)(A9=Company)
|
||||
(AA=_AimScreenName)(AB=AnniversaryYear)(AC=AnniversaryMonth)
|
||||
(AD=AnniversaryDay)(AE=SpouseName)(AF=FamilyName)(B0=DefaultAddress)
|
||||
(B1=Category)(B2=WebPage1)(B3=WebPage2)(B4=BirthYear)(B5=BirthMonth)
|
||||
(B6=BirthDay)(B7=Custom1)>
|
||||
|
||||
<(A8=8)(81=firs)(82=lastn)(83=)(84=d)(85=ni)(86=ema@test.invalid)(80=0)
|
||||
(87=1)(88=first)(89=l)(8A=di)(8B=nic)(8C=emai@test.invalid)(8D=2)(8E=f)
|
||||
(8F=la)(90=dis)(91=nick)(92=email@test.invalid)(93=3)(94=fi)(95=las)
|
||||
(96=disp)(97=nickn)(98=e@test.invalid)(99=4)(9A=fir)(9B=last)(9C=displ)
|
||||
(9D=n)(9E=em@test.invalid)(9F=5)(A0=t)(A1=list)(A2=6)(A3=te)(A4=lis)
|
||||
(A5=7)(A6=tes)(A7=li)>
|
||||
{1:^80 {(k^C0:c)(s=9)}
|
||||
[1:^82(^BF=8)]
|
||||
[1(^83^81)(^84^82)(^85=)(^86=)(^87=d)(^88=ni)(^89^86)(^8A^86)(^8B=)
|
||||
(^8C=)(^8D=)(^8E=0)(^8F=0)(^90=0)(^91=)(^92=)(^93=)(^94=)(^95=)
|
||||
(^96=)(^97=)(^98=)(^99=)(^9A=)(^9B=)(^9C=)(^9D=)(^9E=)(^9F=)(^A0=)
|
||||
(^A1=)(^A2=)(^A3=)(^A4=)(^A5=)(^A6=)(^A7=)(^A8=)(^A9=)(^AA=)(^AB=)
|
||||
(^AC=)(^AD=)(^AE=)(^AF=)(^B0=)(^B1=)(^B2=)(^B3=)(^B4=)(^B5=)(^B6=)
|
||||
(^B7=)(^B8=)(^B9=)(^BA=)(^BB=)(^BC=0)(^BD=1)]
|
||||
[2(^83^88)(^84=l)(^85=)(^86=)(^87=di)(^88^8B)(^89^8C)(^8A^8C)(^8B=)
|
||||
(^8C=)(^8D=)(^8E=0)(^8F=0)(^90=0)(^91=)(^92=)(^93=)(^94=)(^95=)
|
||||
(^96=)(^97=)(^98=)(^99=)(^9A=)(^9B=)(^9C=)(^9D=)(^9E=)(^9F=)(^A0=)
|
||||
(^A1=)(^A2=)(^A3=)(^A4=)(^A5=)(^A6=)(^A7=)(^A8=)(^A9=)(^AA=)(^AB=)
|
||||
(^AC=)(^AD=)(^AE=)(^AF=)(^B0=)(^B1=)(^B2=)(^B3=)(^B4=)(^B5=)(^B6=)
|
||||
(^B7=)(^B8=)(^B9=)(^BA=)(^BB=)(^BC=0)(^BD=2)]
|
||||
[3(^83=f)(^84=la)(^85=)(^86=)(^87^90)(^88^91)(^89^92)(^8A^92)(^8B=)
|
||||
(^8C=)(^8D=)(^8E=0)(^8F=0)(^90=0)(^91=)(^92=)(^93=)(^94=)(^95=)
|
||||
(^96=)(^97=)(^98=)(^99=)(^9A=)(^9B=)(^9C=)(^9D=)(^9E=)(^9F=)(^A0=)
|
||||
(^A1=)(^A2=)(^A3=)(^A4=)(^A5=)(^A6=)(^A7=)(^A8=)(^A9=)(^AA=)(^AB=)
|
||||
(^AC=)(^AD=)(^AE=)(^AF=)(^B0=)(^B1=)(^B2=)(^B3=)(^B4=)(^B5=)(^B6=)
|
||||
(^B7=)(^B8=)(^B9=)(^BA=)(^BB=)(^BC=0)(^BD=3)]
|
||||
[4(^83=fi)(^84^95)(^85=)(^86=)(^87^96)(^88^97)(^89^98)(^8A^98)(^8B=)
|
||||
(^8C=)(^8D=)(^8E=0)(^8F=0)(^90=0)(^91=)(^92=)(^93=)(^94=)(^95=)
|
||||
(^96=)(^97=)(^98=)(^99=)(^9A=)(^9B=)(^9C=)(^9D=)(^9E=)(^9F=)(^A0=)
|
||||
(^A1=)(^A2=)(^A3=)(^A4=)(^A5=)(^A6=)(^A7=)(^A8=)(^A9=)(^AA=)(^AB=)
|
||||
(^AC=)(^AD=)(^AE=)(^AF=)(^B0=)(^B1=)(^B2=)(^B3=)(^B4=)(^B5=)(^B6=)
|
||||
(^B7=)(^B8=)(^B9=)(^BA=)(^BB=)(^BC=0)(^BD=4)]
|
||||
[5(^83^9A)(^84^9B)(^85=)(^86=)(^87^9C)(^88=n)(^89^9E)(^8A^9E)(^8B=)
|
||||
(^8C=)(^8D=)(^8E=0)(^8F=1)(^90=0)(^91=)(^92=)(^93=)(^94=)(^95=)
|
||||
(^96=)(^97=)(^98=)(^99=)(^9A=)(^9B=)(^9C=)(^9D=)(^9E=)(^9F=)(^A0=)
|
||||
(^A1=)(^A2=)(^A3=)(^A4=)(^A5=)(^A6=)(^A7=)(^A8=)(^A9=)(^AA=)(^AB=)
|
||||
(^AC=)(^AD=)(^AE=)(^AF=)(^B0=)(^B1=)(^B2=)(^B3=)(^B4=)(^B5=)(^B6=)
|
||||
(^B7=)(^B8=)(^B9=)(^BA=)(^BB=)(^BC=0)(^BD=5)]
|
||||
[1:^81(^C1=t)(^C5=t)(^C2=)(^C3^A1)(^C4=0)(^BD=6)]
|
||||
[2:^81(^C1=te)(^C5=te)(^C2=)(^C3^A4)(^C4=0)(^BD=7)]
|
||||
[3:^81(^C1^A6)(^C5^A6)(^C2=)(^C3=li)(^C4=0)(^BD=8)]}
|
||||
|
||||
@$${7{@
|
||||
|
||||
<(AB=9)(A9=test)(AA=abcdef)>
|
||||
{1:^80 {(k^C0:c)(s=9)}
|
||||
[-4:^81(^C1^A9)(^C5^A9)(^C2^AA)(^C3=l)(^C4=0)(^BD=9)]}
|
||||
[1:^82(^BF=9)]
|
||||
@$$}7}@
|
||||
|
||||
@$${9{@
|
||||
<(AC=4b683ded)>[-5:^80(^83^9A)(^84^9B)(^85=)(^86=)(^87^9C)(^88=n)(^89^9E)
|
||||
(^8A^9E)(^8B=)(^8C=)(^8D=)(^8E=0)(^8F=9)(^90=0)(^91=)(^92=)(^93=)
|
||||
(^94=)(^95=)(^96=)(^97=)(^98=)(^99=)(^9A=)(^9B=)(^9C=)(^9D=)(^9E=)
|
||||
(^9F=)(^A0=)(^A1=)(^A2=)(^A3=)(^A4=)(^A5=)(^A6=)(^A7=)(^A8=)(^A9=)
|
||||
(^AA=)(^AB=)(^AC=)(^AD=)(^AE=)(^AF=)(^B0=)(^B1=)(^B2=)(^B3=)(^B4=)
|
||||
(^B5=)(^B6=)(^B7=)(^B8=)(^B9=)(^BA=)(^BB=)(^BC^AC)(^BD=5)]
|
||||
@$$}9}@
|
||||
|
||||
@$${B{@
|
||||
<(AD=a)(AE=4b6840f5)>[-5:^80(^83^9A)(^84^9B)(^85=)(^86=)(^87^9C)(^88=n)
|
||||
(^89^9E)(^8A^9E)(^8B=)(^8C=)(^8D=)(^8E=0)(^8F=a)(^90=0)(^91=)(^92=)
|
||||
(^93=)(^94=)(^95=)(^96=)(^97=)(^98=)(^99=)(^9A=)(^9B=)(^9C=)(^9D=)
|
||||
(^9E=)(^9F=)(^A0=)(^A1=)(^A2=)(^A3=)(^A4=)(^A5=)(^A6=)(^A7=)(^A8=)
|
||||
(^A9=)(^AA=)(^AB=)(^AC=)(^AD=)(^AE=)(^AF=)(^B0=)(^B1=)(^B2=)(^B3=)
|
||||
(^B4=)(^B5=)(^B6=)(^B7=)(^B8=)(^B9=)(^BA=)(^BB=)(^BC^AE)(^BD=5)]
|
||||
@$$}B}@
|
Загрузка…
Ссылка в новой задаче