Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 25 Nov 2013 14:25:48 -0500
changeset 157498 0e0787161168d8380013b7612838fb28fb67767a
parent 157497 2c71d40fbee0ce1d35c54d77bf5daff85020ed21 (current diff)
parent 157421 53d55d2d0a25282cca238e6df17b68b3513f9430 (diff)
child 157499 763b04634768aa15d450a8673949eb614593face
push id36742
push usercbook@mozilla.com
push dateTue, 26 Nov 2013 13:00:12 +0000
treeherdermozilla-inbound@28624ec0e7c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team.
dom/encoding/test/unit/test_iso-2022-kr.js
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Bug 941844 - Because Android resource builds are flaky.
+Bug 921918 - need clobber for Windows.
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "2a055e0d4214f04646c15c09a6a03bf96f347689", 
+    "revision": "aac07cb753d6c364c3cbd39ad8116d455d5adf01", 
     "repo_path": "/integration/gaia-central"
 }
--- a/content/base/src/EventSource.cpp
+++ b/content/base/src/EventSource.cpp
@@ -263,17 +263,18 @@ EventSource::Init(nsISupports* aOwner,
   mReconnectionTime =
     Preferences::GetInt("dom.server-events.default-reconnection-time",
                         DEFAULT_RECONNECTION_TIME_VALUE);
 
   nsCOMPtr<nsICharsetConverterManager> convManager =
     do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = convManager->GetUnicodeDecoder("UTF-8", getter_AddRefs(mUnicodeDecoder));
+  rv = convManager->GetUnicodeDecoderRaw("UTF-8",
+                                         getter_AddRefs(mUnicodeDecoder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // the constructor should throw a SYNTAX_ERROR only if it fails resolving the
   // url parameter, so we don't care about the InitChannelAndRequestEventSource
   // result.
   InitChannelAndRequestEventSource();
 
   return NS_OK;
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -535,17 +535,18 @@ nsDOMFileReader::ConvertStream(const cha
                                nsAString &aResult)
 {
   nsresult rv;
   nsCOMPtr<nsICharsetConverterManager> charsetConverter = 
     do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIUnicodeDecoder> unicodeDecoder;
-  rv = charsetConverter->GetUnicodeDecoder(aCharset, getter_AddRefs(unicodeDecoder));
+  rv = charsetConverter->GetUnicodeDecoderRaw(aCharset,
+                                              getter_AddRefs(unicodeDecoder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   int32_t destLength;
   rv = unicodeDecoder->GetMaxLength(aFileData, aDataLen, &destLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aResult.SetLength(destLength, fallible_t()))
     return NS_ERROR_OUT_OF_MEMORY;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2719,17 +2719,18 @@ nsDocument::InitCSP(nsIChannel* aChannel
       // stop!  ERROR page!
       aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
     }
   }
 
   if (csp) {
     // Copy into principal
     nsIPrincipal* principal = GetPrincipal();
-    principal->SetCsp(csp);
+    rv = principal->SetCsp(csp);
+    NS_ENSURE_SUCCESS(rv, rv);
 #ifdef PR_LOGGING
     PR_LOG(gCspPRLog, PR_LOG_DEBUG,
            ("Inserted CSP into principal %p", principal));
 #endif
   }
 
   return NS_OK;
 }
@@ -3284,26 +3285,22 @@ void
 nsDocument::GetBaseTarget(nsAString &aBaseTarget)
 {
   aBaseTarget = mBaseTarget;
 }
 
 void
 nsDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
 {
+  // XXX it would be a good idea to assert the sanity of the argument,
+  // but before we figure out what to do about non-Encoding Standard
+  // encodings in the charset menu and in mailnews, assertions are futile.
   if (!mCharacterSet.Equals(aCharSetID)) {
     mCharacterSet = aCharSetID;
 
-#ifdef DEBUG
-    nsAutoCString canonicalName;
-    nsCharsetAlias::GetPreferred(aCharSetID, canonicalName);
-    NS_ASSERTION(canonicalName.Equals(aCharSetID),
-                 "charset name must be canonical");
-#endif
-
     int32_t n = mCharSetObservers.Length();
 
     for (int32_t i = 0; i < n; i++) {
       nsIObserver* observer = mCharSetObservers.ElementAt(i);
 
       observer->Observe(static_cast<nsIDocument *>(this), "charset",
                         NS_ConvertASCIItoUTF16(aCharSetID).get());
     }
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -766,16 +766,18 @@ GK_ATOM(onpageshow, "onpageshow")
 GK_ATOM(onpaint, "onpaint")
 GK_ATOM(onpairedstatuschanged, "onpairedstatuschanged")
 GK_ATOM(onpaste, "onpaste")
 GK_ATOM(onpopuphidden, "onpopuphidden")
 GK_ATOM(onpopuphiding, "onpopuphiding")
 GK_ATOM(onpopupshowing, "onpopupshowing")
 GK_ATOM(onpopupshown, "onpopupshown")
 GK_ATOM(onradiostatechange, "onradiostatechange")
+GK_ATOM(onreaderror, "onreaderror")
+GK_ATOM(onreadsuccess, "onreadsuccess")
 GK_ATOM(onreadystatechange, "onreadystatechange")
 GK_ATOM(onreceived, "onreceived")
 GK_ATOM(onremoteheld, "onremoteheld")
 GK_ATOM(onremoteresumed, "onremoteresumed")
 GK_ATOM(onretrieving, "onretrieving")
 GK_ATOM(onRequest, "onRequest")
 GK_ATOM(onrequestmediaplaystatus, "onrequestmediaplaystatus")
 GK_ATOM(onreset, "onreset")
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -43,16 +43,17 @@
 #include "nsChannelPolicy.h"
 #include "nsCRT.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozilla/dom/Element.h"
 #include "nsCrossSiteListenerProxy.h"
 #include "nsSandboxFlags.h"
 #include "nsContentTypeParser.h"
 #include "nsINetworkSeer.h"
+#include "mozilla/dom/EncodingUtils.h"
 
 #include "mozilla/CORSMode.h"
 #include "mozilla/Attributes.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gCspPRLog;
 #endif
 
@@ -1192,25 +1193,25 @@ nsScriptLoader::ConvertToUTF16(nsIChanne
     // take care of swallowing the BOM.
     charsetConv->GetUnicodeDecoderRaw(charset.get(),
                                       getter_AddRefs(unicodeDecoder));
   }
 
   if (!unicodeDecoder &&
       aChannel &&
       NS_SUCCEEDED(aChannel->GetContentCharset(charset)) &&
-      !charset.IsEmpty()) {
-    charsetConv->GetUnicodeDecoder(charset.get(),
-                                   getter_AddRefs(unicodeDecoder));
+      EncodingUtils::FindEncodingForLabel(charset, charset)) {
+    charsetConv->GetUnicodeDecoderRaw(charset.get(),
+                                      getter_AddRefs(unicodeDecoder));
   }
 
-  if (!unicodeDecoder && !aHintCharset.IsEmpty()) {
-    CopyUTF16toUTF8(aHintCharset, charset);
-    charsetConv->GetUnicodeDecoder(charset.get(),
-                                   getter_AddRefs(unicodeDecoder));
+  if (!unicodeDecoder &&
+      EncodingUtils::FindEncodingForLabel(aHintCharset, charset)) {
+    charsetConv->GetUnicodeDecoderRaw(charset.get(),
+                                      getter_AddRefs(unicodeDecoder));
   }
 
   if (!unicodeDecoder && aDocument) {
     charset = aDocument->GetDocumentCharacterSet();
     charsetConv->GetUnicodeDecoderRaw(charset.get(),
                                       getter_AddRefs(unicodeDecoder));
   }
 
--- a/content/media/MediaRecorder.cpp
+++ b/content/media/MediaRecorder.cpp
@@ -74,21 +74,23 @@ class MediaRecorder::Session: public nsI
       : mSession(aSession)
     { }
 
     NS_IMETHODIMP Run()
     {
       MOZ_ASSERT(NS_IsMainThread());
 
       MediaRecorder *recorder = mSession->mRecorder;
+      if (mSession->IsEncoderError()) {
+        recorder->NotifyError(NS_ERROR_UNEXPECTED);
+      }
       nsresult rv = recorder->CreateAndDispatchBlobEvent(mSession);
       if (NS_FAILED(rv)) {
         recorder->NotifyError(rv);
       }
-
       return NS_OK;
     }
 
   private:
     Session *mSession;
   };
 
   // Record thread task.
@@ -220,16 +222,23 @@ public:
   already_AddRefed<nsIDOMBlob> GetEncodedData()
   {
     nsString mimeType;
     mRecorder->GetMimeType(mimeType);
 
     return mEncodedBufferCache->ExtractBlob(mimeType);
   }
 
+  bool IsEncoderError()
+  {
+    if (mEncoder && mEncoder->HasError()) {
+      return true;
+    }
+    return false;
+  }
 private:
 
   // Pull encoded meida data from MediaEncoder and put into EncodedBufferCache.
   // Destroy this session object in the end of this function.
   void Extract()
   {
     MOZ_ASSERT(NS_GetCurrentThread() == mReadThread);
 
--- a/content/media/encoder/MediaEncoder.cpp
+++ b/content/media/encoder/MediaEncoder.cpp
@@ -143,65 +143,71 @@ MediaEncoder::CreateEncoder(const nsAStr
  *     Get encoded track data from audio/video encoder
  *     If a packet of track data is generated
  *       Insert encoded track data into the container stream of writer
  *       If the final container data is copied to aOutput
  *         Return the copy of final container data
  *       If this is the last packet of input stream
  *         Set mState to ENCODE_DONE
  *
- *   If mState is ENCODE_DONE
+ *   If mState is ENCODE_DONE or ENCODE_ERROR
  *     Stop the loop
  */
 void
 MediaEncoder::GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
                              nsAString& aMIMEType)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   aMIMEType = mMIMEType;
 
   bool reloop = true;
   while (reloop) {
     switch (mState) {
     case ENCODE_METADDATA: {
       nsRefPtr<TrackMetadataBase> meta = mAudioEncoder->GetMetadata();
-      MOZ_ASSERT(meta);
+      if (meta == nullptr) {
+        LOG("ERROR! AudioEncoder get null Metadata!");
+        mState = ENCODE_ERROR;
+        break;
+      }
       nsresult rv = mWriter->SetMetadata(meta);
       if (NS_FAILED(rv)) {
-       mState = ENCODE_DONE;
+       LOG("ERROR! writer can't accept audio metadata!");
+       mState = ENCODE_ERROR;
        break;
       }
 
       rv = mWriter->GetContainerData(aOutputBufs,
                                      ContainerWriter::GET_HEADER);
       if (NS_FAILED(rv)) {
-       mState = ENCODE_DONE;
+       LOG("ERROR! writer fail to generate header!");
+       mState = ENCODE_ERROR;
        break;
       }
 
       mState = ENCODE_TRACK;
       break;
     }
 
     case ENCODE_TRACK: {
       EncodedFrameContainer encodedData;
       nsresult rv = mAudioEncoder->GetEncodedTrack(encodedData);
       if (NS_FAILED(rv)) {
         // Encoding might be canceled.
         LOG("ERROR! Fail to get encoded data from encoder.");
-        mState = ENCODE_DONE;
+        mState = ENCODE_ERROR;
         break;
       }
       rv = mWriter->WriteEncodedTrack(encodedData,
                                       mAudioEncoder->IsEncodingComplete() ?
                                       ContainerWriter::END_OF_STREAM : 0);
       if (NS_FAILED(rv)) {
         LOG("ERROR! Fail to write encoded track to the media container.");
-        mState = ENCODE_DONE;
+        mState = ENCODE_ERROR;
         break;
       }
 
       rv = mWriter->GetContainerData(aOutputBufs,
                                      mAudioEncoder->IsEncodingComplete() ?
                                      ContainerWriter::FLUSH_NEEDED : 0);
       if (NS_SUCCEEDED(rv)) {
         // Successfully get the copy of final container data from writer.
@@ -212,16 +218,20 @@ MediaEncoder::GetEncodedData(nsTArray<ns
       break;
     }
 
     case ENCODE_DONE:
       LOG("MediaEncoder has been shutdown.");
       mShutdown = true;
       reloop = false;
       break;
-
+    case ENCODE_ERROR:
+      LOG("ERROR! MediaEncoder got error!");
+      mShutdown = true;
+      reloop = false;
+      break;
     default:
       MOZ_CRASH("Invalid encode state");
     }
   }
 }
 
 }
--- a/content/media/encoder/MediaEncoder.h
+++ b/content/media/encoder/MediaEncoder.h
@@ -49,16 +49,17 @@ namespace mozilla {
  */
 class MediaEncoder : public MediaStreamListener
 {
 public :
   enum {
     ENCODE_METADDATA,
     ENCODE_TRACK,
     ENCODE_DONE,
+    ENCODE_ERROR,
   };
 
   MediaEncoder(ContainerWriter* aWriter,
                AudioTrackEncoder* aAudioEncoder,
                VideoTrackEncoder* aVideoEncoder,
                const nsAString& aMIMEType)
     : mWriter(aWriter)
     , mAudioEncoder(aAudioEncoder)
@@ -116,16 +117,21 @@ public :
    */
   void Cancel()
   {
     if (mAudioEncoder) {
       mAudioEncoder->NotifyCancel();
     }
   }
 
+  bool HasError()
+  {
+    return mState == ENCODE_ERROR;
+  }
+
 private:
   nsAutoPtr<ContainerWriter> mWriter;
   nsAutoPtr<AudioTrackEncoder> mAudioEncoder;
   nsAutoPtr<VideoTrackEncoder> mVideoEncoder;
   nsString mMIMEType;
   int mState;
   bool mShutdown;
 };
--- a/content/media/encoder/OpusTrackEncoder.cpp
+++ b/content/media/encoder/OpusTrackEncoder.cpp
@@ -131,28 +131,27 @@ OpusTrackEncoder::~OpusTrackEncoder()
     speex_resampler_destroy(mResampler);
   }
 
 }
 
 nsresult
 OpusTrackEncoder::Init(int aChannels, int aSamplingRate)
 {
-  // The track must have 1 or 2 channels.
-  if (aChannels <= 0 || aChannels > MAX_CHANNELS) {
-    LOG("[Opus] Fail to create the AudioTrackEncoder! The input has"
-        " %d channel(s), but expects no more than %d.", aChannels, MAX_CHANNELS);
-    return NS_ERROR_INVALID_ARG;
-  }
-
   // This monitor is used to wake up other methods that are waiting for encoder
   // to be completely initialized.
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  mChannels = aChannels;
+  // This version of encoder API only support 1 or 2 channels,
+  // So set the mChannels less or equal 2 and
+  // let InterleaveTrackData downmix pcm data.
+  mChannels = aChannels > 2 ? 2 : aChannels;
 
+  if (aChannels <= 0) {
+    return NS_ERROR_FAILURE;
+  }
   // The granule position is required to be incremented at a rate of 48KHz, and
   // it is simply calculated as |granulepos = samples * (48000/source_rate)|,
   // that is, the source sampling rate must divide 48000 evenly.
   // If this constraint is not satisfied, we resample the input to 48kHz.
   if (!((aSamplingRate >= 8000) && (kOpusSamplingRate / aSamplingRate) *
          aSamplingRate == kOpusSamplingRate)) {
     int error;
     mResampler = speex_resampler_init(mChannels,
@@ -321,20 +320,16 @@ OpusTrackEncoder::GetEncodedTrack(Encode
   // The value of frameCopied should equal to (or smaller than, if eos)
   // GetPacketDuration().
   mSourceSegment->RemoveLeading(frameCopied);
 
   // Has reached the end of input stream and all queued data has pulled for
   // encoding.
   if (mSourceSegment->GetDuration() == 0 && mEndOfStream) {
     mDoneEncoding = true;
-    if (mResampler) {
-      speex_resampler_destroy(mResampler);
-      mResampler = nullptr;
-    }
     LOG("[Opus] Done encoding.");
   }
 
   // Append null data to pcm buffer if the leftover data is not enough for
   // opus encoder.
   if (frameCopied < GetPacketDuration() && mEndOfStream) {
     memset(pcm.Elements() + frameCopied * mChannels, 0,
            (GetPacketDuration()-frameCopied)*mChannels*sizeof(AudioDataValue));
@@ -353,15 +348,21 @@ OpusTrackEncoder::GetEncodedTrack(Encode
   result = opus_encode_float(mEncoder, pcmBuf, GetPacketDuration(),
                              frameData.Elements(), MAX_DATA_BYTES);
 #endif
   frameData.SetLength(result >= 0 ? result : 0);
 
   if (result < 0) {
     LOG("[Opus] Fail to encode data! Result: %s.", opus_strerror(result));
   }
+  if (mDoneEncoding) {
+    if (mResampler) {
+      speex_resampler_destroy(mResampler);
+      mResampler = nullptr;
+    }
+  }
 
   audiodata->SetFrameData(&frameData);
   aData.AppendEncodedFrame(audiodata);
   return result >= 0 ? NS_OK : NS_ERROR_FAILURE;
 }
 
 }
--- a/content/media/encoder/TrackEncoder.h
+++ b/content/media/encoder/TrackEncoder.h
@@ -136,18 +136,20 @@ protected:
    * to up-mix or down-mix the channel data if the channels number of this chunk
    * is different from mChannels. The channel data from aChunk might be modified
    * by up-mixing.
    */
   void InterleaveTrackData(AudioChunk& aChunk, int32_t aDuration,
                            uint32_t aOutputChannels, AudioDataValue* aOutput);
 
   /**
-   * The number of channels in the first valid audio chunk, and is being used
-   * to initialize the audio encoder.
+   * The number of channels are used for processing PCM data in the audio encoder.
+   * This value comes from the first valid audio chunk. If encoder can't support
+   * the channels in the chunk, downmix PCM stream can be performed.
+   * This value also be used to initialize the audio encoder.
    */
   int mChannels;
   int mSamplingRate;
   bool mInitialized;
   bool mDoneEncoding;
 
   /**
    * A ReentrantMonitor to protect the pushing and pulling of mRawSegment.
--- a/content/media/ogg/OggWriter.cpp
+++ b/content/media/ogg/OggWriter.cpp
@@ -164,16 +164,17 @@ OggWriter::GetContainerData(nsTArray<nsT
   }
 
   return (rc > 0) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
 OggWriter::SetMetadata(TrackMetadataBase* aMetadata)
 {
+  MOZ_ASSERT(aMetadata);
   if (aMetadata->GetKind() != TrackMetadataBase::METADATA_OPUS) {
     LOG("wrong meta data type!");
     return NS_ERROR_FAILURE;
   }
   // Validate each field of METADATA
   mMetadata = static_cast<OpusMetadata*>(aMetadata);
   if (mMetadata->mIdHeader.Length() == 0) {
     LOG("miss mIdHeader!");
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -232,16 +232,17 @@ support-files =
 [test_standalone.html]
 [test_volume.html]
 [test_video_to_canvas.html]
 [test_audiowrite.html]
 [test_mediarecorder_creation.html]
 [test_mediarecorder_avoid_recursion.html]
 [test_mediarecorder_record_timeslice.html]
 [test_mediarecorder_record_audiocontext.html]
+[test_mediarecorder_record_4ch_audiocontext.html]
 [test_mediarecorder_record_stopms.html]
 [test_mediarecorder_record_nosrc.html]
 [test_mozHasAudio.html]
 [test_source_media.html]
 [test_autoplay_contentEditable.html]
 [test_decoder_disable.html]
 [test_mediarecorder_record_no_timeslice.html]
 [test_mediarecorder_reload_crash.html]
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_mediarecorder_record_4ch_audiocontext.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test MediaRecorder Record AudioContext with four channels</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+
+<script class="testbody" type="text/javascript">
+
+function startTest() {
+  var context = new AudioContext();
+  var buffer = context.createBuffer(4, 80920, context.sampleRate);
+  for (var i = 0; i < 80920; ++i) {
+    for(var j = 0; j < 4; ++j) {
+      buffer.getChannelData(j)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate);
+    }
+  }
+
+  var source = context.createBufferSource();
+  source.buffer = buffer;
+  var dest = context.createMediaStreamDestination();
+  var stopTriggered = false;
+  var onstopTriggered = false;
+  dest.channelCount = 4;
+  var expectedMimeType = 'audio/ogg';
+  source.channelCountMode = 'explicit';
+  source.connect(dest);
+  var elem = document.createElement('audio');
+  elem.mozSrcObject = dest.stream;
+  mMediaStream = dest.stream;
+  source.start(0);
+  elem.play();
+  mMediaRecorder = new MediaRecorder(dest.stream);
+  mMediaRecorder.onwarning = function() {
+    ok(false, 'onwarning unexpectedly fired');
+  };
+
+  mMediaRecorder.onerror = function() {
+    ok(false, 'onerror unexpectedly fired');
+  };
+
+  mMediaRecorder.onstop = function() {
+    ok(true, 'onstop fired successfully');
+    is(mMediaRecorder.state, 'inactive', 'check recording status is inactive');
+    onstopTriggered = true;
+    SimpleTest.finish();
+  };
+  mMediaRecorder.ondataavailable = function (e) {
+    ok(e.data.size > 0, 'check blob has data');
+    is(mMediaRecorder.mimeType, expectedMimeType, 'blob should has mimetype, return ' + mMediaRecorder.mimeType);
+    if (!stopTriggered) {
+      mMediaRecorder.stop();
+      stopTriggered = true;
+    } else if (onstopTriggered) {
+      ok(false, 'ondataavailable should come before onstop event');
+    }
+  };
+  try {
+    mMediaRecorder.start(1000);
+    is('recording', mMediaRecorder.state, "check record state recording");
+  } catch (e) {
+    ok(false, 'Can t record audio context');
+  }
+}
+
+startTest();
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
--- a/docshell/test/browser/browser.ini
+++ b/docshell/test/browser/browser.ini
@@ -25,16 +25,18 @@ support-files =
   file_bug234628-8-child.html
   file_bug234628-8.html
   file_bug234628-9-child.html
   file_bug234628-9.html
   file_bug420605.html
   file_bug503832.html
   file_bug655270.html
   file_bug670318.html
+  file_bug941562-child.html
+  file_bug941562.html
   print_postdata.sjs
   test-form_sjis.html
 
 [browser_bug134911.js]
 [browser_bug234628-1.js]
 [browser_bug234628-10.js]
 [browser_bug234628-11.js]
 [browser_bug234628-2.js]
@@ -53,11 +55,12 @@ support-files =
 [browser_bug441169.js]
 [browser_bug503832.js]
 [browser_bug554155.js]
 [browser_bug655270.js]
 [browser_bug655273.js]
 [browser_bug670318.js]
 [browser_bug673467.js]
 [browser_bug92473.js]
+[browser_bug941562.js]
 [browser_loadDisallowInherit.js]
 [browser_loadURI.js]
 [browser_search_notification.js]
copy from docshell/test/browser/browser_bug234628-6.js
copy to docshell/test/browser/browser_bug941562.js
--- a/docshell/test/browser/browser_bug234628-6.js
+++ b/docshell/test/browser/browser_bug941562.js
@@ -1,39 +1,39 @@
 function test() {
   waitForExplicitFinish();
 
   var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
-  gBrowser.selectedTab = gBrowser.addTab(rootDir + "file_bug234628-6.html");
+  gBrowser.selectedTab = gBrowser.addTab(rootDir + "file_bug941562.html");
   gBrowser.selectedBrowser.addEventListener("load", afterOpen, true);
 }
 
 function afterOpen(event) {
   if (event.target != gBrowser.contentDocument) {
     return;
   }
 
   gBrowser.selectedBrowser.removeEventListener("load", afterOpen, true);
   gBrowser.selectedBrowser.addEventListener("load", afterChangeCharset, true);
 
-  is(gBrowser.contentDocument.documentElement.textContent.indexOf('\u20AC'), 190, "Parent doc should be windows-1252 initially");
+  is(gBrowser.contentDocument.documentElement.textContent.indexOf('\u20AC'), 140, "Parent doc should be windows-1252 initially");
 
-  is(gBrowser.contentDocument.getElementsByTagName("iframe")[0].contentDocument.documentElement.textContent.indexOf('\u20AC'), 109, "Child doc should be utf-16 initially");
+  is(gBrowser.contentDocument.getElementsByTagName("iframe")[0].contentDocument.documentElement.textContent.indexOf('\u4E2D'), 77, "Child doc should be HZ-GB-2312 initially");
 
   BrowserSetForcedCharacterSet("windows-1251");
 }
   
 function afterChangeCharset(event) {
   if (event.target != gBrowser.contentDocument) {
     return;
   }
 
   gBrowser.selectedBrowser.removeEventListener("load", afterChangeCharset, true);
 
-  is(gBrowser.contentDocument.documentElement.textContent.indexOf('\u0402'), 190, "Parent doc should decode as windows-1251 subsequently");
-  is(gBrowser.contentDocument.getElementsByTagName("iframe")[0].contentDocument.documentElement.textContent.indexOf('\u20AC'), 109, "Child doc should decode as utf-16 subsequently");  
+  is(gBrowser.contentDocument.documentElement.textContent.indexOf('\u0402'), 140, "Parent doc should decode as windows-1251 subsequently");
+  is(gBrowser.contentDocument.getElementsByTagName("iframe")[0].contentDocument.documentElement.textContent.indexOf('\u4E2D'), 77, "Child doc should decode as HZ-GB-2312 subsequently");  
 
   is(gBrowser.contentDocument.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently");
-  is(gBrowser.contentDocument.getElementsByTagName("iframe")[0].contentDocument.characterSet, "UTF-16BE", "Child doc should report UTF-16 subsequently");
+  is(gBrowser.contentDocument.getElementsByTagName("iframe")[0].contentDocument.characterSet, "HZ-GB-2312", "Child doc should report HZ-GB-2312 subsequently");
 
   gBrowser.removeCurrentTab();
   finish();
 }
copy from docshell/test/browser/file_bug234628-7-child.html
copy to docshell/test/browser/file_bug941562-child.html
--- a/docshell/test/browser/file_bug234628-7-child.html
+++ b/docshell/test/browser/file_bug941562-child.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html lang="en">
 <head>
+<meta charset="hz-gb-2312">
 <meta content="width=device-width, initial-scale=1" name="viewport">
-<title>meta declaration in parent and BOMless UTF-8 with HTTP charset in child</title>
+<title>meta declaration in parent and meta HZ in child</title>
 </head>
 <body>
-<p>Euro sign if decoded as UTF-8: €</p>
-<p>a with diaeresis if decoded as UTF-8: ä</p>
+<p>China if decoded as HZ: ~{VP~}</p>
 </body>
 </html>
 
copy from docshell/test/browser/file_bug234628-6.html
copy to docshell/test/browser/file_bug941562.html
--- a/docshell/test/browser/file_bug234628-6.html
+++ b/docshell/test/browser/file_bug941562.html
@@ -1,18 +1,18 @@
 <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="windows-1252">
 <meta content="width=device-width, initial-scale=1" name="viewport">
-<title>meta declaration in parent and BOMless UTF-16 with HTTP charset in child</title>
+<title>meta declaration in parent and meta HZ in child</title>
 </head>
 <body>
-<h1>meta declaration in parent and BOMless UTF-16 with HTTP charset in child</h1>
+<h1>meta declaration in parent and meta HZ in child</h1>
 
 <p>Euro sign if decoded as Windows-1252: </p>
 <p>a with diaeresis if decoded as Windows-1252: </p>
 
-<iframe src="file_bug234628-6-child.html"></iframe>
+<iframe src="file_bug941562-child.html"></iframe>
 
 </body>
 </html>
 
--- a/dom/encoding/EncodingUtils.cpp
+++ b/dom/encoding/EncodingUtils.cpp
@@ -33,14 +33,16 @@ EncodingUtils::FindEncodingForLabel(cons
 }
 
 bool
 EncodingUtils::IsAsciiCompatible(const nsACString& aPreferredName)
 {
   return !(aPreferredName.LowerCaseEqualsLiteral("utf-16") ||
            aPreferredName.LowerCaseEqualsLiteral("utf-16be") ||
            aPreferredName.LowerCaseEqualsLiteral("utf-16le") ||
+           aPreferredName.LowerCaseEqualsLiteral("replacement") ||
+           aPreferredName.LowerCaseEqualsLiteral("hz-gb-2312") ||
            aPreferredName.LowerCaseEqualsLiteral("utf-7") ||
            aPreferredName.LowerCaseEqualsLiteral("x-imap4-modified-utf7"));
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/encoding/TextDecoder.cpp
+++ b/dom/encoding/TextDecoder.cpp
@@ -16,18 +16,19 @@ static const PRUnichar kReplacementChar 
 void
 TextDecoder::Init(const nsAString& aEncoding, const bool aFatal,
                   ErrorResult& aRv)
 {
   nsAutoString label(aEncoding);
   EncodingUtils::TrimSpaceCharacters(label);
 
   // Let encoding be the result of getting an encoding from label.
-  // If encoding is failure, throw a TypeError.
-  if (!EncodingUtils::FindEncodingForLabel(label, mEncoding)) {
+  // If encoding is failure or replacement, throw a TypeError.
+  if (!EncodingUtils::FindEncodingForLabel(label, mEncoding) ||
+      mEncoding.EqualsLiteral("replacement")) {
     aRv.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &label);
     return;
   }
 
   // If the constructor is called with an options argument,
   // and the fatal property of the dictionary is set,
   // set the internal fatal flag of the decoder object.
   mFatal = aFatal;
--- a/dom/encoding/labelsencodings.properties
+++ b/dom/encoding/labelsencodings.properties
@@ -210,14 +210,16 @@ csksc56011987=EUC-KR
 euc-kr=EUC-KR
 iso-ir-149=EUC-KR
 korean=EUC-KR
 ks_c_5601-1987=EUC-KR
 ks_c_5601-1989=EUC-KR
 ksc5601=EUC-KR
 ksc_5601=EUC-KR
 windows-949=EUC-KR
-csiso2022kr=ISO-2022-KR
-iso-2022-kr=ISO-2022-KR
+csiso2022kr=replacement
+iso-2022-kr=replacement
+iso-2022-cn=replacement
+iso-2022-cn-ext=replacement
 utf-16=UTF-16LE
 utf-16le=UTF-16LE
 utf-16be=UTF-16BE
 x-user-defined=x-user-defined
new file mode 100644
--- /dev/null
+++ b/dom/encoding/test/reftest/bug863728-1-ref.html
@@ -0,0 +1,1 @@
+<meta charset=utf-8>�
new file mode 100644
--- /dev/null
+++ b/dom/encoding/test/reftest/bug863728-1.html
@@ -0,0 +1,1 @@
+<meta charset=iso-2022-cn>
new file mode 100644
--- /dev/null
+++ b/dom/encoding/test/reftest/bug863728-2-ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<iframe src="data:text/html;charset=utf-8,�<iframe src='data:text/html;charset=utf-8,PASS'></iframe>" width=400 height=200></iframe>
new file mode 100644
--- /dev/null
+++ b/dom/encoding/test/reftest/bug863728-2.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<meta charset=utf-8>
+<script>
+function runTest() {
+  var r = document.documentElement;
+  var d = window[0].document;
+  var i = d.createElement("iframe");
+  i.src = "data:text/html,PASS";
+  i.onload = function() {
+    r.removeAttribute("class");
+  }
+  d.body.appendChild(i);
+}
+</script>
+<body onload="runTest();">
+<iframe src="bug863728-1.html" width=400 height=200></iframe>
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/dom/encoding/test/reftest/bug863728-3.html
@@ -0,0 +1,5 @@
+<link rel=stylesheet href="data:text/css;charset=iso-2022-kr,html { background-color: red }">
+<link rel=stylesheet href="data:text/css,html { background-color: red }" charset="iso-2022-cn-ext">
+<link rel=stylesheet href='data:text/css,@charset "csiso2022kr"; html { background-color: red }'>
+<script src="data:text/javascript;charset=iso-2022-kr,document.write('FAIL');"></script>
+<script src="data:text/javascript,document.write('FAIL');" charset="iso-2022-kr"></script>
new file mode 100644
--- /dev/null
+++ b/dom/encoding/test/reftest/reftest.list
@@ -0,0 +1,3 @@
+== bug863728-1.html bug863728-1-ref.html
+== bug863728-2.html bug863728-2-ref.html
+== bug863728-3.html bug863728-3-ref.html
--- a/dom/encoding/test/test_TextDecoder.js
+++ b/dom/encoding/test/test_TextDecoder.js
@@ -344,21 +344,20 @@ function testDecoderGetEncoding()
     {encoding: "gb18030", labels: ["gb18030"]},
     {encoding: "hz-gb-2312", labels: ["hz-gb-2312"]},
     {encoding: "big5", labels: ["big5", "cn-big5", "csbig5", "x-x-big5"]},
     {encoding: "big5-hkscs", labels: ["big5-hkscs"]},
     {encoding: "euc-jp", labels: ["cseucpkdfmtjapanese", "euc-jp", "x-euc-jp"]},
     {encoding: "iso-2022-jp", labels: ["csiso2022jp", "iso-2022-jp"]},
     {encoding: "shift_jis", labels: ["csshiftjis", "ms_kanji", "shift-jis", "shift_jis", "sjis", "windows-31j", "x-sjis"]},
     {encoding: "euc-kr", labels: ["cseuckr", "csksc56011987", "euc-kr", "iso-ir-149", "korean", "ks_c_5601-1987", "ks_c_5601-1989", "ksc5601", "ksc_5601", "windows-949"]},
-    {encoding: "iso-2022-kr", labels: ["csiso2022kr", "iso-2022-kr"]},
     {encoding: "utf-16le", labels: ["utf-16", "utf-16le"]},
     {encoding: "utf-16be", labels: ["utf-16be"]},
     {encoding: "x-user-defined", labels: ["x-user-defined"]},
-    {error: "TypeError", labels: ["x-windows-949", "\u0130SO-8859-1"]},
+    {error: "TypeError", labels: ["x-windows-949", "\u0130SO-8859-1", "csiso2022kr", "iso-2022-kr", "iso-2022-cn", "iso-2022-cn-ext", "replacement"]},
   ];
 
   for (var le of labelEncodings) {
     for (var label of le.labels) {
       try {
         var decoder = TextDecoder(label);
       } catch (e) {
         assert_true(!!le.error, label + " shoud not throw " + e.name);
--- a/dom/encoding/test/test_stringencoding.html
+++ b/dom/encoding/test/test_stringencoding.html
@@ -19,12 +19,11 @@ setup({explicit_timeout: true});
 <script type="text/javascript" src="unit/test_gbk.js"></script>
 <!-- TODO: gb18030 -->
 <script type="text/javascript" src="unit/test_hz-gb-2312.js"></script>
 <script type="text/javascript" src="unit/test_big5.js"></script>
 <script type="text/javascript" src="unit/test_euc-jp.js"></script>
 <script type="text/javascript" src="unit/test_iso-2022-jp.js"></script>
 <script type="text/javascript" src="unit/test_shift_jis.js"></script>
 <script type="text/javascript" src="unit/test_euc-kr.js"></script>
-<script type="text/javascript" src="unit/test_iso-2022-kr.js"></script>
 
 </body>
 </html>
--- a/dom/encoding/test/unit/mochitest.ini
+++ b/dom/encoding/test/unit/mochitest.ini
@@ -1,11 +1,10 @@
 [DEFAULT]
 
 [test_big5.js]
 [test_euc-jp.js]
 [test_euc-kr.js]
 [test_gbk.js]
 [test_hz-gb-2312.js]
 [test_iso-2022-jp.js]
-[test_iso-2022-kr.js]
 [test_shift_jis.js]
 [test_singlebytes.js]
deleted file mode 100644
--- a/dom/encoding/test/unit/test_iso-2022-kr.js
+++ /dev/null
@@ -1,9 +0,0 @@
-test(
-  function () {
-    var bytes = [27,36,41,67,14,33,33,33,34,33,35,33,36,33,37,33,38,33,39,33,40,33,41,33,42,33,43,33,44,33,45,33,46,33,47,33,48,33,49,33,50,33,51,33,52,33,53,33,54,33,55,33,56,33,57,33,58,33,59,33,60,33,61,33,62,33,63,33,64,33,65,33,66,33,67,33,68,33,69,33,70,33,71,33,72,33,73,33,74,33,75,33,76,33,77,33,78,33,79,33,80,33,81,33,82,33,83,33,84,33,85,33,86,33,87,33,88,33,89,33,90,33,91,33,92,33,93,33,94,33,95,33,96,33,97,33,98,33,99,33,100,33,101,33,102,33,103,33,104,33,105,33,106,33,107,33,108,33,109,33,110,33,111,33,112,33,113,33,114,33,115,33,116,33,117,33,118,33,119,33,120,33,121,33,122,33,123,33,124,33,125,33,126,34,33,34,34,34,35,34,36,34,37,34,38,34,39,34,40,34,41,34,42,34,43,34,44,34,45,34,46,34,47,34,48,34,49,34,50,34,51,34,52,34,53,34,54,34,55,34,56,34,57,34,58,34,59,34,60,34,61,34,62,34,63,34,64,34,65,34,66,34,67,34,68,34,69,34,70,34,71,34,72,34,73,34,74,34,75,34,76,34,77,34,78,34,79,34,80,34,81,34,82,34,83,34,84,34,85,34,86,34,87,34,88,34,89,34,90,34,91,34,92,34,93,34,94,34,95,34,96,34,97,34,98,34,99,34,100,34,101,34,102,34,103,35,33,35,34,35,35,35,36,35,37,35,38,35,39,35,40,35,41,35,42,35,43,35,44,35,45,35,46,35,47,35,48,35,49,35,50,35,51,35,52,35,53,35,54,35,55,35,56,35,57,35,58,35,59,35,60,35,61,35,62,35,63,35,64,35,65,35,66,35,67,35,68,35,69,35,70,35,71,35,72,35,73,35,74,35,75,35,76,35,77,35,78,35,79,35,80,35,81,35,82,35,83,35,84,35,85,35,86,35,87,35,88,35,89,35,90,35,91,35,92,35,93,35,94,35,95,35,96,35,97,35,98,35,99,35,100,35,101,35,102,35,103,35,104,35,105,35,106,35,107,35,108,35,109,35,110,35,111,35,112,35,113,35,114,35,115,35,116,35,117,35,118,35,119,35,120,35,121,35,122,35,123,35,124,35,125,35,126,36,33,36,34,36,35,36,36,36,37,36,38,36,39,36,40,36,41,36,42,36,43,36,44,36,45,36,46,36,47,36,48,36,49,36,50,36,51,36,52,36,53,36,54,36,55,36,56,36,57,36,58,36,59,36,60,36,61,36,62,36,63,36,64,36,65,36,66,36,67,36,68,36,69,36,70,36,71,36,72,36,73,36,74,36,75,36,76,36,77,36,78,36,79,36,80,36,81,36,82,36,83,36,84,36,85,36,86,36,87,36,88,36,89,36,90,36,91,36,92,36,93,36,94,36,95,36,96,36,97,36,98,36,99,36,100,36,101,36,102,36,103,36,104,36,105,36,106,36,107,36,108,36,109,36,110,36,111,36,112,36,113,36,114,36,115,36,116,36,117,36,118,36,119,36,120,36,121,36,122,36,123,36,124,36,125,36,126,37,33,37,34,37,35,37,36,37,37,37,38,37,39,37,40,37,41,37,42,37,48,37,49,37,50,37,51,37,52,37,53,37,54,37,55,37,56,37,57,37,65,37,66,37,67,37,68,37,69,37,70,37,71,37,72,37,73,37,74,37,75,37,76,37,77,37,78,37,79,37,80,37,81,37,82,37,83,37,84,37,85,37,86,37,87,37,88,37,97,37,98,37,99,37,100,37,101,37,102,37,103,37,104,37,105,37,106,37,107,37,108,37,109,37,110,37,111,37,112,37,113,37,114,37,115,37,116,37,117,37,118,37,119,37,120,38,33,38,34,38,35,38,36,38,37,38,38,38,39,38,40,38,41,38,42,38,43,38,44,38,45,38,46,38,47,38,48,38,49,38,50,38,51,38,52,38,53,38,54,38,55,38,56,38,57,38,58,38,59,38,60,38,61,38,62,38,63,38,64,38,65,38,66,38,67,38,68,38,69,38,70,38,71,38,72,38,73,38,74,38,75,38,76,38,77,38,78,38,79,38,80,38,81,38,82,38,83,38,84,38,85,38,86,38,87,38,88,38,89,38,90,38,91,38,92,38,93,38,94,38,95,38,96,38,97,38,98,38,99,38,100,39,33,39,34,39,35,39,36,39,37,39,38,39,39,39,40,39,41,39,42,39,43,39,44,39,45,39,46,39,47,39,48,39,49,39,50,39,51,39,52,39,53,39,54,39,55,39,56,39,57,39,58,39,59,39,60,39,61,39,62,39,63,39,64,39,65,39,66,39,67,39,68,39,69,39,70,39,71,39,72,39,73,39,74,39,75,39,76,39,77,39,78,39,79,39,80,39,81,39,82,39,83,39,84,39,85,39,86,39,87,39,88,39,89,39,90,39,91,39,92,39,93,39,94,39,95,39,96,39,97,39,98,39,99,39,100,39,101,39,102,39,103,39,104,39,105,39,106,39,107,39,108,39,109,39,110,39,111,40,33,40,34,40,35,40,36,40,38,40,40,40,41,40,42,40,43,40,44,40,45,40,46,40,47,40,49,40,50,40,51,40,52,40,53,40,54,40,55,40,56,40,57,40,58,40,59,40,60,40,61,40,62,40,63,40,64,40,65,40,66,40,67,40,68,40,69,40,70,40,71,40,72,40,73,40,74,40,75,40,76,40,77,40,78,40,79,40,80,40,81,40,82,40,83,40,84,40,85,40,86,40,87,40,88,40,89,40,90,40,91,40,92,40,93,40,94,40,95,40,96,40,97,40,98,40,99,40,100,40,101,40,102,40,103,40,104,40,105,40,106,40,107,40,108,40,109,40,110,40,111,40,112,40,113,40,114,40,115,40,116,40,117,40,118,40,119,40,120,40,121,40,122,40,123,40,124,40,125,40,126,41,33,41,34,41,35,41,36,41,37,41,38,41,39,41,40,41,41,41,42,41,43,41,44,41,45,41,46,41,47,41,48,41,49,41,50,41,51,41,52,41,53,41,54,41,55,41,56,41,57,41,58,41,59,41,60,41,61,41,62,41,63,41,64,41,65,41,66,41,67,41,68,41,69,41,70,41,71,41,72,41,73,41,74,41,75,41,76,41,77,41,78,41,79,41,80,41,81,41,82,41,83,41,84,41,85,41,86,41,87,41,88,41,89,41,90,41,91,41,92,41,93,41,94,41,95,41,96,41,97,41,98,41,99,41,100,41,101,41,102,41,103,41,104,41,105,41,106,41,107,41,108,41,109,41,110,41,111,41,112,41,113,41,114,41,115,41,116,41,117,41,118,41,119,41,120,41,121,41,122,41,123,41,124,41,125,41,126,42,33,42,34,42,35,42,36,42,37,42,38,42,39,42,40,42,41,42,42,42,43,42,44,42,45,42,46,42,47,42,48,42,49,42,50,42,51,42,52,42,53,42,54,42,55,42,56,42,57,42,58,42,59,42,60,42,61,42,62,42,63,42,64,42,65,42,66,42,67,42,68,42,69,42,70,42,71,42,72,42,73,42,74,42,75,42,76,42,77,42,78,42,79,42,80,42,81,42,82,42,83,42,84,42,85,42,86,42,87,42,88,42,89,42,90,42,91,42,92,42,93,42,94,42,95,42,96,42,97,42,98,42,99,42,100,42,101,42,102,42,103,42,104,42,105,42,106,42,107,42,108,42,109,42,110,42,111,42,112,42,113,42,114,42,115,43,33,43,34,43,35,43,36,43,37,43,38,43,39,43,40,43,41,43,42,43,43,43,44,43,45,43,46,43,47,43,48,43,49,43,50,43,51,43,52,43,53,43,54,43,55,43,56,43,57,43,58,43,59,43,60,43,61,43,62,43,63,43,64,43,65,43,66,43,67,43,68,43,69,43,70,43,71,43,72,43,73,43,74,43,75,43,76,43,77,43,78,43,79,43,80,43,81,43,82,43,83,43,84,43,85,43,86,43,87,43,88,43,89,43,90,43,91,43,92,43,93,43,94,43,95,43,96,43,97,43,98,43,99,43,100,43,101,43,102,43,103,43,104,43,105,43,106,43,107,43,108,43,109,43,110,43,111,43,112,43,113,43,114,43,115,43,116,43,117,43,118,44,33,44,34,44,35,44,36,44,37,44,38,44,39,44,40,44,41,44,42,44,43,44,44,44,45,44,46,44,47,44,48,44,49,44,50,44,51,44,52,44,53,44,54,44,55,44,56,44,57,44,58,44,59,44,60,44,61,44,62,44,63,44,64,44,65,44,81,44,82,44,83,44,84,44,85,44,86,44,87,44,88,44,89,44,90,44,91,44,92,44,93,44,94,44,95,44,96,44,97,44,98,44,99,44,100,44,101,44,102,44,103,44,104,44,105,44,106,44,107,44,108,44,109,44,110,44,111,44,112,44,113,48,33,48,34,48,35,48,36,48,37,48,38,48,39,48,40,48,41,48,42,48,43,48,44,48,45,48,46,48,47,48,48,48,49,48,50,48,51,48,52,48,53,48,54,48,55,48,56,48,57,48,58,48,59,48,60,48,61,48,62,48,63,48,64,48,65,48,66,48,67,48,68,48,69,48,70,48,71,48,72,48,73,48,74,48,75,48,76,48,77,48,78,48,79,48,80,48,81,48,82,48,83,48,84,48,85,48,86,48,87,48,88,48,89,48,90,48,91,48,92,48,93,48,94,48,95,48,96,48,97,48,98,48,99,48,100,48,101,48,102,48,103,48,104,48,105,48,106,48,107,48,108,48,109,48,110,48,111,48,112,48,113,48,114,48,115,48,116,48,117,48,118,48,119,48,120,48,121,48,122,48,123,48,124,48,125,48,126,49,33,49,34,49,35,49,36,49,37,49,38,49,39,49,40,49,41,49,42,49,43,49,44,49,45,49,46,49,47,49,48,49,49,49,50,49,51,49,52,49,53,49,54,49,55,49,56,49,57,49,58,49,59,49,60,49,61,49,62,49,63,49,64,49,65,49,66,49,67,49,68,49,69,49,70,49,71,49,72,49,73,49,74,49,75,49,76,49,77,49,78,49,79,49,80,49,81,49,82,49,83,49,84,49,85,49,86,49,87,49,88,49,89,49,90,49,91,49,92,49,93,49,94,49,95,49,96,49,97,49,98,49,99,49,100,49,101,49,102,49,103,49,104,49,105,49,106,49,107,49,108,49,109,49,110,49,111,49,112,49,113,49,114,49,115,49,116,49,117,49,118,49,119,49,120,49,121,49,122,49,123,49,124,49,125,49,126,50,33,50,34,50,35,50,36,50,37,50,38,50,39,50,40,50,41,50,42,50,43,50,44,50,45,50,46,50,47,50,48,50,49,50,50,50,51,50,52,50,53,50,54,50,55,50,56,50,57,50,58,50,59,50,60,50,61,50,62,50,63,50,64,50,65,50,66,50,67,50,68,50,69,50,70,50,71,50,72,50,73,50,74,50,75,50,76,50,77,50,78,50,79,50,80,50,81,50,82,50,83,50,84,50,85,50,86,50,87,50,88,50,89,50,90,50,91,50,92,50,93,50,94,50,95,50,96,50,97,50,98,50,99,50,100,50,101,50,102,50,103,50,104,50,105,50,106,50,107,50,108,50,109,50,110,50,111,50,112,50,113,50,114,50,115,50,116,50,117,50,118,50,119,50,120,50,121,50,122,50,123,50,124,50,125,50,126,51,33,51,34,51,35,51,36,51,37,51,38,51,39,51,40,51,41,51,42,51,43,51,44,51,45,51,46,51,47,51,48,51,49,51,50,51,51,51,52,51,53,51,54,51,55,51,56,51,57,51,58,51,59,51,60,51,61,51,62,51,63,51,64,51,65,51,66,51,67,51,68,51,69,51,70,51,71,51,72,51,73,51,74,51,75,51,76,51,77,51,78,51,79,51,80,51,81,51,82,51,83,51,84,51,85,51,86,51,87,51,88,51,89,51,90,51,91,51,92,51,93,51,94,51,95,51,96,51,97,51,98,51,99,51,100,51,101,51,102,51,103,51,104,51,105,51,106,51,107,51,108,51,109,51,110,51,111,51,112,51,113,51,114,51,115,51,116,51,117,51,118,51,119,51,120,51,121,51,122,51,123,51,124,51,125,51,126,52,33,52,34,52,35,52,36,52,37,52,38,52,39,52,40,52,41,52,42,52,43,52,44,52,45,52,46,52,47,52,48,52,49,52,50,52,51,52,52,52,53,52,54,52,55,52,56,52,57,52,58,52,59,52,60,52,61,52,62,52,63,52,64,52,65,52,66,52,67,52,68,52,69,52,70,52,71,52,72,52,73,52,74,52,75,52,76,52,77,52,78,52,79,52,80,52,81,52,82,52,83,52,84,52,85,52,86,52,87,52,88,52,89,52,90,52,91,52,92,52,93,52,94,52,95,52,96,52,97,52,98,52,99,52,100,52,101,52,102,52,103,52,104,52,105,52,106,52,107,52,108,52,109,52,110,52,111,52,112,52,113,52,114,52,115,52,116,52,117,52,118,52,119,52,120,52,121,52,122,52,123,52,124,52,125,52,126,53,33,53,34,53,35,53,36,53,37,53,38,53,39,53,40,53,41,53,42,53,43,53,44,53,45,53,46,53,47,53,48,53,49,53,50,53,51,53,52,53,53,53,54,53,55,53,56,53,57,53,58,53,59,53,60,53,61,53,62,53,63,53,64,53,65,53,66,53,67,53,68,53,69,53,70,53,71,53,72,53,73,53,74,53,75,53,76,53,77,53,78,53,79,53,80,53,81,53,82,53,83,53,84,53,85,53,86,53,87,53,88,53,89,53,90,53,91,53,92,53,93,53,94,53,95,53,96,53,97,53,98,53,99,53,100,53,101,53,102,53,103,53,104,53,105,53,106,53,107,53,108,53,109,53,110,53,111,53,112,53,113,53,114,53,115,53,116,53,117,53,118,53,119,53,120,53,121,53,122,53,123,53,124,53,125,53,126,54,33,54,34,54,35,54,36,54,37,54,38,54,39,54,40,54,41,54,42,54,43,54,44,54,45,54,46,54,47,54,48,54,49,54,50,54,51,54,52,54,53,54,54,54,55,54,56,54,57,54,58,54,59,54,60,54,61,54,62,54,63,54,64,54,65,54,66,54,67,54,68,54,69,54,70,54,71,54,72,54,73,54,74,54,75,54,76,54,77,54,78,54,79,54,80,54,81,54,82,54,83,54,84,54,85,54,86,54,87,54,88,54,89,54,90,54,91,54,92,54,93,54,94,54,95,54,96,54,97,54,98,54,99,54,100,54,101,54,102,54,103,54,104,54,105,54,106,54,107,54,108,54,109,54,110,54,111,54,112,54,113,54,114,54,115,54,116,54,117,54,118,54,119,54,120,54,121,54,122,54,123,54,124,54,125,54,126,55,33,55,34,55,35,55,36,55,37,55,38,55,39,55,40,55,41,55,42,55,43,55,44,55,45,55,46,55,47,55,48,55,49,55,50,55,51,55,52,55,53,55,54,55,55,55,56,55,57,55,58,55,59,55,60,55,61,55,62,55,63,55,64,55,65,55,66,55,67,55,68,55,69,55,70,55,71,55,72,55,73,55,74,55,75,55,76,55,77,55,78,55,79,55,80,55,81,55,82,55,83,55,84,55,85,55,86,55,87,55,88,55,89,55,90,55,91,55,92,55,93,55,94,55,95,55,96,55,97,55,98,55,99,55,100,55,101,55,102,55,103,55,104,55,105,55,106,55,107,55,108,55,109,55,110,55,111,55,112,55,113,55,114,55,115,55,116,55,117,55,118,55,119,55,120,55,121,55,122,55,123,55,124,55,125,55,126,56,33,56,34,56,35,56,36,56,37,56,38,56,39,56,40,56,41,56,42,56,43,56,44,56,45,56,46,56,47,56,48,56,49,56,50,56,51,56,52,56,53,56,54,56,55,56,56,56,57,56,58,56,59,56,60,56,61,56,62,56,63,56,64,56,65,56,66,56,67,56,68,56,69,56,70,56,71,56,72,56,73,56,74,56,75,56,76,56,77,56,78,56,79,56,80,56,81,56,82,56,83,56,84,56,85,56,86,56,87,56,88,56,89,56,90,56,91,56,92,56,93,56,94,56,95,56,96,56,97,56,98,56,99,56,100,56,101,56,102,56,103,56,104,56,105,56,106,56,107,56,108,56,109,56,110,56,111,56,112,56,113,56,114,56,115,56,116,56,117,56,118,56,119,56,120,56,121,56,122,56,123,56,124,56,125,56,126,57,33,57,34,57,35,57,36,57,37,57,38,57,39,57,40,57,41,57,42,57,43,57,44,57,45,57,46,57,47,57,48,57,49,57,50,57,51,57,52,57,53,57,54,57,55,57,56,57,57,57,58,57,59,57,60,57,61,57,62,57,63,57,64,57,65,57,66,57,67,57,68,57,69,57,70,57,71,57,72,57,73,57,74,57,75,57,76,57,77,57,78,57,79,57,80,57,81,57,82,57,83,57,84,57,85,57,86,57,87,57,88,57,89,57,90,57,91,57,92,57,93,57,94,57,95,57,96,57,97,57,98,57,99,57,100,57,101,57,102,57,103,57,104,57,105,57,106,57,107,57,108,57,109,57,110,57,111,57,112,57,113,57,114,57,115,57,116,57,117,57,118,57,119,57,120,57,121,57,122,57,123,57,124,57,125,57,126,58,33,58,34,58,35,58,36,58,37,58,38,58,39,58,40,58,41,58,42,58,43,58,44,58,45,58,46,58,47,58,48,58,49,58,50,58,51,58,52,58,53,58,54,58,55,58,56,58,57,58,58,58,59,58,60,58,61,58,62,58,63,58,64,58,65,58,66,58,67,58,68,58,69,58,70,58,71,58,72,58,73,58,74,58,75,58,76,58,77,58,78,58,79,58,80,58,81,58,82,58,83,58,84,58,85,58,86,58,87,58,88,58,89,58,90,58,91,58,92,58,93,58,94,58,95,58,96,58,97,58,98,58,99,58,100,58,101,58,102,58,103,58,104,58,105,58,106,58,107,58,108,58,109,58,110,58,111,58,112,58,113,58,114,58,115,58,116,58,117,58,118,58,119,58,120,58,121,58,122,58,123,58,124,58,125,58,126,59,33,59,34,59,35,59,36,59,37,59,38,59,39,59,40,59,41,59,42,59,43,59,44,59,45,59,46,59,47,59,48,59,49,59,50,59,51,59,52,59,53,59,54,59,55,59,56,59,57,59,58,59,59,59,60,59,61,59,62,59,63,59,64,59,65,59,66,59,67,59,68,59,69,59,70,59,71,59,72,59,73,59,74,59,75,59,76,59,77,59,78,59,79,59,80,59,81,59,82,59,83,59,84,59,85,59,86,59,87,59,88,59,89,59,90,59,91,59,92,59,93,59,94,59,95,59,96,59,97,59,98,59,99,59,100,59,101,59,102,59,103,59,104,59,105,59,106,59,107,59,108,59,109,59,110,59,111,59,112,59,113,59,114,59,115,59,116,59,117,59,118,59,119,59,120,59,121,59,122,59,123,59,124,59,125,59,126,60,33,60,34,60,35,60,36,60,37,60,38,60,39,60,40,60,41,60,42,60,43,60,44,60,45,60,46,60,47,60,48,60,49,60,50,60,51,60,52,60,53,60,54,60,55,60,56,60,57,60,58,60,59,60,60,60,61,60,62,60,63,60,64,60,65,60,66,60,67,60,68,60,69,60,70,60,71,60,72,60,73,60,74,60,75,60,76,60,77,60,78,60,79,60,80,60,81,60,82,60,83,60,84,60,85,60,86,60,87,60,88,60,89,60,90,60,91,60,92,60,93,60,94,60,95,60,96,60,97,60,98,60,99,60,100,60,101,60,102,60,103,60,104,60,105,60,106,60,107,60,108,60,109,60,110,60,111,60,112,60,113,60,114,60,115,60,116,60,117,60,118,60,119,60,120,60,121,60,122,60,123,60,124,60,125,60,126,61,33,61,34,61,35,61,36,61,37,61,38,61,39,61,40,61,41,61,42,61,43,61,44,61,45,61,46,61,47,61,48,61,49,61,50,61,51,61,52,61,53,61,54,61,55,61,56,61,57,61,58,61,59,61,60,61,61,61,62,61,63,61,64,61,65,61,66,61,67,61,68,61,69,61,70,61,71,61,72,61,73,61,74,61,75,61,76,61,77,61,78,61,79,61,80,61,81,61,82,61,83,61,84,61,85,61,86,61,87,61,88,61,89,61,90,61,91,61,92,61,93,61,94,61,95,61,96,61,97,61,98,61,99,61,100,61,101,61,102,61,103,61,104,61,105,61,106,61,107,61,108,61,109,61,110,61,111,61,112,61,113,61,114,61,115,61,116,61,117,61,118,61,119,61,120,61,121,61,122,61,123,61,124,61,125,61,126,62,33,62,34,62,35,62,36,62,37,62,38,62,39,62,40,62,41,62,42,62,43,62,44,62,45,62,46,62,47,62,48,62,49,62,50,62,51,62,52,62,53,62,54,62,55,62,56,62,57,62,58,62,59,62,60,62,61,62,62,62,63,62,64,62,65,62,66,62,67,62,68,62,69,62,70,62,71,62,72,62,73,62,74,62,75,62,76,62,77,62,78,62,79,62,80,62,81,62,82,62,83,62,84,62,85,62,86,62,87,62,88,62,89,62,90,62,91,62,92,62,93,62,94,62,95,62,96,62,97,62,98,62,99,62,100,62,101,62,102,62,103,62,104,62,105,62,106,62,107,62,108,62,109,62,110,62,111,62,112,62,113,62,114,62,115,62,116,62,117,62,118,62,119,62,120,62,121,62,122,62,123,62,124,62,125,62,126,63,33,63,34,63,35,63,36,63,37,63,38,63,39,63,40,63,41,63,42,63,43,63,44,63,45,63,46,63,47,63,48,63,49,63,50,63,51,63,52,63,53,63,54,63,55,63,56,63,57,63,58,63,59,63,60,63,61,63,62,63,63,63,64,63,65,63,66,63,67,63,68,63,69,63,70,63,71,63,72,63,73,63,74,63,75,63,76,63,77,63,78,63,79,63,80,63,81,63,82,63,83,63,84,63,85,63,86,63,87,63,88,63,89,63,90,63,91,63,92,63,93,63,94,63,95,63,96,63,97,63,98,63,99,63,100,63,101,63,102,63,103,63,104,63,105,63,106,63,107,63,108,63,109,63,110,63,111,63,112,63,113,63,114,63,115,63,116,63,117,63,118,63,119,63,120,63,121,63,122,63,123,63,124,63,125,63,126,64,33,64,34,64,35,64,36,64,37,64,38,64,39,64,40,64,41,64,42,64,43,64,44,64,45,64,46,64,47,64,48,64,49,64,50,64,51,64,52,64,53,64,54,64,55,64,56,64,57,64,58,64,59,64,60,64,61,64,62,64,63,64,64,64,65,64,66,64,67,64,68,64,69,64,70,64,71,64,72,64,73,64,74,64,75,64,76,64,77,64,78,64,79,64,80,64,81,64,82,64,83,64,84,64,85,64,86,64,87,64,88,64,89,64,90,64,91,64,92,64,93,64,94,64,95,64,96,64,97,64,98,64,99,64,100,64,101,64,102,64,103,64,104,64,105,64,106,64,107,64,108,64,109,64,110,64,111,64,112,64,113,64,114,64,115,64,116,64,117,64,118,64,119,64,120,64,121,64,122,64,123,64,124,64,125,64,126,65,33,65,34,65,35,65,36,65,37,65,38,65,39,65,40,65,41,65,42,65,43,65,44,65,45,65,46,65,47,65,48,65,49,65,50,65,51,65,52,65,53,65,54,65,55,65,56,65,57,65,58,65,59,65,60,65,61,65,62,65,63,65,64,65,65,65,66,65,67,65,68,65,69,65,70,65,71,65,72,65,73,65,74,65,75,65,76,65,77,65,78,65,79,65,80,65,81,65,82,65,83,65,84,65,85,65,86,65,87,65,88,65,89,65,90,65,91,65,92,65,93,65,94,65,95,65,96,65,97,65,98,65,99,65,100,65,101,65,102,65,103,65,104,65,105,65,106,65,107,65,108,65,109,65,110,65,111,65,112,65,113,65,114,65,115,65,116,65,117,65,118,65,119,65,120,65,121,65,122,65,123,65,124,65,125,65,126,66,33,66,34,66,35,66,36,66,37,66,38,66,39,66,40,66,41,66,42,66,43,66,44,66,45,66,46,66,47,66,48,66,49,66,50,66,51,66,52,66,53,66,54,66,55,66,56,66,57,66,58,66,59,66,60,66,61,66,62,66,63,66,64,66,65,66,66,66,67,66,68,66,69,66,70,66,71,66,72,66,73,66,74,66,75,66,76,66,77,66,78,66,79,66,80,66,81,66,82,66,83,66,84,66,85,66,86,66,87,66,88,66,89,66,90,66,91,66,92,66,93,66,94,66,95,66,96,66,97,66,98,66,99,66,100,66,101,66,102,66,103,66,104,66,105,66,106,66,107,66,108,66,109,66,110,66,111,66,112,66,113,66,114,66,115,66,116,66,117,66,118,66,119,66,120,66,121,66,122,66,123,66,124,66,125,66,126,67,33,67,34,67,35,67,36,67,37,67,38,67,39,67,40,67,41,67,42,67,43,67,44,67,45,67,46,67,47,67,48,67,49,67,50,67,51,67,52,67,53,67,54,67,55,67,56,67,57,67,58,67,59,67,60,67,61,67,62,67,63,67,64,67,65,67,66,67,67,67,68,67,69,67,70,67,71,67,72,67,73,67,74,67,75,67,76,67,77,67,78,67,79,67,80,67,81,67,82,67,83,67,84,67,85,67,86,67,87,67,88,67,89,67,90,67,91,67,92,67,93,67,94,67,95,67,96,67,97,67,98,67,99,67,100,67,101,67,102,67,103,67,104,67,105,67,106,67,107,67,108,67,109,67,110,67,111,67,112,67,113,67,114,67,115,67,116,67,117,67,118,67,119,67,120,67,121,67,122,67,123,67,124,67,125,67,126,68,33,68,34,68,35,68,36,68,37,68,38,68,39,68,40,68,41,68,42,68,43,68,44,68,45,68,46,68,47,68,48,68,49,68,50,68,51,68,52,68,53,68,54,68,55,68,56,68,57,68,58,68,59,68,60,68,61,68,62,68,63,68,64,68,65,68,66,68,67,68,68,68,69,68,70,68,71,68,72,68,73,68,74,68,75,68,76,68,77,68,78,68,79,68,80,68,81,68,82,68,83,68,84,68,85,68,86,68,87,68,88,68,89,68,90,68,91,68,92,68,93,68,94,68,95,68,96,68,97,68,98,68,99,68,100,68,101,68,102,68,103,68,104,68,105,68,106,68,107,68,108,68,109,68,110,68,111,68,112,68,113,68,114,68,115,68,116,68,117,68,118,68,119,68,120,68,121,68,122,68,123,68,124,68,125,68,126,69,33,69,34,69,35,69,36,69,37,69,38,69,39,69,40,69,41,69,42,69,43,69,44,69,45,69,46,69,47,69,48,69,49,69,50,69,51,69,52,69,53,69,54,69,55,69,56,69,57,69,58,69,59,69,60,69,61,69,62,69,63,69,64,69,65,69,66,69,67,69,68,69,69,69,70,69,71,69,72,69,73,69,74,69,75,69,76,69,77,69,78,69,79,69,80,69,81,69,82,69,83,69,84,69,85,69,86,69,87,69,88,69,89,69,90,69,91,69,92,69,93,69,94,69,95,69,96,69,97,69,98,69,99,69,100,69,101,69,102,69,103,69,104,69,105,69,106,69,107,69,108,69,109,69,110,69,111,69,112,69,113,69,114,69,115,69,116,69,117,69,118,69,119,69,120,69,121,69,122,69,123,69,124,69,125,69,126,70,33,70,34,70,35,70,36,70,37,70,38,70,39,70,40,70,41,70,42,70,43,70,44,70,45,70,46,70,47,70,48,70,49,70,50,70,51,70,52,70,53,70,54,70,55,70,56,70,57,70,58,70,59,70,60,70,61,70,62,70,63,70,64,70,65,70,66,70,67,70,68,70,69,70,70,70,71,70,72,70,73,70,74,70,75,70,76,70,77,70,78,70,79,70,80,70,81,70,82,70,83,70,84,70,85,70,86,70,87,70,88,70,89,70,90,70,91,70,92,70,93,70,94,70,95,70,96,70,97,70,98,70,99,70,100,70,101,70,102,70,103,70,104,70,105,70,106,70,107,70,108,70,109,70,110,70,111,70,112,70,113,70,114,70,115,70,116,70,117,70,118,70,119,70,120,70,121,70,122,70,123,70,124,70,125,70,126,71,33,71,34,71,35,71,36,71,37,71,38,71,39,71,40,71,41,71,42,71,43,71,44,71,45,71,46,71,47,71,48,71,49,71,50,71,51,71,52,71,53,71,54,71,55,71,56,71,57,71,58,71,59,71,60,71,61,71,62,71,63,71,64,71,65,71,66,71,67,71,68,71,69,71,70,71,71,71,72,71,73,71,74,71,75,71,76,71,77,71,78,71,79,71,80,71,81,71,82,71,83,71,84,71,85,71,86,71,87,71,88,71,89,71,90,71,91,71,92,71,93,71,94,71,95,71,96,71,97,71,98,71,99,71,100,71,101,71,102,71,103,71,104,71,105,71,106,71,107,71,108,71,109,71,110,71,111,71,112,71,113,71,114,71,115,71,116,71,117,71,118,71,119,71,120,71,121,71,122,71,123,71,124,71,125,71,126,72,33,72,34,72,35,72,36,72,37,72,38,72,39,72,40,72,41,72,42,72,43,72,44,72,45,72,46,72,47,72,48,72,49,72,50,72,51,72,52,72,53,72,54,72,55,72,56,72,57,72,58,72,59,72,60,72,61,72,62,72,63,72,64,72,65,72,66,72,67,72,68,72,69,72,70,72,71,72,72,72,73,72,74,72,75,72,76,72,77,72,78,72,79,72,80,72,81,72,82,72,83,72,84,72,85,72,86,72,87,72,88,72,89,72,90,72,91,72,92,72,93,72,94,72,95,72,96,72,97,72,98,72,99,72,100,72,101,72,102,72,103,72,104,72,105,72,106,72,107,72,108,72,109,72,110,72,111,72,112,72,113,72,114,72,115,72,116,72,117,72,118,72,119,72,120,72,121,72,122,72,123,72,124,72,125,72,126,74,33,74,34,74,35,74,36,74,37,74,38,74,39,74,40,74,41,74,42,74,43,74,44,74,45,74,46,74,47,74,48,74,49,74,50,74,51,74,52,74,53,74,54,74,55,74,56,74,57,74,58,74,59,74,60,74,61,74,62,74,63,74,64,74,65,74,66,74,67,74,68,74,69,74,70,74,71,74,72,74,73,74,74,74,75,74,76,74,77,74,78,74,79,74,80,74,81,74,82,74,83,74,84,74,85,74,86,74,87,74,88,74,89,74,90,74,91,74,92,74,93,74,94,74,95,74,96,74,97,74,98,74,99,74,100,74,101,74,102,74,103,74,104,74,105,74,106,74,107,74,108,74,109,74,110,74,111,74,112,74,113,74,114,74,115,74,116,74,117,74,118,74,119,74,120,74,121,74,122,74,123,74,124,74,125,74,126,75,33,75,34,75,35,75,36,75,37,75,38,75,39,75,40,75,41,75,42,75,43,75,44,75,45,75,46,75,47,75,48,75,49,75,50,75,51,75,52,75,53,75,54,75,55,75,56,75,57,75,58,75,59,75,60,75,61,75,62,75,63,75,64,75,65,75,66,75,67,75,68,75,69,75,70,75,71,75,72,75,73,75,74,75,75,75,76,75,77,75,78,75,79,75,80,75,81,75,82,75,83,75,84,75,85,75,86,75,87,75,88,75,89,75,90,75,91,75,92,75,93,75,94,75,95,75,96,75,97,75,98,75,99,75,100,75,101,75,102,75,103,75,104,75,105,75,106,75,107,75,108,75,109,75,110,75,111,75,112,75,113,75,114,75,115,75,116,75,117,75,118,75,119,75,120,75,121,75,122,75,123,75,124,75,125,75,126,76,33,76,34,76,35,76,36,76,37,76,38,76,39,76,40,76,41,76,42,76,43,76,44,76,45,76,46,76,47,76,48,76,49,76,50,76,51,76,52,76,53,76,54,76,55,76,56,76,57,76,58,76,59,76,60,76,61,76,62,76,63,76,64,76,65,76,66,76,67,76,68,76,69,76,70,76,71,76,72,76,73,76,74,76,75,76,76,76,77,76,78,76,79,76,80,76,81,76,82,76,83,76,84,76,85,76,86,76,87,76,88,76,89,76,90,76,91,76,92,76,93,76,94,76,95,76,96,76,97,76,98,76,99,76,100,76,101,76,102,76,103,76,104,76,105,76,106,76,107,76,108,76,109,76,110,76,111,76,112,76,113,76,114,76,115,76,116,76,117,76,118,76,119,76,120,76,121,76,122,76,123,76,124,76,125,76,126,77,33,77,34,77,35,77,36,77,37,77,38,77,39,77,40,77,41,77,42,77,43,77,44,77,45,77,46,77,47,77,48,77,49,77,50,77,51,77,52,77,53,77,54,77,55,77,56,77,57,77,58,77,59,77,60,77,61,77,62,77,63,77,64,77,65,77,66,77,67,77,68,77,69,77,70,77,71,77,72,77,73,77,74,77,75,77,76,77,77,77,78,77,79,77,80,77,81,77,82,77,83,77,84,77,85,77,86,77,87,77,88,77,89,77,90,77,91,77,92,77,93,77,94,77,95,77,96,77,97,77,98,77,99,77,100,77,101,77,102,77,103,77,104,77,105,77,106,77,107,77,108,77,109,77,110,77,111,77,112,77,113,77,114,77,115,77,116,77,117,77,118,77,119,77,120,77,121,77,122,77,123,77,124,77,125,77,126,78,33,78,34,78,35,78,36,78,37,78,38,78,39,78,40,78,41,78,42,78,43,78,44,78,45,78,46,78,47,78,48,78,49,78,50,78,51,78,52,78,53,78,54,78,55,78,56,78,57,78,58,78,59,78,60,78,61,78,62,78,63,78,64,78,65,78,66,78,67,78,68,78,69,78,70,78,71,78,72,78,73,78,74,78,75,78,76,78,77,78,78,78,79,78,80,78,81,78,82,78,83,78,84,78,85,78,86,78,87,78,88,78,89,78,90,78,91,78,92,78,93,78,94,78,95,78,96,78,97,78,98,78,99,78,100,78,101,78,102,78,103,78,104,78,105,78,106,78,107,78,108,78,109,78,110,78,111,78,112,78,113,78,114,78,115,78,116,78,117,78,118,78,119,78,120,78,121,78,122,78,123,78,124,78,125,78,126,79,33,79,34,79,35,79,36,79,37,79,38,79,39,79,40,79,41,79,42,79,43,79,44,79,45,79,46,79,47,79,48,79,49,79,50,79,51,79,52,79,53,79,54,79,55,79,56,79,57,79,58,79,59,79,60,79,61,79,62,79,63,79,64,79,65,79,66,79,67,79,68,79,69,79,70,79,71,79,72,79,73,79,74,79,75,79,76,79,77,79,78,79,79,79,80,79,81,79,82,79,83,79,84,79,85,79,86,79,87,79,88,79,89,79,90,79,91,79,92,79,93,79,94,79,95,79,96,79,97,79,98,79,99,79,100,79,101,79,102,79,103,79,104,79,105,79,106,79,107,79,108,79,109,79,110,79,111,79,112,79,113,79,114,79,115,79,116,79,117,79,118,79,119,79,120,79,121,79,122,79,123,79,124,79,125,79,126,80,33,80,34,80,35,80,36,80,37,80,38,80,39,80,40,80,41,80,42,80,43,80,44,80,45,80,46,80,47,80,48,80,49,80,50,80,51,80,52,80,53,80,54,80,55,80,56,80,57,80,58,80,59,80,60,80,61,80,62,80,63,80,64,80,65,80,66,80,67,80,68,80,69,80,70,80,71,80,72,80,73,80,74,80,75,80,76,80,77,80,78,80,79,80,80,80,81,80,82,80,83,80,84,80,85,80,86,80,87,80,88,80,89,80,90,80,91,80,92,80,93,80,94,80,95,80,96,80,97,80,98,80,99,80,100,80,101,80,102,80,103,80,104,80,105,80,106,80,107,80,108,80,109,80,110,80,111,80,112,80,113,80,114,80,115,80,116,80,117,80,118,80,119,80,120,80,121,80,122,80,123,80,124,80,125,80,126,81,33,81,34,81,35,81,36,81,37,81,38,81,39,81,40,81,41,81,42,81,43,81,44,81,45,81,46,81,47,81,48,81,49,81,50,81,51,81,52,81,53,81,54,81,55,81,56,81,57,81,58,81,59,81,60,81,61,81,62,81,63,81,64,81,65,81,66,81,67,81,68,81,69,81,70,81,71,81,72,81,73,81,74,81,75,81,76,81,77,81,78,81,79,81,80,81,81,81,82,81,83,81,84,81,85,81,86,81,87,81,88,81,89,81,90,81,91,81,92,81,93,81,94,81,95,81,96,81,97,81,98,81,99,81,100,81,101,81,102,81,103,81,104,81,105,81,106,81,107,81,108,81,109,81,110,81,111,81,112,81,113,81,114,81,115,81,116,81,117,81,118,81,119,81,120,81,121,81,122,81,123,81,124,81,125,81,126,82,33,82,34,82,35,82,36,82,37,82,38,82,39,82,40,82,41,82,42,82,43,82,44,82,45,82,46,82,47,82,48,82,49,82,50,82,51,82,52,82,53,82,54,82,55,82,56,82,57,82,58,82,59,82,60,82,61,82,62,82,63,82,64,82,65,82,66,82,67,82,68,82,69,82,70,82,71,82,72,82,73,82,74,82,75,82,76,82,77,82,78,82,79,82,80,82,81,82,82,82,83,82,84,82,85,82,86,82,87,82,88,82,89,82,90,82,91,82,92,82,93,82,94,82,95,82,96,82,97,82,98,82,99,82,100,82,101,82,102,82,103,82,104,82,105,82,106,82,107,82,108,82,109,82,110,82,111,82,112,82,113,82,114,82,115,82,116,82,117,82,118,82,119,82,120,82,121,82,122,82,123,82,124,82,125,82,126,83,33,83,34,83,35,83,36,83,37,83,38,83,39,83,40,83,41,83,42,83,43,83,44,83,45,83,46,83,47,83,48,83,49,83,50,83,51,83,52,83,53,83,54,83,55,83,56,83,57,83,58,83,59,83,60,83,61,83,62,83,63,83,64,83,65,83,66,83,67,83,68,83,69,83,70,83,71,83,72,83,73,83,74,83,75,83,76,83,77,83,78,83,79,83,80,83,81,83,82,83,83,83,84,83,85,83,86,83,87,83,88,83,89,83,90,83,91,83,92,83,93,83,94,83,95,83,96,83,97,83,98,83,99,83,100,83,101,83,102,83,103,83,104,83,105,83,106,83,107,83,108,83,109,83,110,83,111,83,112,83,113,83,114,83,115,83,116,83,117,83,118,83,119,83,120,83,121,83,122,83,123,83,124,83,125,83,126,84,33,84,34,84,35,84,36,84,37,84,38,84,39,84,40,84,41,84,42,84,43,84,44,84,45,84,46,84,47,84,48,84,49,84,50,84,51,84,52,84,53,84,54,84,55,84,56,84,57,84,58,84,59,84,60,84,61,84,62,84,63,84,64,84,65,84,66,84,67,84,68,84,69,84,70,84,71,84,72,84,73,84,74,84,75,84,76,84,77,84,78,84,79,84,80,84,81,84,82,84,83,84,84,84,85,84,86,84,87,84,88,84,89,84,90,84,91,84,92,84,93,84,94,84,95,84,96,84,97,84,98,84,99,84,100,84,101,84,102,84,103,84,104,84,105,84,106,84,107,84,108,84,109,84,110,84,111,84,112,84,113,84,114,84,115,84,116,84,117,84,118,84,119,84,120,84,121,84,122,84,123,84,124,84,125,84,126,85,33,85,34,85,35,85,36,85,37,85,38,85,39,85,40,85,41,85,42,85,43,85,44,85,45,85,46,85,47,85,48,85,49,85,50,85,51,85,52,85,53,85,54,85,55,85,56,85,57,85,58,85,59,85,60,85,61,85,62,85,63,85,64,85,65,85,66,85,67,85,68,85,69,85,70,85,71,85,72,85,73,85,74,85,75,85,76,85,77,85,78,85,79,85,80,85,81,85,82,85,83,85,84,85,85,85,86,85,87,85,88,85,89,85,90,85,91,85,92,85,93,85,94,85,95,85,96,85,97,85,98,85,99,85,100,85,101,85,102,85,103,85,104,85,105,85,106,85,107,85,108,85,109,85,110,85,111,85,112,85,113,85,114,85,115,85,116,85,117,85,118,85,119,85,120,85,121,85,122,85,123,85,124,85,125,85,126,86,33,86,34,86,35,86,36,86,37,86,38,86,39,86,40,86,41,86,42,86,43,86,44,86,45,86,46,86,47,86,48,86,49,86,50,86,51,86,52,86,53,86,54,86,55,86,56,86,57,86,58,86,59,86,60,86,61,86,62,86,63,86,64,86,65,86,66,86,67,86,68,86,69,86,70,86,71,86,72,86,73,86,74,86,75,86,76,86,77,86,78,86,79,86,80,86,81,86,82,86,83,86,84,86,85,86,86,86,87,86,88,86,89,86,90,86,91,86,92,86,93,86,94,86,95,86,96,86,97,86,98,86,99,86,100,86,101,86,102,86,103,86,104,86,105,86,106,86,107,86,108,86,109,86,110,86,111,86,112,86,113,86,114,86,115,86,116,86,117,86,118,86,119,86,120,86,121,86,122,86,123,86,124,86,125,86,126,87,33,87,34,87,35,87,36,87,37,87,38,87,39,87,40,87,41,87,42,87,43,87,44,87,45,87,46,87,47,87,48,87,49,87,50,87,51,87,52,87,53,87,54,87,55,87,56,87,57,87,58,87,59,87,60,87,61,87,62,87,63,87,64,87,65,87,66,87,67,87,68,87,69,87,70,87,71,87,72,87,73,87,74,87,75,87,76,87,77,87,78,87,79,87,80,87,81,87,82,87,83,87,84,87,85,87,86,87,87,87,88,87,89,87,90,87,91,87,92,87,93,87,94,87,95,87,96,87,97,87,98,87,99,87,100,87,101,87,102,87,103,87,104,87,105,87,106,87,107,87,108,87,109,87,110,87,111,87,112,87,113,87,114,87,115,87,116,87,117,87,118,87,119,87,120,87,121,87,122,87,123,87,124,87,125,87,126,88,33,88,34,88,35,88,36,88,37,88,38,88,39,88,40,88,41,88,42,88,43,88,44,88,45,88,46,88,47,88,48,88,49,88,50,88,51,88,52,88,53,88,54,88,55,88,56,88,57,88,58,88,59,88,60,88,61,88,62,88,63,88,64,88,65,88,66,88,67,88,68,88,69,88,70,88,71,88,72,88,73,88,74,88,75,88,76,88,77,88,78,88,79,88,80,88,81,88,82,88,83,88,84,88,85,88,86,88,87,88,88,88,89,88,90,88,91,88,92,88,93,88,94,88,95,88,96,88,97,88,98,88,99,88,100,88,101,88,102,88,103,88,104,88,105,88,106,88,107,88,108,88,109,88,110,88,111,88,112,88,113,88,114,88,115,88,116,88,117,88,118,88,119,88,120,88,121,88,122,88,123,88,124,88,125,88,126,89,33,89,34,89,35,89,36,89,37,89,38,89,39,89,40,89,41,89,42,89,43,89,44,89,45,89,46,89,47,89,48,89,49,89,50,89,51,89,52,89,53,89,54,89,55,89,56,89,57,89,58,89,59,89,60,89,61,89,62,89,63,89,64,89,65,89,66,89,67,89,68,89,69,89,70,89,71,89,72,89,73,89,74,89,75,89,76,89,77,89,78,89,79,89,80,89,81,89,82,89,83,89,84,89,85,89,86,89,87,89,88,89,89,89,90,89,91,89,92,89,93,89,94,89,95,89,96,89,97,89,98,89,99,89,100,89,101,89,102,89,103,89,104,89,105,89,106,89,107,89,108,89,109,89,110,89,111,89,112,89,113,89,114,89,115,89,116,89,117,89,118,89,119,89,120,89,121,89,122,89,123,89,124,89,125,89,126,90,33,90,34,90,35,90,36,90,37,90,38,90,39,90,40,90,41,90,42,90,43,90,44,90,45,90,46,90,47,90,48,90,49,90,50,90,51,90,52,90,53,90,54,90,55,90,56,90,57,90,58,90,59,90,60,90,61,90,62,90,63,90,64,90,65,90,66,90,67,90,68,90,69,90,70,90,71,90,72,90,73,90,74,90,75,90,76,90,77,90,78,90,79,90,80,90,81,90,82,90,83,90,84,90,85,90,86,90,87,90,88,90,89,90,90,90,91,90,92,90,93,90,94,90,95,90,96,90,97,90,98,90,99,90,100,90,101,90,102,90,103,90,104,90,105,90,106,90,107,90,108,90,109,90,110,90,111,90,112,90,113,90,114,90,115,90,116,90,117,90,118,90,119,90,120,90,121,90,122,90,123,90,124,90,125,90,126,91,33,91,34,91,35,91,36,91,37,91,38,91,39,91,40,91,41,91,42,91,43,91,44,91,45,91,46,91,47,91,48,91,49,91,50,91,51,91,52,91,53,91,54,91,55,91,56,91,57,91,58,91,59,91,60,91,61,91,62,91,63,91,64,91,65,91,66,91,67,91,68,91,69,91,70,91,71,91,72,91,73,91,74,91,75,91,76,91,77,91,78,91,79,91,80,91,81,91,82,91,83,91,84,91,85,91,86,91,87,91,88,91,89,91,90,91,91,91,92,91,93,91,94,91,95,91,96,91,97,91,98,91,99,91,100,91,101,91,102,91,103,91,104,91,105,91,106,91,107,91,108,91,109,91,110,91,111,91,112,91,113,91,114,91,115,91,116,91,117,91,118,91,119,91,120,91,121,91,122,91,123,91,124,91,125,91,126,92,33,92,34,92,35,92,36,92,37,92,38,92,39,92,40,92,41,92,42,92,43,92,44,92,45,92,46,92,47,92,48,92,49,92,50,92,51,92,52,92,53,92,54,92,55,92,56,92,57,92,58,92,59,92,60,92,61,92,62,92,63,92,64,92,65,92,66,92,67,92,68,92,69,92,70,92,71,92,72,92,73,92,74,92,75,92,76,92,77,92,78,92,79,92,80,92,81,92,82,92,83,92,84,92,85,92,86,92,87,92,88,92,89,92,90,92,91,92,92,92,93,92,94,92,95,92,96,92,97,92,98,92,99,92,100,92,101,92,102,92,103,92,104,92,105,92,106,92,107,92,108,92,109,92,110,92,111,92,112,92,113,92,114,92,115,92,116,92,117,92,118,92,119,92,120,92,121,92,122,92,123,92,124,92,125,92,126,93,33,93,34,93,35,93,36,93,37,93,38,93,39,93,40,93,41,93,42,93,43,93,44,93,45,93,46,93,47,93,48,93,49,93,50,93,51,93,52,93,53,93,54,93,55,93,56,93,57,93,58,93,59,93,60,93,61,93,62,93,63,93,64,93,65,93,66,93,67,93,68,93,69,93,70,93,71,93,72,93,73,93,74,93,75,93,76,93,77,93,78,93,79,93,80,93,81,93,82,93,83,93,84,93,85,93,86,93,87,93,88,93,89,93,90,93,91,93,92,93,93,93,94,93,95,93,96,93,97,93,98,93,99,93,100,93,101,93,102,93,103,93,104,93,105,93,106,93,107,93,108,93,109,93,110,93,111,93,112,93,113,93,114,93,115,93,116,93,117,93,118,93,119,93,120,93,121,93,122,93,123,93,124,93,125,93,126,94,33,94,34,94,35,94,36,94,37,94,38,94,39,94,40,94,41,94,42,94,43,94,44,94,45,94,46,94,47,94,48,94,49,94,50,94,51,94,52,94,53,94,54,94,55,94,56,94,57,94,58,94,59,94,60,94,61,94,62,94,63,94,64,94,65,94,66,94,67,94,68,94,69,94,70,94,71,94,72,94,73,94,74,94,75,94,76,94,77,94,78,94,79,94,80,94,81,94,82,94,83,94,84,94,85,94,86,94,87,94,88,94,89,94,90,94,91,94,92,94,93,94,94,94,95,94,96,94,97,94,98,94,99,94,100,94,101,94,102,94,103,94,104,94,105,94,106,94,107,94,108,94,109,94,110,94,111,94,112,94,113,94,114,94,115,94,116,94,117,94,118,94,119,94,120,94,121,94,122,94,123,94,124,94,125,94,126,95,33,95,34,95,35,95,36,95,37,95,38,95,39,95,40,95,41,95,42,95,43,95,44,95,45,95,46,95,47,95,48,95,49,95,50,95,51,95,52,95,53,95,54,95,55,95,56,95,57,95,58,95,59,95,60,95,61,95,62,95,63,95,64,95,65,95,66,95,67,95,68,95,69,95,70,95,71,95,72,95,73,95,74,95,75,95,76,95,77,95,78,95,79,95,80,95,81,95,82,95,83,95,84,95,85,95,86,95,87,95,88,95,89,95,90,95,91,95,92,95,93,95,94,95,95,95,96,95,97,95,98,95,99,95,100,95,101,95,102,95,103,95,104,95,105,95,106,95,107,95,108,95,109,95,110,95,111,95,112,95,113,95,114,95,115,95,116,95,117,95,118,95,119,95,120,95,121,95,122,95,123,95,124,95,125,95,126,96,33,96,34,96,35,96,36,96,37,96,38,96,39,96,40,96,41,96,42,96,43,96,44,96,45,96,46,96,47,96,48,96,49,96,50,96,51,96,52,96,53,96,54,96,55,96,56,96,57,96,58,96,59,96,60,96,61,96,62,96,63,96,64,96,65,96,66,96,67,96,68,96,69,96,70,96,71,96,72,96,73,96,74,96,75,96,76,96,77,96,78,96,79,96,80,96,81,96,82,96,83,96,84,96,85,96,86,96,87,96,88,96,89,96,90,96,91,96,92,96,93,96,94,96,95,96,96,96,97,96,98,96,99,96,100,96,101,96,102,96,103,96,104,96,105,96,106,96,107,96,108,96,109,96,110,96,111,96,112,96,113,96,114,96,115,96,116,96,117,96,118,96,119,96,120,96,121,96,122,96,123,96,124,96,125,96,126,97,33,97,34,97,35,97,36,97,37,97,38,97,39,97,40,97,41,97,42,97,43,97,44,97,45,97,46,97,47,97,48,97,49,97,50,97,51,97,52,97,53,97,54,97,55,97,56,97,57,97,58,97,59,97,60,97,61,97,62,97,63,97,64,97,65,97,66,97,67,97,68,97,69,97,70,97,71,97,72,97,73,97,74,97,75,97,76,97,77,97,78,97,79,97,80,97,81,97,82,97,83,97,84,97,85,97,86,97,87,97,88,97,89,97,90,97,91,97,92,97,93,97,94,97,95,97,96,97,97,97,98,97,99,97,100,97,101,97,102,97,103,97,104,97,105,97,106,97,107,97,108,97,109,97,110,97,111,97,112,97,113,97,114,97,115,97,116,97,117,97,118,97,119,97,120,97,121,97,122,97,123,97,124,97,125,97,126,98,33,98,34,98,35,98,36,98,37,98,38,98,39,98,40,98,41,98,42,98,43,98,44,98,45,98,46,98,47,98,48,98,49,98,50,98,51,98,52,98,53,98,54,98,55,98,56,98,57,98,58,98,59,98,60,98,61,98,62,98,63,98,64,98,65,98,66,98,67,98,68,98,69,98,70,98,71,98,72,98,73,98,74,98,75,98,76,98,77,98,78,98,79,98,80,98,81,98,82,98,83,98,84,98,85,98,86,98,87,98,88,98,89,98,90,98,91,98,92,98,93,98,94,98,95,98,96,98,97,98,98,98,99,98,100,98,101,98,102,98,103,98,104,98,105,98,106,98,107,98,108,98,109,98,110,98,111,98,112,98,113,98,114,98,115,98,116,98,117,98,118,98,119,98,120,98,121,98,122,98,123,98,124,98,125,98,126,99,33,99,34,99,35,99,36,99,37,99,38,99,39,99,40,99,41,99,42,99,43,99,44,99,45,99,46,99,47,99,48,99,49,99,50,99,51,99,52,99,53,99,54,99,55,99,56,99,57,99,58,99,59,99,60,99,61,99,62,99,63,99,64,99,65,99,66,99,67,99,68,99,69,99,70,99,71,99,72,99,73,99,74,99,75,99,76,99,77,99,78,99,79,99,80,99,81,99,82,99,83,99,84,99,85,99,86,99,87,99,88,99,89,99,90,99,91,99,92,99,93,99,94,99,95,99,96,99,97,99,98,99,99,99,100,99,101,99,102,99,103,99,104,99,105,99,106,99,107,99,108,99,109,99,110,99,111,99,112,99,113,99,114,99,115,99,116,99,117,99,118,99,119,99,120,99,121,99,122,99,123,99,124,99,125,99,126,100,33,100,34,100,35,100,36,100,37,100,38,100,39,100,40,100,41,100,42,100,43,100,44,100,45,100,46,100,47,100,48,100,49,100,50,100,51,100,52,100,53,100,54,100,55,100,56,100,57,100,58,100,59,100,60,100,61,100,62,100,63,100,64,100,65,100,66,100,67,100,68,100,69,100,70,100,71,100,72,100,73,100,74,100,75,100,76,100,77,100,78,100,79,100,80,100,81,100,82,100,83,100,84,100,85,100,86,100,87,100,88,100,89,100,90,100,91,100,92,100,93,100,94,100,95,100,96,100,97,100,98,100,99,100,100,100,101,100,102,100,103,100,104,100,105,100,106,100,107,100,108,100,109,100,110,100,111,100,112,100,113,100,114,100,115,100,116,100,117,100,118,100,119,100,120,100,121,100,122,100,123,100,124,100,125,100,126,101,33,101,34,101,35,101,36,101,37,101,38,101,39,101,40,101,41,101,42,101,43,101,44,101,45,101,46,101,47,101,48,101,49,101,50,101,51,101,52,101,53,101,54,101,55,101,56,101,57,101,58,101,59,101,60,101,61,101,62,101,63,101,64,101,65,101,66,101,67,101,68,101,69,101,70,101,71,101,72,101,73,101,74,101,75,101,76,101,77,101,78,101,79,101,80,101,81,101,82,101,83,101,84,101,85,101,86,101,87,101,88,101,89,101,90,101,91,101,92,101,93,101,94,101,95,101,96,101,97,101,98,101,99,101,100,101,101,101,102,101,103,101,104,101,105,101,106,101,107,101,108,101,109,101,110,101,111,101,112,101,113,101,114,101,115,101,116,101,117,101,118,101,119,101,120,101,121,101,122,101,123,101,124,101,125,101,126,102,33,102,34,102,35,102,36,102,37,102,38,102,39,102,40,102,41,102,42,102,43,102,44,102,45,102,46,102,47,102,48,102,49,102,50,102,51,102,52,102,53,102,54,102,55,102,56,102,57,102,58,102,59,102,60,102,61,102,62,102,63,102,64,102,65,102,66,102,67,102,68,102,69,102,70,102,71,102,72,102,73,102,74,102,75,102,76,102,77,102,78,102,79,102,80,102,81,102,82,102,83,102,84,102,85,102,86,102,87,102,88,102,89,102,90,102,91,102,92,102,93,102,94,102,95,102,96,102,97,102,98,102,99,102,100,102,101,102,102,102,103,102,104,102,105,102,106,102,107,102,108,102,109,102,110,102,111,102,112,102,113,102,114,102,115,102,116,102,117,102,118,102,119,102,120,102,121,102,122,102,123,102,124,102,125,102,126,103,33,103,34,103,35,103,36,103,37,103,38,103,39,103,40,103,41,103,42,103,43,103,44,103,45,103,46,103,47,103,48,103,49,103,50,103,51,103,52,103,53,103,54,103,55,103,56,103,57,103,58,103,59,103,60,103,61,103,62,103,63,103,64,103,65,103,66,103,67,103,68,103,69,103,70,103,71,103,72,103,73,103,74,103,75,103,76,103,77,103,78,103,79,103,80,103,81,103,82,103,83,103,84,103,85,103,86,103,87,103,88,103,89,103,90,103,91,103,92,103,93,103,94,103,95,103,96,103,97,103,98,103,99,103,100,103,101,103,102,103,103,103,104,103,105,103,106,103,107,103,108,103,109,103,110,103,111,103,112,103,113,103,114,103,115,103,116,103,117,103,118,103,119,103,120,103,121,103,122,103,123,103,124,103,125,103,126,104,33,104,34,104,35,104,36,104,37,104,38,104,39,104,40,104,41,104,42,104,43,104,44,104,45,104,46,104,47,104,48,104,49,104,50,104,51,104,52,104,53,104,54,104,55,104,56,104,57,104,58,104,59,104,60,104,61,104,62,104,63,104,64,104,65,104,66,104,67,104,68,104,69,104,70,104,71,104,72,104,73,104,74,104,75,104,76,104,77,104,78,104,79,104,80,104,81,104,82,104,83,104,84,104,85,104,86,104,87,104,88,104,89,104,90,104,91,104,92,104,93,104,94,104,95,104,96,104,97,104,98,104,99,104,100,104,101,104,102,104,103,104,104,104,105,104,106,104,107,104,108,104,109,104,110,104,111,104,112,104,113,104,114,104,115,104,116,104,117,104,118,104,119,104,120,104,121,104,122,104,123,104,124,104,125,104,126,105,33,105,34,105,35,105,36,105,37,105,38,105,39,105,40,105,41,105,42,105,43,105,44,105,45,105,46,105,47,105,48,105,49,105,50,105,51,105,52,105,53,105,54,105,55,105,56,105,57,105,58,105,59,105,60,105,61,105,62,105,63,105,64,105,65,105,66,105,67,105,68,105,69,105,70,105,71,105,72,105,73,105,74,105,75,105,76,105,77,105,78,105,79,105,80,105,81,105,82,105,83,105,84,105,85,105,86,105,87,105,88,105,89,105,90,105,91,105,92,105,93,105,94,105,95,105,96,105,97,105,98,105,99,105,100,105,101,105,102,105,103,105,104,105,105,105,106,105,107,105,108,105,109,105,110,105,111,105,112,105,113,105,114,105,115,105,116,105,117,105,118,105,119,105,120,105,121,105,122,105,123,105,124,105,125,105,126,106,33,106,34,106,35,106,36,106,37,106,38,106,39,106,40,106,41,106,42,106,43,106,44,106,45,106,46,106,47,106,48,106,49,106,50,106,51,106,52,106,53,106,54,106,55,106,56,106,57,106,58,106,59,106,60,106,61,106,62,106,63,106,64,106,65,106,66,106,67,106,68,106,69,106,70,106,71,106,72,106,73,106,74,106,75,106,76,106,77,106,78,106,79,106,80,106,81,106,82,106,83,106,84,106,85,106,86,106,87,106,88,106,89,106,90,106,91,106,92,106,93,106,94,106,95,106,96,106,97,106,98,106,99,106,100,106,101,106,102,106,103,106,104,106,105,106,106,106,107,106,108,106,109,106,110,106,111,106,112,106,113,106,114,106,115,106,116,106,117,106,118,106,119,106,120,106,121,106,122,106,123,106,124,106,125,106,126,107,33,107,34,107,35,107,36,107,37,107,38,107,39,107,40,107,41,107,42,107,43,107,44,107,45,107,46,107,47,107,48,107,49,107,50,107,51,107,52,107,53,107,54,107,55,107,56,107,57,107,58,107,59,107,60,107,61,107,62,107,63,107,64,107,65,107,66,107,67,107,68,107,69,107,70,107,71,107,72,107,73,107,74,107,75,107,76,107,77,107,78,107,79,107,80,107,81,107,82,107,83,107,84,107,85,107,86,107,87,107,88,107,89,107,90,107,91,107,92,107,93,107,94,107,95,107,96,107,97,107,98,107,99,107,100,107,101,107,102,107,103,107,104,107,105,107,106,107,107,107,108,107,109,107,110,107,111,107,112,107,113,107,114,107,115,107,116,107,117,107,118,107,119,107,120,107,121,107,122,107,123,107,124,107,125,107,126,108,33,108,34,108,35,108,36,108,37,108,38,108,39,108,40,108,41,108,42,108,43,108,44,108,45,108,46,108,47,108,48,108,49,108,50,108,51,108,52,108,53,108,54,108,55,108,56,108,57,108,58,108,59,108,60,108,61,108,62,108,63,108,64,108,65,108,66,108,67,108,68,108,69,108,70,108,71,108,72,108,73,108,74,108,75,108,76,108,77,108,78,108,79,108,80,108,81,108,82,108,83,108,84,108,85,108,86,108,87,108,88,108,89,108,90,108,91,108,92,108,93,108,94,108,95,108,96,108,97,108,98,108,99,108,100,108,101,108,102,108,103,108,104,108,105,108,106,108,107,108,108,108,109,108,110,108,111,108,112,108,113,108,114,108,115,108,116,108,117,108,118,108,119,108,120,108,121,108,122,108,123,108,124,108,125,108,126,109,33,109,34,109,35,109,36,109,37,109,38,109,39,109,40,109,41,109,42,109,43,109,44,109,45,109,46,109,47,109,48,109,49,109,50,109,51,109,52,109,53,109,54,109,55,109,56,109,57,109,58,109,59,109,60,109,61,109,62,109,63,109,64,109,65,109,66,109,67,109,68,109,69,109,70,109,71,109,72,109,73,109,74,109,75,109,76,109,77,109,78,109,79,109,80,109,81,109,82,109,83,109,84,109,85,109,86,109,87,109,88,109,89,109,90,109,91,109,92,109,93,109,94,109,95,109,96,109,97,109,98,109,99,109,100,109,101,109,102,109,103,109,104,109,105,109,106,109,107,109,108,109,109,109,110,109,111,109,112,109,113,109,114,109,115,109,116,109,117,109,118,109,119,109,120,109,121,109,122,109,123,109,124,109,125,109,126,110,33,110,34,110,35,110,36,110,37,110,38,110,39,110,40,110,41,110,42,110,43,110,44,110,45,110,46,110,47,110,48,110,49,110,50,110,51,110,52,110,53,110,54,110,55,110,56,110,57,110,58,110,59,110,60,110,61,110,62,110,63,110,64,110,65,110,66,110,67,110,68,110,69,110,70,110,71,110,72,110,73,110,74,110,75,110,76,110,77,110,78,110,79,110,80,110,81,110,82,110,83,110,84,110,85,110,86,110,87,110,88,110,89,110,90,110,91,110,92,110,93,110,94,110,95,110,96,110,97,110,98,110,99,110,100,110,101,110,102,110,103,110,104,110,105,110,106,110,107,110,108,110,109,110,110,110,111,110,112,110,113,110,114,110,115,110,116,110,117,110,118,110,119,110,120,110,121,110,122,110,123,110,124,110,125,110,126,111,33,111,34,111,35,111,36,111,37,111,38,111,39,111,40,111,41,111,42,111,43,111,44,111,45,111,46,111,47,111,48,111,49,111,50,111,51,111,52,111,53,111,54,111,55,111,56,111,57,111,58,111,59,111,60,111,61,111,62,111,63,111,64,111,65,111,66,111,67,111,68,111,69,111,70,111,71,111,72,111,73,111,74,111,75,111,76,111,77,111,78,111,79,111,80,111,81,111,82,111,83,111,84,111,85,111,86,111,87,111,88,111,89,111,90,111,91,111,92,111,93,111,94,111,95,111,96,111,97,111,98,111,99,111,100,111,101,111,102,111,103,111,104,111,105,111,106,111,107,111,108,111,109,111,110,111,111,111,112,111,113,111,114,111,115,111,116,111,117,111,118,111,119,111,120,111,121,111,122,111,123,111,124,111,125,111,126,112,33,112,34,112,35,112,36,112,37,112,38,112,39,112,40,112,41,112,42,112,43,112,44,112,45,112,46,112,47,112,48,112,49,112,50,112,51,112,52,112,53,112,54,112,55,112,56,112,57,112,58,112,59,112,60,112,61,112,62,112,63,112,64,112,65,112,66,112,67,112,68,112,69,112,70,112,71,112,72,112,73,112,74,112,75,112,76,112,77,112,78,112,79,112,80,112,81,112,82,112,83,112,84,112,85,112,86,112,87,112,88,112,89,112,90,112,91,112,92,112,93,112,94,112,95,112,96,112,97,112,98,112,99,112,100,112,101,112,102,112,103,112,104,112,105,112,106,112,107,112,108,112,109,112,110,112,111,112,112,112,113,112,114,112,115,112,116,112,117,112,118,112,119,112,120,112,121,112,122,112,123,112,124,112,125,112,126,113,33,113,34,113,35,113,36,113,37,113,38,113,39,113,40,113,41,113,42,113,43,113,44,113,45,113,46,113,47,113,48,113,49,113,50,113,51,113,52,113,53,113,54,113,55,113,56,113,57,113,58,113,59,113,60,113,61,113,62,113,63,113,64,113,65,113,66,113,67,113,68,113,69,113,70,113,71,113,72,113,73,113,74,113,75,113,76,113,77,113,78,113,79,113,80,113,81,113,82,113,83,113,84,113,85,113,86,113,87,113,88,113,89,113,90,113,91,113,92,113,93,113,94,113,95,113,96,113,97,113,98,113,99,113,100,113,101,113,102,113,103,113,104,113,105,113,106,113,107,113,108,113,109,113,110,113,111,113,112,113,113,113,114,113,115,113,116,113,117,113,118,113,119,113,120,113,121,113,122,113,123,113,124,113,125,113,126,114,33,114,34,114,35,114,36,114,37,114,38,114,39,114,40,114,41,114,42,114,43,114,44,114,45,114,46,114,47,114,48,114,49,114,50,114,51,114,52,114,53,114,54,114,55,114,56,114,57,114,58,114,59,114,60,114,61,114,62,114,63,114,64,114,65,114,66,114,67,114,68,114,69,114,70,114,71,114,72,114,73,114,74,114,75,114,76,114,77,114,78,114,79,114,80,114,81,114,82,114,83,114,84,114,85,114,86,114,87,114,88,114,89,114,90,114,91,114,92,114,93,114,94,114,95,114,96,114,97,114,98,114,99,114,100,114,101,114,102,114,103,114,104,114,105,114,106,114,107,114,108,114,109,114,110,114,111,114,112,114,113,114,114,114,115,114,116,114,117,114,118,114,119,114,120,114,121,114,122,114,123,114,124,114,125,114,126,115,33,115,34,115,35,115,36,115,37,115,38,115,39,115,40,115,41,115,42,115,43,115,44,115,45,115,46,115,47,115,48,115,49,115,50,115,51,115,52,115,53,115,54,115,55,115,56,115,57,115,58,115,59,115,60,115,61,115,62,115,63,115,64,115,65,115,66,115,67,115,68,115,69,115,70,115,71,115,72,115,73,115,74,115,75,115,76,115,77,115,78,115,79,115,80,115,81,115,82,115,83,115,84,115,85,115,86,115,87,115,88,115,89,115,90,115,91,115,92,115,93,115,94,115,95,115,96,115,97,115,98,115,99,115,100,115,101,115,102,115,103,115,104,115,105,115,106,115,107,115,108,115,109,115,110,115,111,115,112,115,113,115,114,115,115,115,116,115,117,115,118,115,119,115,120,115,121,115,122,115,123,115,124,115,125,115,126,116,33,116,34,116,35,116,36,116,37,116,38,116,39,116,40,116,41,116,42,116,43,116,44,116,45,116,46,116,47,116,48,116,49,116,50,116,51,116,52,116,53,116,54,116,55,116,56,116,57,116,58,116,59,116,60,116,61,116,62,116,63,116,64,116,65,116,66,116,67,116,68,116,69,116,70,116,71,116,72,116,73,116,74,116,75,116,76,116,77,116,78,116,79,116,80,116,81,116,82,116,83,116,84,116,85,116,86,116,87,116,88,116,89,116,90,116,91,116,92,116,93,116,94,116,95,116,96,116,97,116,98,116,99,116,100,116,101,116,102,116,103,116,104,116,105,116,106,116,107,116,108,116,109,116,110,116,111,116,112,116,113,116,114,116,115,116,116,116,117,116,118,116,119,116,120,116,121,116,122,116,123,116,124,116,125,116,126,117,33,117,34,117,35,117,36,117,37,117,38,117,39,117,40,117,41,117,42,117,43,117,44,117,45,117,46,117,47,117,48,117,49,117,50,117,51,117,52,117,53,117,54,117,55,117,56,117,57,117,58,117,59,117,60,117,61,117,62,117,63,117,64,117,65,117,66,117,67,117,68,117,69,117,70,117,71,117,72,117,73,117,74,117,75,117,76,117,77,117,78,117,79,117,80,117,81,117,82,117,83,117,84,117,85,117,86,117,87,117,88,117,89,117,90,117,91,117,92,117,93,117,94,117,95,117,96,117,97,117,98,117,99,117,100,117,101,117,102,117,103,117,104,117,105,117,106,117,107,117,108,117,109,117,110,117,111,117,112,117,113,117,114,117,115,117,116,117,117,117,118,117,119,117,120,117,121,117,122,117,123,117,124,117,125,117,126,118,33,118,34,118,35,118,36,118,37,118,38,118,39,118,40,118,41,118,42,118,43,118,44,118,45,118,46,118,47,118,48,118,49,118,50,118,51,118,52,118,53,118,54,118,55,118,56,118,57,118,58,118,59,118,60,118,61,118,62,118,63,118,64,118,65,118,66,118,67,118,68,118,69,118,70,118,71,118,72,118,73,118,74,118,75,118,76,118,77,118,78,118,79,118,80,118,81,118,82,118,83,118,84,118,85,118,86,118,87,118,88,118,89,118,90,118,91,118,92,118,93,118,94,118,95,118,96,118,97,118,98,118,99,118,100,118,101,118,102,118,103,118,104,118,105,118,106,118,107,118,108,118,109,118,110,118,111,118,112,118,113,118,114,118,115,118,116,118,117,118,118,118,119,118,120,118,121,118,122,118,123,118,124,118,125,118,126,119,33,119,34,119,35,119,36,119,37,119,38,119,39,119,40,119,41,119,42,119,43,119,44,119,45,119,46,119,47,119,48,119,49,119,50,119,51,119,52,119,53,119,54,119,55,119,56,119,57,119,58,119,59,119,60,119,61,119,62,119,63,119,64,119,65,119,66,119,67,119,68,119,69,119,70,119,71,119,72,119,73,119,74,119,75,119,76,119,77,119,78,119,79,119,80,119,81,119,82,119,83,119,84,119,85,119,86,119,87,119,88,119,89,119,90,119,91,119,92,119,93,119,94,119,95,119,96,119,97,119,98,119,99,119,100,119,101,119,102,119,103,119,104,119,105,119,106,119,107,119,108,119,109,119,110,119,111,119,112,119,113,119,114,119,115,119,116,119,117,119,118,119,119,119,120,119,121,119,122,119,123,119,124,119,125,119,126,120,33,120,34,120,35,120,36,120,37,120,38,120,39,120,40,120,41,120,42,120,43,120,44,120,45,120,46,120,47,120,48,120,49,120,50,120,51,120,52,120,53,120,54,120,55,120,56,120,57,120,58,120,59,120,60,120,61,120,62,120,63,120,64,120,65,120,66,120,67,120,68,120,69,120,70,120,71,120,72,120,73,120,74,120,75,120,76,120,77,120,78,120,79,120,80,120,81,120,82,120,83,120,84,120,85,120,86,120,87,120,88,120,89,120,90,120,91,120,92,120,93,120,94,120,95,120,96,120,97,120,98,120,99,120,100,120,101,120,102,120,103,120,104,120,105,120,106,120,107,120,108,120,109,120,110,120,111,120,112,120,113,120,114,120,115,120,116,120,117,120,118,120,119,120,120,120,121,120,122,120,123,120,124,120,125,120,126,121,33,121,34,121,35,121,36,121,37,121,38,121,39,121,40,121,41,121,42,121,43,121,44,121,45,121,46,121,47,121,48,121,49,121,50,121,51,121,52,121,53,121,54,121,55,121,56,121,57,121,58,121,59,121,60,121,61,121,62,121,63,121,64,121,65,121,66,121,67,121,68,121,69,121,70,121,71,121,72,121,73,121,74,121,75,121,76,121,77,121,78,121,79,121,80,121,81,121,82,121,83,121,84,121,85,121,86,121,87,121,88,121,89,121,90,121,91,121,92,121,93,121,94,121,95,121,96,121,97,121,98,121,99,121,100,121,101,121,102,121,103,121,104,121,105,121,106,121,107,121,108,121,109,121,110,121,111,121,112,121,113,121,114,121,115,121,116,121,117,121,118,121,119,121,120,121,121,121,122,121,123,121,124,121,125,121,126,122,33,122,34,122,35,122,36,122,37,122,38,122,39,122,40,122,41,122,42,122,43,122,44,122,45,122,46,122,47,122,48,122,49,122,50,122,51,122,52,122,53,122,54,122,55,122,56,122,57,122,58,122,59,122,60,122,61,122,62,122,63,122,64,122,65,122,66,122,67,122,68,122,69,122,70,122,71,122,72,122,73,122,74,122,75,122,76,122,77,122,78,122,79,122,80,122,81,122,82,122,83,122,84,122,85,122,86,122,87,122,88,122,89,122,90,122,91,122,92,122,93,122,94,122,95,122,96,122,97,122,98,122,99,122,100,122,101,122,102,122,103,122,104,122,105,122,106,122,107,122,108,122,109,122,110,122,111,122,112,122,113,122,114,122,115,122,116,122,117,122,118,122,119,122,120,122,121,122,122,122,123,122,124,122,125,122,126,123,33,123,34,123,35,123,36,123,37,123,38,123,39,123,40,123,41,123,42,123,43,123,44,123,45,123,46,123,47,123,48,123,49,123,50,123,51,123,52,123,53,123,54,123,55,123,56,123,57,123,58,123,59,123,60,123,61,123,62,123,63,123,64,123,65,123,66,123,67,123,68,123,69,123,70,123,71,123,72,123,73,123,74,123,75,123,76,123,77,123,78,123,79,123,80,123,81,123,82,123,83,123,84,123,85,123,86,123,87,123,88,123,89,123,90,123,91,123,92,123,93,123,94,123,95,123,96,123,97,123,98,123,99,123,100,123,101,123,102,123,103,123,104,123,105,123,106,123,107,123,108,123,109,123,110,123,111,123,112,123,113,123,114,123,115,123,116,123,117,123,118,123,119,123,120,123,121,123,122,123,123,123,124,123,125,123,126,124,33,124,34,124,35,124,36,124,37,124,38,124,39,124,40,124,41,124,42,124,43,124,44,124,45,124,46,124,47,124,48,124,49,124,50,124,51,124,52,124,53,124,54,124,55,124,56,124,57,124,58,124,59,124,60,124,61,124,62,124,63,124,64,124,65,124,66,124,67,124,68,124,69,124,70,124,71,124,72,124,73,124,74,124,75,124,76,124,77,124,78,124,79,124,80,124,81,124,82,124,83,124,84,124,85,124,86,124,87,124,88,124,89,124,90,124,91,124,92,124,93,124,94,124,95,124,96,124,97,124,98,124,99,124,100,124,101,124,102,124,103,124,104,124,105,124,106,124,107,124,108,124,109,124,110,124,111,124,112,124,113,124,114,124,115,124,116,124,117,124,118,124,119,124,120,124,121,124,122,124,123,124,124,124,125,124,126,125,33,125,34,125,35,125,36,125,37,125,38,125,39,125,40,125,41,125,42,125,43,125,44,125,45,125,46,125,47,125,48,125,49,125,50,125,51,125,52,125,53,125,54,125,55,125,56,125,57,125,58,125,59,125,60,125,61,125,62,125,63,125,64,125,65,125,66,125,67,125,68,125,69,125,70,125,71,125,72,125,73,125,74,125,75,125,76,125,77,125,78,125,79,125,80,125,81,125,82,125,83,125,84,125,85,125,86,125,87,125,88,125,89,125,90,125,91,125,92,125,93,125,94,125,95,125,96,125,97,125,98,125,99,125,100,125,101,125,102,125,103,125,104,125,105,125,106,125,107,125,108,125,109,125,110,125,111,125,112,125,113,125,114,125,115,125,116,125,117,125,118,125,119,125,120,125,121,125,122,125,123,125,124,125,125,125,126];
-    var string = "\u3000\u3001\u3002\u00B7\u2025\u2026\u00A8\u3003\u00AD\u2015\u2225\uFF3C\u223C\u2018\u2019\u201C\u201D\u3014\u3015\u3008\u3009\u300A\u300B\u300C\u300D\u300E\u300F\u3010\u3011\u00B1\u00D7\u00F7\u2260\u2264\u2265\u221E\u2234\u00B0\u2032\u2033\u2103\u212B\uFFE0\uFFE1\uFFE5\u2642\u2640\u2220\u22A5\u2312\u2202\u2207\u2261\u2252\u00A7\u203B\u2606\u2605\u25CB\u25CF\u25CE\u25C7\u25C6\u25A1\u25A0\u25B3\u25B2\u25BD\u25BC\u2192\u2190\u2191\u2193\u2194\u3013\u226A\u226B\u221A\u223D\u221D\u2235\u222B\u222C\u2208\u220B\u2286\u2287\u2282\u2283\u222A\u2229\u2227\u2228\uFFE2\u21D2\u21D4\u2200\u2203\u00B4\uFF5E\u02C7\u02D8\u02DD\u02DA\u02D9\u00B8\u02DB\u00A1\u00BF\u02D0\u222E\u2211\u220F\u00A4\u2109\u2030\u25C1\u25C0\u25B7\u25B6\u2664\u2660\u2661\u2665\u2667\u2663\u2299\u25C8\u25A3\u25D0\u25D1\u2592\u25A4\u25A5\u25A8\u25A7\u25A6\u25A9\u2668\u260F\u260E\u261C\u261E\u00B6\u2020\u2021\u2195\u2197\u2199\u2196\u2198\u266D\u2669\u266A\u266C\u327F\u321C\u2116\u33C7\u2122\u33C2\u33D8\u2121\u20AC\u00AE\uFF01\uFF02\uFF03\uFF04\uFF05\uFF06\uFF07\uFF08\uFF09\uFF0A\uFF0B\uFF0C\uFF0D\uFF0E\uFF0F\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF1A\uFF1B\uFF1C\uFF1D\uFF1E\uFF1F\uFF20\uFF21\uFF22\uFF23\uFF24\uFF25\uFF26\uFF27\uFF28\uFF29\uFF2A\uFF2B\uFF2C\uFF2D\uFF2E\uFF2F\uFF30\uFF31\uFF32\uFF33\uFF34\uFF35\uFF36\uFF37\uFF38\uFF39\uFF3A\uFF3B\uFFE6\uFF3D\uFF3E\uFF3F\uFF40\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48\uFF49\uFF4A\uFF4B\uFF4C\uFF4D\uFF4E\uFF4F\uFF50\uFF51\uFF52\uFF53\uFF54\uFF55\uFF56\uFF57\uFF58\uFF59\uFF5A\uFF5B\uFF5C\uFF5D\uFFE3\u3131\u3132\u3133\u3134\u3135\u3136\u3137\u3138\u3139\u313A\u313B\u313C\u313D\u313E\u313F\u3140\u3141\u3142\u3143\u3144\u3145\u3146\u3147\u3148\u3149\u314A\u314B\u314C\u314D\u314E\u314F\u3150\u3151\u3152\u3153\u3154\u3155\u3156\u3157\u3158\u3159\u315A\u315B\u315C\u315D\u315E\u315F\u3160\u3161\u3162\u3163\u3164\u3165\u3166\u3167\u3168\u3169\u316A\u316B\u316C\u316D\u316E\u316F\u3170\u3171\u3172\u3173\u3174\u3175\u3176\u3177\u3178\u3179\u317A\u317B\u317C\u317D\u317E\u317F\u3180\u3181\u3182\u3183\u3184\u3185\u3186\u3187\u3188\u3189\u318A\u318B\u318C\u318D\u318E\u2170\u2171\u2172\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u2160\u2161\u2162\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C3\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\u2500\u2502\u250C\u2510\u2518\u2514\u251C\u252C\u2524\u2534\u253C\u2501\u2503\u250F\u2513\u251B\u2517\u2523\u2533\u252B\u253B\u254B\u2520\u252F\u2528\u2537\u253F\u251D\u2530\u2525\u2538\u2542\u2512\u2511\u251A\u2519\u2516\u2515\u250E\u250D\u251E\u251F\u2521\u2522\u2526\u2527\u2529\u252A\u252D\u252E\u2531\u2532\u2535\u2536\u2539\u253A\u253D\u253E\u2540\u2541\u2543\u2544\u2545\u2546\u2547\u2548\u2549\u254A\u3395\u3396\u3397\u2113\u3398\u33C4\u33A3\u33A4\u33A5\u33A6\u3399\u339A\u339B\u339C\u339D\u339E\u339F\u33A0\u33A1\u33A2\u33CA\u338D\u338E\u338F\u33CF\u3388\u3389\u33C8\u33A7\u33A8\u33B0\u33B1\u33B2\u33B3\u33B4\u33B5\u33B6\u33B7\u33B8\u33B9\u3380\u3381\u3382\u3383\u3384\u33BA\u33BB\u33BC\u33BD\u33BE\u33BF\u3390\u3391\u3392\u3393\u3394\u2126\u33C0\u33C1\u338A\u338B\u338C\u33D6\u33C5\u33AD\u33AE\u33AF\u33DB\u33A9\u33AA\u33AB\u33AC\u33DD\u33D0\u33D3\u33C3\u33C9\u33DC\u33C6\u00C6\u00D0\u00AA\u0126\u0132\u013F\u0141\u00D8\u0152\u00BA\u00DE\u0166\u014A\u3260\u3261\u3262\u3263\u3264\u3265\u3266\u3267\u3268\u3269\u326A\u326B\u326C\u326D\u326E\u326F\u3270\u3271\u3272\u3273\u3274\u3275\u3276\u3277\u3278\u3279\u327A\u327B\u24D0\u24D1\u24D2\u24D3\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9\u24DA\u24DB\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1\u24E2\u24E3\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2469\u246A\u246B\u246C\u246D\u246E\u00BD\u2153\u2154\u00BC\u00BE\u215B\u215C\u215D\u215E\u00E6\u0111\u00F0\u0127\u0131\u0133\u0138\u0140\u0142\u00F8\u0153\u00DF\u00FE\u0167\u014B\u0149\u3200\u3201\u3202\u3203\u3204\u3205\u3206\u3207\u3208\u3209\u320A\u320B\u320C\u320D\u320E\u320F\u3210\u3211\u3212\u3213\u3214\u3215\u3216\u3217\u3218\u3219\u321A\u321B\u249C\u249D\u249E\u249F\u24A0\u24A1\u24A2\u24A3\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9\u24AA\u24AB\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1\u24B2\u24B3\u24B4\u24B5\u2474\u2475\u2476\u2477\u2478\u2479\u247A\u247B\u247C\u247D\u247E\u247F\u2480\u2481\u2482\u00B9\u00B2\u00B3\u2074\u207F\u2081\u2082\u2083\u2084\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304A\u304B\u304C\u304D\u304E\u304F\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305A\u305B\u305C\u305D\u305E\u305F\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306A\u306B\u306C\u306D\u306E\u306F\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307A\u307B\u307C\u307D\u307E\u307F\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308A\u308B\u308C\u308D\u308E\u308F\u3090\u3091\u3092\u3093\u30A1\u30A2\u30A3\u30A4\u30A5\u30A6\u30A7\u30A8\u30A9\u30AA\u30AB\u30AC\u30AD\u30AE\u30AF\u30B0\u30B1\u30B2\u30B3\u30B4\u30B5\u30B6\u30B7\u30B8\u30B9\u30BA\u30BB\u30BC\u30BD\u30BE\u30BF\u30C0\u30C1\u30C2\u30C3\u30C4\u30C5\u30C6\u30C7\u30C8\u30C9\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D0\u30D1\u30D2\u30D3\u30D4\u30D5\u30D6\u30D7\u30D8\u30D9\u30DA\u30DB\u30DC\u30DD\u30DE\u30DF\u30E0\u30E1\u30E2\u30E3\u30E4\u30E5\u30E6\u30E7\u30E8\u30E9\u30EA\u30EB\u30EC\u30ED\u30EE\u30EF\u30F0\u30F1\u30F2\u30F3\u30F4\u30F5\u30F6\u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\uAC00\uAC01\uAC04\uAC07\uAC08\uAC09\uAC0A\uAC10\uAC11\uAC12\uAC13\uAC14\uAC15\uAC16\uAC17\uAC19\uAC1A\uAC1B\uAC1C\uAC1D\uAC20\uAC24\uAC2C\uAC2D\uAC2F\uAC30\uAC31\uAC38\uAC39\uAC3C\uAC40\uAC4B\uAC4D\uAC54\uAC58\uAC5C\uAC70\uAC71\uAC74\uAC77\uAC78\uAC7A\uAC80\uAC81\uAC83\uAC84\uAC85\uAC86\uAC89\uAC8A\uAC8B\uAC8C\uAC90\uAC94\uAC9C\uAC9D\uAC9F\uACA0\uACA1\uACA8\uACA9\uACAA\uACAC\uACAF\uACB0\uACB8\uACB9\uACBB\uACBC\uACBD\uACC1\uACC4\uACC8\uACCC\uACD5\uACD7\uACE0\uACE1\uACE4\uACE7\uACE8\uACEA\uACEC\uACEF\uACF0\uACF1\uACF3\uACF5\uACF6\uACFC\uACFD\uAD00\uAD04\uAD06\uAD0C\uAD0D\uAD0F\uAD11\uAD18\uAD1C\uAD20\uAD29\uAD2C\uAD2D\uAD34\uAD35\uAD38\uAD3C\uAD44\uAD45\uAD47\uAD49\uAD50\uAD54\uAD58\uAD61\uAD63\uAD6C\uAD6D\uAD70\uAD73\uAD74\uAD75\uAD76\uAD7B\uAD7C\uAD7D\uAD7F\uAD81\uAD82\uAD88\uAD89\uAD8C\uAD90\uAD9C\uAD9D\uADA4\uADB7\uADC0\uADC1\uADC4\uADC8\uADD0\uADD1\uADD3\uADDC\uADE0\uADE4\uADF8\uADF9\uADFC\uADFF\uAE00\uAE01\uAE08\uAE09\uAE0B\uAE0D\uAE14\uAE30\uAE31\uAE34\uAE37\uAE38\uAE3A\uAE40\uAE41\uAE43\uAE45\uAE46\uAE4A\uAE4C\uAE4D\uAE4E\uAE50\uAE54\uAE56\uAE5C\uAE5D\uAE5F\uAE60\uAE61\uAE65\uAE68\uAE69\uAE6C\uAE70\uAE78\uAE79\uAE7B\uAE7C\uAE7D\uAE84\uAE85\uAE8C\uAEBC\uAEBD\uAEBE\uAEC0\uAEC4\uAECC\uAECD\uAECF\uAED0\uAED1\uAED8\uAED9\uAEDC\uAEE8\uAEEB\uAEED\uAEF4\uAEF8\uAEFC\uAF07\uAF08\uAF0D\uAF10\uAF2C\uAF2D\uAF30\uAF32\uAF34\uAF3C\uAF3D\uAF3F\uAF41\uAF42\uAF43\uAF48\uAF49\uAF50\uAF5C\uAF5D\uAF64\uAF65\uAF79\uAF80\uAF84\uAF88\uAF90\uAF91\uAF95\uAF9C\uAFB8\uAFB9\uAFBC\uAFC0\uAFC7\uAFC8\uAFC9\uAFCB\uAFCD\uAFCE\uAFD4\uAFDC\uAFE8\uAFE9\uAFF0\uAFF1\uAFF4\uAFF8\uB000\uB001\uB004\uB00C\uB010\uB014\uB01C\uB01D\uB028\uB044\uB045\uB048\uB04A\uB04C\uB04E\uB053\uB054\uB055\uB057\uB059\uB05D\uB07C\uB07D\uB080\uB084\uB08C\uB08D\uB08F\uB091\uB098\uB099\uB09A\uB09C\uB09F\uB0A0\uB0A1\uB0A2\uB0A8\uB0A9\uB0AB\uB0AC\uB0AD\uB0AE\uB0AF\uB0B1\uB0B3\uB0B4\uB0B5\uB0B8\uB0BC\uB0C4\uB0C5\uB0C7\uB0C8\uB0C9\uB0D0\uB0D1\uB0D4\uB0D8\uB0E0\uB0E5\uB108\uB109\uB10B\uB10C\uB110\uB112\uB113\uB118\uB119\uB11B\uB11C\uB11D\uB123\uB124\uB125\uB128\uB12C\uB134\uB135\uB137\uB138\uB139\uB140\uB141\uB144\uB148\uB150\uB151\uB154\uB155\uB158\uB15C\uB160\uB178\uB179\uB17C\uB180\uB182\uB188\uB189\uB18B\uB18D\uB192\uB193\uB194\uB198\uB19C\uB1A8\uB1CC\uB1D0\uB1D4\uB1DC\uB1DD\uB1DF\uB1E8\uB1E9\uB1EC\uB1F0\uB1F9\uB1FB\uB1FD\uB204\uB205\uB208\uB20B\uB20C\uB214\uB215\uB217\uB219\uB220\uB234\uB23C\uB258\uB25C\uB260\uB268\uB269\uB274\uB275\uB27C\uB284\uB285\uB289\uB290\uB291\uB294\uB298\uB299\uB29A\uB2A0\uB2A1\uB2A3\uB2A5\uB2A6\uB2AA\uB2AC\uB2B0\uB2B4\uB2C8\uB2C9\uB2CC\uB2D0\uB2D2\uB2D8\uB2D9\uB2DB\uB2DD\uB2E2\uB2E4\uB2E5\uB2E6\uB2E8\uB2EB\uB2EC\uB2ED\uB2EE\uB2EF\uB2F3\uB2F4\uB2F5\uB2F7\uB2F8\uB2F9\uB2FA\uB2FB\uB2FF\uB300\uB301\uB304\uB308\uB310\uB311\uB313\uB314\uB315\uB31C\uB354\uB355\uB356\uB358\uB35B\uB35C\uB35E\uB35F\uB364\uB365\uB367\uB369\uB36B\uB36E\uB370\uB371\uB374\uB378\uB380\uB381\uB383\uB384\uB385\uB38C\uB390\uB394\uB3A0\uB3A1\uB3A8\uB3AC\uB3C4\uB3C5\uB3C8\uB3CB\uB3CC\uB3CE\uB3D0\uB3D4\uB3D5\uB3D7\uB3D9\uB3DB\uB3DD\uB3E0\uB3E4\uB3E8\uB3FC\uB410\uB418\uB41C\uB420\uB428\uB429\uB42B\uB434\uB450\uB451\uB454\uB458\uB460\uB461\uB463\uB465\uB46C\uB480\uB488\uB49D\uB4A4\uB4A8\uB4AC\uB4B5\uB4B7\uB4B9\uB4C0\uB4C4\uB4C8\uB4D0\uB4D5\uB4DC\uB4DD\uB4E0\uB4E3\uB4E4\uB4E6\uB4EC\uB4ED\uB4EF\uB4F1\uB4F8\uB514\uB515\uB518\uB51B\uB51C\uB524\uB525\uB527\uB528\uB529\uB52A\uB530\uB531\uB534\uB538\uB540\uB541\uB543\uB544\uB545\uB54B\uB54C\uB54D\uB550\uB554\uB55C\uB55D\uB55F\uB560\uB561\uB5A0\uB5A1\uB5A4\uB5A8\uB5AA\uB5AB\uB5B0\uB5B1\uB5B3\uB5B4\uB5B5\uB5BB\uB5BC\uB5BD\uB5C0\uB5C4\uB5CC\uB5CD\uB5CF\uB5D0\uB5D1\uB5D8\uB5EC\uB610\uB611\uB614\uB618\uB625\uB62C\uB634\uB648\uB664\uB668\uB69C\uB69D\uB6A0\uB6A4\uB6AB\uB6AC\uB6B1\uB6D4\uB6F0\uB6F4\uB6F8\uB700\uB701\uB705\uB728\uB729\uB72C\uB72F\uB730\uB738\uB739\uB73B\uB744\uB748\uB74C\uB754\uB755\uB760\uB764\uB768\uB770\uB771\uB773\uB775\uB77C\uB77D\uB780\uB784\uB78C\uB78D\uB78F\uB790\uB791\uB792\uB796\uB797\uB798\uB799\uB79C\uB7A0\uB7A8\uB7A9\uB7AB\uB7AC\uB7AD\uB7B4\uB7B5\uB7B8\uB7C7\uB7C9\uB7EC\uB7ED\uB7F0\uB7F4\uB7FC\uB7FD\uB7FF\uB800\uB801\uB807\uB808\uB809\uB80C\uB810\uB818\uB819\uB81B\uB81D\uB824\uB825\uB828\uB82C\uB834\uB835\uB837\uB838\uB839\uB840\uB844\uB851\uB853\uB85C\uB85D\uB860\uB864\uB86C\uB86D\uB86F\uB871\uB878\uB87C\uB88D\uB8A8\uB8B0\uB8B4\uB8B8\uB8C0\uB8C1\uB8C3\uB8C5\uB8CC\uB8D0\uB8D4\uB8DD\uB8DF\uB8E1\uB8E8\uB8E9\uB8EC\uB8F0\uB8F8\uB8F9\uB8FB\uB8FD\uB904\uB918\uB920\uB93C\uB93D\uB940\uB944\uB94C\uB94F\uB951\uB958\uB959\uB95C\uB960\uB968\uB969\uB96B\uB96D\uB974\uB975\uB978\uB97C\uB984\uB985\uB987\uB989\uB98A\uB98D\uB98E\uB9AC\uB9AD\uB9B0\uB9B4\uB9BC\uB9BD\uB9BF\uB9C1\uB9C8\uB9C9\uB9CC\uB9CE\uB9CF\uB9D0\uB9D1\uB9D2\uB9D8\uB9D9\uB9DB\uB9DD\uB9DE\uB9E1\uB9E3\uB9E4\uB9E5\uB9E8\uB9EC\uB9F4\uB9F5\uB9F7\uB9F8\uB9F9\uB9FA\uBA00\uBA01\uBA08\uBA15\uBA38\uBA39\uBA3C\uBA40\uBA42\uBA48\uBA49\uBA4B\uBA4D\uBA4E\uBA53\uBA54\uBA55\uBA58\uBA5C\uBA64\uBA65\uBA67\uBA68\uBA69\uBA70\uBA71\uBA74\uBA78\uBA83\uBA84\uBA85\uBA87\uBA8C\uBAA8\uBAA9\uBAAB\uBAAC\uBAB0\uBAB2\uBAB8\uBAB9\uBABB\uBABD\uBAC4\uBAC8\uBAD8\uBAD9\uBAFC\uBB00\uBB04\uBB0D\uBB0F\uBB11\uBB18\uBB1C\uBB20\uBB29\uBB2B\uBB34\uBB35\uBB36\uBB38\uBB3B\uBB3C\uBB3D\uBB3E\uBB44\uBB45\uBB47\uBB49\uBB4D\uBB4F\uBB50\uBB54\uBB58\uBB61\uBB63\uBB6C\uBB88\uBB8C\uBB90\uBBA4\uBBA8\uBBAC\uBBB4\uBBB7\uBBC0\uBBC4\uBBC8\uBBD0\uBBD3\uBBF8\uBBF9\uBBFC\uBBFF\uBC00\uBC02\uBC08\uBC09\uBC0B\uBC0C\uBC0D\uBC0F\uBC11\uBC14\uBC15\uBC16\uBC17\uBC18\uBC1B\uBC1C\uBC1D\uBC1E\uBC1F\uBC24\uBC25\uBC27\uBC29\uBC2D\uBC30\uBC31\uBC34\uBC38\uBC40\uBC41\uBC43\uBC44\uBC45\uBC49\uBC4C\uBC4D\uBC50\uBC5D\uBC84\uBC85\uBC88\uBC8B\uBC8C\uBC8E\uBC94\uBC95\uBC97\uBC99\uBC9A\uBCA0\uBCA1\uBCA4\uBCA7\uBCA8\uBCB0\uBCB1\uBCB3\uBCB4\uBCB5\uBCBC\uBCBD\uBCC0\uBCC4\uBCCD\uBCCF\uBCD0\uBCD1\uBCD5\uBCD8\uBCDC\uBCF4\uBCF5\uBCF6\uBCF8\uBCFC\uBD04\uBD05\uBD07\uBD09\uBD10\uBD14\uBD24\uBD2C\uBD40\uBD48\uBD49\uBD4C\uBD50\uBD58\uBD59\uBD64\uBD68\uBD80\uBD81\uBD84\uBD87\uBD88\uBD89\uBD8A\uBD90\uBD91\uBD93\uBD95\uBD99\uBD9A\uBD9C\uBDA4\uBDB0\uBDB8\uBDD4\uBDD5\uBDD8\uBDDC\uBDE9\uBDF0\uBDF4\uBDF8\uBE00\uBE03\uBE05\uBE0C\uBE0D\uBE10\uBE14\uBE1C\uBE1D\uBE1F\uBE44\uBE45\uBE48\uBE4C\uBE4E\uBE54\uBE55\uBE57\uBE59\uBE5A\uBE5B\uBE60\uBE61\uBE64\uBE68\uBE6A\uBE70\uBE71\uBE73\uBE74\uBE75\uBE7B\uBE7C\uBE7D\uBE80\uBE84\uBE8C\uBE8D\uBE8F\uBE90\uBE91\uBE98\uBE99\uBEA8\uBED0\uBED1\uBED4\uBED7\uBED8\uBEE0\uBEE3\uBEE4\uBEE5\uBEEC\uBF01\uBF08\uBF09\uBF18\uBF19\uBF1B\uBF1C\uBF1D\uBF40\uBF41\uBF44\uBF48\uBF50\uBF51\uBF55\uBF94\uBFB0\uBFC5\uBFCC\uBFCD\uBFD0\uBFD4\uBFDC\uBFDF\uBFE1\uC03C\uC051\uC058\uC05C\uC060\uC068\uC069\uC090\uC091\uC094\uC098\uC0A0\uC0A1\uC0A3\uC0A5\uC0AC\uC0AD\uC0AF\uC0B0\uC0B3\uC0B4\uC0B5\uC0B6\uC0BC\uC0BD\uC0BF\uC0C0\uC0C1\uC0C5\uC0C8\uC0C9\uC0CC\uC0D0\uC0D8\uC0D9\uC0DB\uC0DC\uC0DD\uC0E4\uC0E5\uC0E8\uC0EC\uC0F4\uC0F5\uC0F7\uC0F9\uC100\uC104\uC108\uC110\uC115\uC11C\uC11D\uC11E\uC11F\uC120\uC123\uC124\uC126\uC127\uC12C\uC12D\uC12F\uC130\uC131\uC136\uC138\uC139\uC13C\uC140\uC148\uC149\uC14B\uC14C\uC14D\uC154\uC155\uC158\uC15C\uC164\uC165\uC167\uC168\uC169\uC170\uC174\uC178\uC185\uC18C\uC18D\uC18E\uC190\uC194\uC196\uC19C\uC19D\uC19F\uC1A1\uC1A5\uC1A8\uC1A9\uC1AC\uC1B0\uC1BD\uC1C4\uC1C8\uC1CC\uC1D4\uC1D7\uC1D8\uC1E0\uC1E4\uC1E8\uC1F0\uC1F1\uC1F3\uC1FC\uC1FD\uC200\uC204\uC20C\uC20D\uC20F\uC211\uC218\uC219\uC21C\uC21F\uC220\uC228\uC229\uC22B\uC22D\uC22F\uC231\uC232\uC234\uC248\uC250\uC251\uC254\uC258\uC260\uC265\uC26C\uC26D\uC270\uC274\uC27C\uC27D\uC27F\uC281\uC288\uC289\uC290\uC298\uC29B\uC29D\uC2A4\uC2A5\uC2A8\uC2AC\uC2AD\uC2B4\uC2B5\uC2B7\uC2B9\uC2DC\uC2DD\uC2E0\uC2E3\uC2E4\uC2EB\uC2EC\uC2ED\uC2EF\uC2F1\uC2F6\uC2F8\uC2F9\uC2FB\uC2FC\uC300\uC308\uC309\uC30C\uC30D\uC313\uC314\uC315\uC318\uC31C\uC324\uC325\uC328\uC329\uC345\uC368\uC369\uC36C\uC370\uC372\uC378\uC379\uC37C\uC37D\uC384\uC388\uC38C\uC3C0\uC3D8\uC3D9\uC3DC\uC3DF\uC3E0\uC3E2\uC3E8\uC3E9\uC3ED\uC3F4\uC3F5\uC3F8\uC408\uC410\uC424\uC42C\uC430\uC434\uC43C\uC43D\uC448\uC464\uC465\uC468\uC46C\uC474\uC475\uC479\uC480\uC494\uC49C\uC4B8\uC4BC\uC4E9\uC4F0\uC4F1\uC4F4\uC4F8\uC4FA\uC4FF\uC500\uC501\uC50C\uC510\uC514\uC51C\uC528\uC529\uC52C\uC530\uC538\uC539\uC53B\uC53D\uC544\uC545\uC548\uC549\uC54A\uC54C\uC54D\uC54E\uC553\uC554\uC555\uC557\uC558\uC559\uC55D\uC55E\uC560\uC561\uC564\uC568\uC570\uC571\uC573\uC574\uC575\uC57C\uC57D\uC580\uC584\uC587\uC58C\uC58D\uC58F\uC591\uC595\uC597\uC598\uC59C\uC5A0\uC5A9\uC5B4\uC5B5\uC5B8\uC5B9\uC5BB\uC5BC\uC5BD\uC5BE\uC5C4\uC5C5\uC5C6\uC5C7\uC5C8\uC5C9\uC5CA\uC5CC\uC5CE\uC5D0\uC5D1\uC5D4\uC5D8\uC5E0\uC5E1\uC5E3\uC5E5\uC5EC\uC5ED\uC5EE\uC5F0\uC5F4\uC5F6\uC5F7\uC5FC\uC5FD\uC5FE\uC5FF\uC600\uC601\uC605\uC606\uC607\uC608\uC60C\uC610\uC618\uC619\uC61B\uC61C\uC624\uC625\uC628\uC62C\uC62D\uC62E\uC630\uC633\uC634\uC635\uC637\uC639\uC63B\uC640\uC641\uC644\uC648\uC650\uC651\uC653\uC654\uC655\uC65C\uC65D\uC660\uC66C\uC66F\uC671\uC678\uC679\uC67C\uC680\uC688\uC689\uC68B\uC68D\uC694\uC695\uC698\uC69C\uC6A4\uC6A5\uC6A7\uC6A9\uC6B0\uC6B1\uC6B4\uC6B8\uC6B9\uC6BA\uC6C0\uC6C1\uC6C3\uC6C5\uC6CC\uC6CD\uC6D0\uC6D4\uC6DC\uC6DD\uC6E0\uC6E1\uC6E8\uC6E9\uC6EC\uC6F0\uC6F8\uC6F9\uC6FD\uC704\uC705\uC708\uC70C\uC714\uC715\uC717\uC719\uC720\uC721\uC724\uC728\uC730\uC731\uC733\uC735\uC737\uC73C\uC73D\uC740\uC744\uC74A\uC74C\uC74D\uC74F\uC751\uC752\uC753\uC754\uC755\uC756\uC757\uC758\uC75C\uC760\uC768\uC76B\uC774\uC775\uC778\uC77C\uC77D\uC77E\uC783\uC784\uC785\uC787\uC788\uC789\uC78A\uC78E\uC790\uC791\uC794\uC796\uC797\uC798\uC79A\uC7A0\uC7A1\uC7A3\uC7A4\uC7A5\uC7A6\uC7AC\uC7AD\uC7B0\uC7B4\uC7BC\uC7BD\uC7BF\uC7C0\uC7C1\uC7C8\uC7C9\uC7CC\uC7CE\uC7D0\uC7D8\uC7DD\uC7E4\uC7E8\uC7EC\uC800\uC801\uC804\uC808\uC80A\uC810\uC811\uC813\uC815\uC816\uC81C\uC81D\uC820\uC824\uC82C\uC82D\uC82F\uC831\uC838\uC83C\uC840\uC848\uC849\uC84C\uC84D\uC854\uC870\uC871\uC874\uC878\uC87A\uC880\uC881\uC883\uC885\uC886\uC887\uC88B\uC88C\uC88D\uC894\uC89D\uC89F\uC8A1\uC8A8\uC8BC\uC8BD\uC8C4\uC8C8\uC8CC\uC8D4\uC8D5\uC8D7\uC8D9\uC8E0\uC8E1\uC8E4\uC8F5\uC8FC\uC8FD\uC900\uC904\uC905\uC906\uC90C\uC90D\uC90F\uC911\uC918\uC92C\uC934\uC950\uC951\uC954\uC958\uC960\uC961\uC963\uC96C\uC970\uC974\uC97C\uC988\uC989\uC98C\uC990\uC998\uC999\uC99B\uC99D\uC9C0\uC9C1\uC9C4\uC9C7\uC9C8\uC9CA\uC9D0\uC9D1\uC9D3\uC9D5\uC9D6\uC9D9\uC9DA\uC9DC\uC9DD\uC9E0\uC9E2\uC9E4\uC9E7\uC9EC\uC9ED\uC9EF\uC9F0\uC9F1\uC9F8\uC9F9\uC9FC\uCA00\uCA08\uCA09\uCA0B\uCA0C\uCA0D\uCA14\uCA18\uCA29\uCA4C\uCA4D\uCA50\uCA54\uCA5C\uCA5D\uCA5F\uCA60\uCA61\uCA68\uCA7D\uCA84\uCA98\uCABC\uCABD\uCAC0\uCAC4\uCACC\uCACD\uCACF\uCAD1\uCAD3\uCAD8\uCAD9\uCAE0\uCAEC\uCAF4\uCB08\uCB10\uCB14\uCB18\uCB20\uCB21\uCB41\uCB48\uCB49\uCB4C\uCB50\uCB58\uCB59\uCB5D\uCB64\uCB78\uCB79\uCB9C\uCBB8\uCBD4\uCBE4\uCBE7\uCBE9\uCC0C\uCC0D\uCC10\uCC14\uCC1C\uCC1D\uCC21\uCC22\uCC27\uCC28\uCC29\uCC2C\uCC2E\uCC30\uCC38\uCC39\uCC3B\uCC3C\uCC3D\uCC3E\uCC44\uCC45\uCC48\uCC4C\uCC54\uCC55\uCC57\uCC58\uCC59\uCC60\uCC64\uCC66\uCC68\uCC70\uCC75\uCC98\uCC99\uCC9C\uCCA0\uCCA8\uCCA9\uCCAB\uCCAC\uCCAD\uCCB4\uCCB5\uCCB8\uCCBC\uCCC4\uCCC5\uCCC7\uCCC9\uCCD0\uCCD4\uCCE4\uCCEC\uCCF0\uCD01\uCD08\uCD09\uCD0C\uCD10\uCD18\uCD19\uCD1B\uCD1D\uCD24\uCD28\uCD2C\uCD39\uCD5C\uCD60\uCD64\uCD6C\uCD6D\uCD6F\uCD71\uCD78\uCD88\uCD94\uCD95\uCD98\uCD9C\uCDA4\uCDA5\uCDA7\uCDA9\uCDB0\uCDC4\uCDCC\uCDD0\uCDE8\uCDEC\uCDF0\uCDF8\uCDF9\uCDFB\uCDFD\uCE04\uCE08\uCE0C\uCE14\uCE19\uCE20\uCE21\uCE24\uCE28\uCE30\uCE31\uCE33\uCE35\uCE58\uCE59\uCE5C\uCE5F\uCE60\uCE61\uCE68\uCE69\uCE6B\uCE6D\uCE74\uCE75\uCE78\uCE7C\uCE84\uCE85\uCE87\uCE89\uCE90\uCE91\uCE94\uCE98\uCEA0\uCEA1\uCEA3\uCEA4\uCEA5\uCEAC\uCEAD\uCEC1\uCEE4\uCEE5\uCEE8\uCEEB\uCEEC\uCEF4\uCEF5\uCEF7\uCEF8\uCEF9\uCF00\uCF01\uCF04\uCF08\uCF10\uCF11\uCF13\uCF15\uCF1C\uCF20\uCF24\uCF2C\uCF2D\uCF2F\uCF30\uCF31\uCF38\uCF54\uCF55\uCF58\uCF5C\uCF64\uCF65\uCF67\uCF69\uCF70\uCF71\uCF74\uCF78\uCF80\uCF85\uCF8C\uCFA1\uCFA8\uCFB0\uCFC4\uCFE0\uCFE1\uCFE4\uCFE8\uCFF0\uCFF1\uCFF3\uCFF5\uCFFC\uD000\uD004\uD011\uD018\uD02D\uD034\uD035\uD038\uD03C\uD044\uD045\uD047\uD049\uD050\uD054\uD058\uD060\uD06C\uD06D\uD070\uD074\uD07C\uD07D\uD081\uD0A4\uD0A5\uD0A8\uD0AC\uD0B4\uD0B5\uD0B7\uD0B9\uD0C0\uD0C1\uD0C4\uD0C8\uD0C9\uD0D0\uD0D1\uD0D3\uD0D4\uD0D5\uD0DC\uD0DD\uD0E0\uD0E4\uD0EC\uD0ED\uD0EF\uD0F0\uD0F1\uD0F8\uD10D\uD130\uD131\uD134\uD138\uD13A\uD140\uD141\uD143\uD144\uD145\uD14C\uD14D\uD150\uD154\uD15C\uD15D\uD15F\uD161\uD168\uD16C\uD17C\uD184\uD188\uD1A0\uD1A1\uD1A4\uD1A8\uD1B0\uD1B1\uD1B3\uD1B5\uD1BA\uD1BC\uD1C0\uD1D8\uD1F4\uD1F8\uD207\uD209\uD210\uD22C\uD22D\uD230\uD234\uD23C\uD23D\uD23F\uD241\uD248\uD25C\uD264\uD280\uD281\uD284\uD288\uD290\uD291\uD295\uD29C\uD2A0\uD2A4\uD2AC\uD2B1\uD2B8\uD2B9\uD2BC\uD2BF\uD2C0\uD2C2\uD2C8\uD2C9\uD2CB\uD2D4\uD2D8\uD2DC\uD2E4\uD2E5\uD2F0\uD2F1\uD2F4\uD2F8\uD300\uD301\uD303\uD305\uD30C\uD30D\uD30E\uD310\uD314\uD316\uD31C\uD31D\uD31F\uD320\uD321\uD325\uD328\uD329\uD32C\uD330\uD338\uD339\uD33B\uD33C\uD33D\uD344\uD345\uD37C\uD37D\uD380\uD384\uD38C\uD38D\uD38F\uD390\uD391\uD398\uD399\uD39C\uD3A0\uD3A8\uD3A9\uD3AB\uD3AD\uD3B4\uD3B8\uD3BC\uD3C4\uD3C5\uD3C8\uD3C9\uD3D0\uD3D8\uD3E1\uD3E3\uD3EC\uD3ED\uD3F0\uD3F4\uD3FC\uD3FD\uD3FF\uD401\uD408\uD41D\uD440\uD444\uD45C\uD460\uD464\uD46D\uD46F\uD478\uD479\uD47C\uD47F\uD480\uD482\uD488\uD489\uD48B\uD48D\uD494\uD4A9\uD4CC\uD4D0\uD4D4\uD4DC\uD4DF\uD4E8\uD4EC\uD4F0\uD4F8\uD4FB\uD4FD\uD504\uD508\uD50C\uD514\uD515\uD517\uD53C\uD53D\uD540\uD544\uD54C\uD54D\uD54F\uD551\uD558\uD559\uD55C\uD560\uD565\uD568\uD569\uD56B\uD56D\uD574\uD575\uD578\uD57C\uD584\uD585\uD587\uD588\uD589\uD590\uD5A5\uD5C8\uD5C9\uD5CC\uD5D0\uD5D2\uD5D8\uD5D9\uD5DB\uD5DD\uD5E4\uD5E5\uD5E8\uD5EC\uD5F4\uD5F5\uD5F7\uD5F9\uD600\uD601\uD604\uD608\uD610\uD611\uD613\uD614\uD615\uD61C\uD620\uD624\uD62D\uD638\uD639\uD63C\uD640\uD645\uD648\uD649\uD64B\uD64D\uD651\uD654\uD655\uD658\uD65C\uD667\uD669\uD670\uD671\uD674\uD683\uD685\uD68C\uD68D\uD690\uD694\uD69D\uD69F\uD6A1\uD6A8\uD6AC\uD6B0\uD6B9\uD6BB\uD6C4\uD6C5\uD6C8\uD6CC\uD6D1\uD6D4\uD6D7\uD6D9\uD6E0\uD6E4\uD6E8\uD6F0\uD6F5\uD6FC\uD6FD\uD700\uD704\uD711\uD718\uD719\uD71C\uD720\uD728\uD729\uD72B\uD72D\uD734\uD735\uD738\uD73C\uD744\uD747\uD749\uD750\uD751\uD754\uD756\uD757\uD758\uD759\uD760\uD761\uD763\uD765\uD769\uD76C\uD770\uD774\uD77C\uD77D\uD781\uD788\uD789\uD78C\uD790\uD798\uD799\uD79B\uD79D\u4F3D\u4F73\u5047\u50F9\u52A0\u53EF\u5475\u54E5\u5609\u5AC1\u5BB6\u6687\u67B6\u67B7\u67EF\u6B4C\u73C2\u75C2\u7A3C\u82DB\u8304\u8857\u8888\u8A36\u8CC8\u8DCF\u8EFB\u8FE6\u99D5\u523B\u5374\u5404\u606A\u6164\u6BBC\u73CF\u811A\u89BA\u89D2\u95A3\u4F83\u520A\u58BE\u5978\u59E6\u5E72\u5E79\u61C7\u63C0\u6746\u67EC\u687F\u6F97\u764E\u770B\u78F5\u7A08\u7AFF\u7C21\u809D\u826E\u8271\u8AEB\u9593\u4E6B\u559D\u66F7\u6E34\u78A3\u7AED\u845B\u8910\u874E\u97A8\u52D8\u574E\u582A\u5D4C\u611F\u61BE\u6221\u6562\u67D1\u6A44\u6E1B\u7518\u75B3\u76E3\u77B0\u7D3A\u90AF\u9451\u9452\u9F95\u5323\u5CAC\u7532\u80DB\u9240\u9598\u525B\u5808\u59DC\u5CA1\u5D17\u5EB7\u5F3A\u5F4A\u6177\u6C5F\u757A\u7586\u7CE0\u7D73\u7DB1\u7F8C\u8154\u8221\u8591\u8941\u8B1B\u92FC\u964D\u9C47\u4ECB\u4EF7\u500B\u51F1\u584F\u6137\u613E\u6168\u6539\u69EA\u6F11\u75A5\u7686\u76D6\u7B87\u82A5\u84CB\uF900\u93A7\u958B\u5580\u5BA2\u5751\uF901\u7CB3\u7FB9\u91B5\u5028\u53BB\u5C45\u5DE8\u62D2\u636E\u64DA\u64E7\u6E20\u70AC\u795B\u8DDD\u8E1E\uF902\u907D\u9245\u92F8\u4E7E\u4EF6\u5065\u5DFE\u5EFA\u6106\u6957\u8171\u8654\u8E47\u9375\u9A2B\u4E5E\u5091\u6770\u6840\u5109\u528D\u5292\u6AA2\u77BC\u9210\u9ED4\u52AB\u602F\u8FF2\u5048\u61A9\u63ED\u64CA\u683C\u6A84\u6FC0\u8188\u89A1\u9694\u5805\u727D\u72AC\u7504\u7D79\u7E6D\u80A9\u898B\u8B74\u9063\u9D51\u6289\u6C7A\u6F54\u7D50\u7F3A\u8A23\u517C\u614A\u7B9D\u8B19\u9257\u938C\u4EAC\u4FD3\u501E\u50BE\u5106\u52C1\u52CD\u537F\u5770\u5883\u5E9A\u5F91\u6176\u61AC\u64CE\u656C\u666F\u66BB\u66F4\u6897\u6D87\u7085\u70F1\u749F\u74A5\u74CA\u75D9\u786C\u78EC\u7ADF\u7AF6\u7D45\u7D93\u8015\u803F\u811B\u8396\u8B66\u8F15\u9015\u93E1\u9803\u9838\u9A5A\u9BE8\u4FC2\u5553\u583A\u5951\u5B63\u5C46\u60B8\u6212\u6842\u68B0\u68E8\u6EAA\u754C\u7678\u78CE\u7A3D\u7CFB\u7E6B\u7E7C\u8A08\u8AA1\u8C3F\u968E\u9DC4\u53E4\u53E9\u544A\u5471\u56FA\u59D1\u5B64\u5C3B\u5EAB\u62F7\u6537\u6545\u6572\u66A0\u67AF\u69C1\u6CBD\u75FC\u7690\u777E\u7A3F\u7F94\u8003\u80A1\u818F\u82E6\u82FD\u83F0\u85C1\u8831\u88B4\u8AA5\uF903\u8F9C\u932E\u96C7\u9867\u9AD8\u9F13\u54ED\u659B\u66F2\u688F\u7A40\u8C37\u9D60\u56F0\u5764\u5D11\u6606\u68B1\u68CD\u6EFE\u7428\u889E\u9BE4\u6C68\uF904\u9AA8\u4F9B\u516C\u5171\u529F\u5B54\u5DE5\u6050\u606D\u62F1\u63A7\u653B\u73D9\u7A7A\u86A3\u8CA2\u978F\u4E32\u5BE1\u6208\u679C\u74DC\u79D1\u83D3\u8A87\u8AB2\u8DE8\u904E\u934B\u9846\u5ED3\u69E8\u85FF\u90ED\uF905\u51A0\u5B98\u5BEC\u6163\u68FA\u6B3E\u704C\u742F\u74D8\u7BA1\u7F50\u83C5\u89C0\u8CAB\u95DC\u9928\u522E\u605D\u62EC\u9002\u4F8A\u5149\u5321\u58D9\u5EE3\u66E0\u6D38\u709A\u72C2\u73D6\u7B50\u80F1\u945B\u5366\u639B\u7F6B\u4E56\u5080\u584A\u58DE\u602A\u6127\u62D0\u69D0\u9B41\u5B8F\u7D18\u80B1\u8F5F\u4EA4\u50D1\u54AC\u55AC\u5B0C\u5DA0\u5DE7\u652A\u654E\u6821\u6A4B\u72E1\u768E\u77EF\u7D5E\u7FF9\u81A0\u854E\u86DF\u8F03\u8F4E\u90CA\u9903\u9A55\u9BAB\u4E18\u4E45\u4E5D\u4EC7\u4FF1\u5177\u52FE\u5340\u53E3\u53E5\u548E\u5614\u5775\u57A2\u5BC7\u5D87\u5ED0\u61FC\u62D8\u6551\u67B8\u67E9\u69CB\u6B50\u6BC6\u6BEC\u6C42\u6E9D\u7078\u72D7\u7396\u7403\u77BF\u77E9\u7A76\u7D7F\u8009\u81FC\u8205\u820A\u82DF\u8862\u8B33\u8CFC\u8EC0\u9011\u90B1\u9264\u92B6\u99D2\u9A45\u9CE9\u9DD7\u9F9C\u570B\u5C40\u83CA\u97A0\u97AB\u9EB4\u541B\u7A98\u7FA4\u88D9\u8ECD\u90E1\u5800\u5C48\u6398\u7A9F\u5BAE\u5F13\u7A79\u7AAE\u828E\u8EAC\u5026\u5238\u52F8\u5377\u5708\u62F3\u6372\u6B0A\u6DC3\u7737\u53A5\u7357\u8568\u8E76\u95D5\u673A\u6AC3\u6F70\u8A6D\u8ECC\u994B\uF906\u6677\u6B78\u8CB4\u9B3C\uF907\u53EB\u572D\u594E\u63C6\u69FB\u73EA\u7845\u7ABA\u7AC5\u7CFE\u8475\u898F\u8D73\u9035\u95A8\u52FB\u5747\u7547\u7B60\u83CC\u921E\uF908\u6A58\u514B\u524B\u5287\u621F\u68D8\u6975\u9699\u50C5\u52A4\u52E4\u61C3\u65A4\u6839\u69FF\u747E\u7B4B\u82B9\u83EB\u89B2\u8B39\u8FD1\u9949\uF909\u4ECA\u5997\u64D2\u6611\u6A8E\u7434\u7981\u79BD\u82A9\u887E\u887F\u895F\uF90A\u9326\u4F0B\u53CA\u6025\u6271\u6C72\u7D1A\u7D66\u4E98\u5162\u77DC\u80AF\u4F01\u4F0E\u5176\u5180\u55DC\u5668\u573B\u57FA\u57FC\u5914\u5947\u5993\u5BC4\u5C90\u5D0E\u5DF1\u5E7E\u5FCC\u6280\u65D7\u65E3\u671E\u671F\u675E\u68CB\u68C4\u6A5F\u6B3A\u6C23\u6C7D\u6C82\u6DC7\u7398\u7426\u742A\u7482\u74A3\u7578\u757F\u7881\u78EF\u7941\u7947\u7948\u797A\u7B95\u7D00\u7DBA\u7F88\u8006\u802D\u808C\u8A18\u8B4F\u8C48\u8D77\u9321\u9324\u98E2\u9951\u9A0E\u9A0F\u9A65\u9E92\u7DCA\u4F76\u5409\u62EE\u6854\u91D1\u55AB\u513A\uF90B\uF90C\u5A1C\u61E6\uF90D\u62CF\u62FF\uF90E\uF90F\uF910\uF911\uF912\uF913\u90A3\uF914\uF915\uF916\uF917\uF918\u8AFE\uF919\uF91A\uF91B\uF91C\u6696\uF91D\u7156\uF91E\uF91F\u96E3\uF920\u634F\u637A\u5357\uF921\u678F\u6960\u6E73\uF922\u7537\uF923\uF924\uF925\u7D0D\uF926\uF927\u8872\u56CA\u5A18\uF928\uF929\uF92A\uF92B\uF92C\u4E43\uF92D\u5167\u5948\u67F0\u8010\uF92E\u5973\u5E74\u649A\u79CA\u5FF5\u606C\u62C8\u637B\u5BE7\u5BD7\u52AA\uF92F\u5974\u5F29\u6012\uF930\uF931\uF932\u7459\uF933\uF934\uF935\uF936\uF937\uF938\u99D1\uF939\uF93A\uF93B\uF93C\uF93D\uF93E\uF93F\uF940\uF941\uF942\uF943\u6FC3\uF944\uF945\u81BF\u8FB2\u60F1\uF946\uF947\u8166\uF948\uF949\u5C3F\uF94A\uF94B\uF94C\uF94D\uF94E\uF94F\uF950\uF951\u5AE9\u8A25\u677B\u7D10\uF952\uF953\uF954\uF955\uF956\uF957\u80FD\uF958\uF959\u5C3C\u6CE5\u533F\u6EBA\u591A\u8336\u4E39\u4EB6\u4F46\u55AE\u5718\u58C7\u5F56\u65B7\u65E6\u6A80\u6BB5\u6E4D\u77ED\u7AEF\u7C1E\u7DDE\u86CB\u8892\u9132\u935B\u64BB\u6FBE\u737A\u75B8\u9054\u5556\u574D\u61BA\u64D4\u66C7\u6DE1\u6E5B\u6F6D\u6FB9\u75F0\u8043\u81BD\u8541\u8983\u8AC7\u8B5A\u931F\u6C93\u7553\u7B54\u8E0F\u905D\u5510\u5802\u5858\u5E62\u6207\u649E\u68E0\u7576\u7CD6\u87B3\u9EE8\u4EE3\u5788\u576E\u5927\u5C0D\u5CB1\u5E36\u5F85\u6234\u64E1\u73B3\u81FA\u888B\u8CB8\u968A\u9EDB\u5B85\u5FB7\u60B3\u5012\u5200\u5230\u5716\u5835\u5857\u5C0E\u5C60\u5CF6\u5D8B\u5EA6\u5F92\u60BC\u6311\u6389\u6417\u6843\u68F9\u6AC2\u6DD8\u6E21\u6ED4\u6FE4\u71FE\u76DC\u7779\u79B1\u7A3B\u8404\u89A9\u8CED\u8DF3\u8E48\u9003\u9014\u9053\u90FD\u934D\u9676\u97DC\u6BD2\u7006\u7258\u72A2\u7368\u7763\u79BF\u7BE4\u7E9B\u8B80\u58A9\u60C7\u6566\u65FD\u66BE\u6C8C\u711E\u71C9\u8C5A\u9813\u4E6D\u7A81\u4EDD\u51AC\u51CD\u52D5\u540C\u61A7\u6771\u6850\u68DF\u6D1E\u6F7C\u75BC\u77B3\u7AE5\u80F4\u8463\u9285\u515C\u6597\u675C\u6793\u75D8\u7AC7\u8373\uF95A\u8C46\u9017\u982D\u5C6F\u81C0\u829A\u9041\u906F\u920D\u5F97\u5D9D\u6A59\u71C8\u767B\u7B49\u85E4\u8B04\u9127\u9A30\u5587\u61F6\uF95B\u7669\u7F85\u863F\u87BA\u88F8\u908F\uF95C\u6D1B\u70D9\u73DE\u7D61\u843D\uF95D\u916A\u99F1\uF95E\u4E82\u5375\u6B04\u6B12\u703E\u721B\u862D\u9E1E\u524C\u8FA3\u5D50\u64E5\u652C\u6B16\u6FEB\u7C43\u7E9C\u85CD\u8964\u89BD\u62C9\u81D8\u881F\u5ECA\u6717\u6D6A\u72FC\u7405\u746F\u8782\u90DE\u4F86\u5D0D\u5FA0\u840A\u51B7\u63A0\u7565\u4EAE\u5006\u5169\u51C9\u6881\u6A11\u7CAE\u7CB1\u7CE7\u826F\u8AD2\u8F1B\u91CF\u4FB6\u5137\u52F5\u5442\u5EEC\u616E\u623E\u65C5\u6ADA\u6FFE\u792A\u85DC\u8823\u95AD\u9A62\u9A6A\u9E97\u9ECE\u529B\u66C6\u6B77\u701D\u792B\u8F62\u9742\u6190\u6200\u6523\u6F23\u7149\u7489\u7DF4\u806F\u84EE\u8F26\u9023\u934A\u51BD\u5217\u52A3\u6D0C\u70C8\u88C2\u5EC9\u6582\u6BAE\u6FC2\u7C3E\u7375\u4EE4\u4F36\u56F9\uF95F\u5CBA\u5DBA\u601C\u73B2\u7B2D\u7F9A\u7FCE\u8046\u901E\u9234\u96F6\u9748\u9818\u9F61\u4F8B\u6FA7\u79AE\u91B4\u96B7\u52DE\uF960\u6488\u64C4\u6AD3\u6F5E\u7018\u7210\u76E7\u8001\u8606\u865C\u8DEF\u8F05\u9732\u9B6F\u9DFA\u9E75\u788C\u797F\u7DA0\u83C9\u9304\u9E7F\u9E93\u8AD6\u58DF\u5F04\u6727\u7027\u74CF\u7C60\u807E\u5121\u7028\u7262\u78CA\u8CC2\u8CDA\u8CF4\u96F7\u4E86\u50DA\u5BEE\u5ED6\u6599\u71CE\u7642\u77AD\u804A\u84FC\u907C\u9B27\u9F8D\u58D8\u5A41\u5C62\u6A13\u6DDA\u6F0F\u763B\u7D2F\u7E37\u851E\u8938\u93E4\u964B\u5289\u65D2\u67F3\u69B4\u6D41\u6E9C\u700F\u7409\u7460\u7559\u7624\u786B\u8B2C\u985E\u516D\u622E\u9678\u4F96\u502B\u5D19\u6DEA\u7DB8\u8F2A\u5F8B\u6144\u6817\uF961\u9686\u52D2\u808B\u51DC\u51CC\u695E\u7A1C\u7DBE\u83F1\u9675\u4FDA\u5229\u5398\u540F\u550E\u5C65\u60A7\u674E\u68A8\u6D6C\u7281\u72F8\u7406\u7483\uF962\u75E2\u7C6C\u7F79\u7FB8\u8389\u88CF\u88E1\u91CC\u91D0\u96E2\u9BC9\u541D\u6F7E\u71D0\u7498\u85FA\u8EAA\u96A3\u9C57\u9E9F\u6797\u6DCB\u7433\u81E8\u9716\u782C\u7ACB\u7B20\u7C92\u6469\u746A\u75F2\u78BC\u78E8\u99AC\u9B54\u9EBB\u5BDE\u5E55\u6F20\u819C\u83AB\u9088\u4E07\u534D\u5A29\u5DD2\u5F4E\u6162\u633D\u6669\u66FC\u6EFF\u6F2B\u7063\u779E\u842C\u8513\u883B\u8F13\u9945\u9C3B\u551C\u62B9\u672B\u6CAB\u8309\u896A\u977A\u4EA1\u5984\u5FD8\u5FD9\u671B\u7DB2\u7F54\u8292\u832B\u83BD\u8F1E\u9099\u57CB\u59B9\u5A92\u5BD0\u6627\u679A\u6885\u6BCF\u7164\u7F75\u8CB7\u8CE3\u9081\u9B45\u8108\u8C8A\u964C\u9A40\u9EA5\u5B5F\u6C13\u731B\u76F2\u76DF\u840C\u51AA\u8993\u514D\u5195\u52C9\u68C9\u6C94\u7704\u7720\u7DBF\u7DEC\u9762\u9EB5\u6EC5\u8511\u51A5\u540D\u547D\u660E\u669D\u6927\u6E9F\u76BF\u7791\u8317\u84C2\u879F\u9169\u9298\u9CF4\u8882\u4FAE\u5192\u52DF\u59C6\u5E3D\u6155\u6478\u6479\u66AE\u67D0\u6A21\u6BCD\u6BDB\u725F\u7261\u7441\u7738\u77DB\u8017\u82BC\u8305\u8B00\u8B28\u8C8C\u6728\u6C90\u7267\u76EE\u7766\u7A46\u9DA9\u6B7F\u6C92\u5922\u6726\u8499\u536F\u5893\u5999\u5EDF\u63CF\u6634\u6773\u6E3A\u732B\u7AD7\u82D7\u9328\u52D9\u5DEB\u61AE\u61CB\u620A\u62C7\u64AB\u65E0\u6959\u6B66\u6BCB\u7121\u73F7\u755D\u7E46\u821E\u8302\u856A\u8AA3\u8CBF\u9727\u9D61\u58A8\u9ED8\u5011\u520E\u543B\u554F\u6587\u6C76\u7D0A\u7D0B\u805E\u868A\u9580\u96EF\u52FF\u6C95\u7269\u5473\u5A9A\u5C3E\u5D4B\u5F4C\u5FAE\u672A\u68B6\u6963\u6E3C\u6E44\u7709\u7C73\u7F8E\u8587\u8B0E\u8FF7\u9761\u9EF4\u5CB7\u60B6\u610D\u61AB\u654F\u65FB\u65FC\u6C11\u6CEF\u739F\u73C9\u7DE1\u9594\u5BC6\u871C\u8B10\u525D\u535A\u62CD\u640F\u64B2\u6734\u6A38\u6CCA\u73C0\u749E\u7B94\u7C95\u7E1B\u818A\u8236\u8584\u8FEB\u96F9\u99C1\u4F34\u534A\u53CD\u53DB\u62CC\u642C\u6500\u6591\u69C3\u6CEE\u6F58\u73ED\u7554\u7622\u76E4\u76FC\u78D0\u78FB\u792C\u7D46\u822C\u87E0\u8FD4\u9812\u98EF\u52C3\u62D4\u64A5\u6E24\u6F51\u767C\u8DCB\u91B1\u9262\u9AEE\u9B43\u5023\u508D\u574A\u59A8\u5C28\u5E47\u5F77\u623F\u653E\u65B9\u65C1\u6609\u678B\u699C\u6EC2\u78C5\u7D21\u80AA\u8180\u822B\u82B3\u84A1\u868C\u8A2A\u8B17\u90A6\u9632\u9F90\u500D\u4FF3\uF963\u57F9\u5F98\u62DC\u6392\u676F\u6E43\u7119\u76C3\u80CC\u80DA\u88F4\u88F5\u8919\u8CE0\u8F29\u914D\u966A\u4F2F\u4F70\u5E1B\u67CF\u6822\u767D\u767E\u9B44\u5E61\u6A0A\u7169\u71D4\u756A\uF964\u7E41\u8543\u85E9\u98DC\u4F10\u7B4F\u7F70\u95A5\u51E1\u5E06\u68B5\u6C3E\u6C4E\u6CDB\u72AF\u7BC4\u8303\u6CD5\u743A\u50FB\u5288\u58C1\u64D8\u6A97\u74A7\u7656\u78A7\u8617\u95E2\u9739\uF965\u535E\u5F01\u8B8A\u8FA8\u8FAF\u908A\u5225\u77A5\u9C49\u9F08\u4E19\u5002\u5175\u5C5B\u5E77\u661E\u663A\u67C4\u68C5\u70B3\u7501\u75C5\u79C9\u7ADD\u8F27\u9920\u9A08\u4FDD\u5821\u5831\u5BF6\u666E\u6B65\u6D11\u6E7A\u6F7D\u73E4\u752B\u83E9\u88DC\u8913\u8B5C\u8F14\u4F0F\u50D5\u5310\u535C\u5B93\u5FA9\u670D\u798F\u8179\u832F\u8514\u8907\u8986\u8F39\u8F3B\u99A5\u9C12\u672C\u4E76\u4FF8\u5949\u5C01\u5CEF\u5CF0\u6367\u68D2\u70FD\u71A2\u742B\u7E2B\u84EC\u8702\u9022\u92D2\u9CF3\u4E0D\u4ED8\u4FEF\u5085\u5256\u526F\u5426\u5490\u57E0\u592B\u5A66\u5B5A\u5B75\u5BCC\u5E9C\uF966\u6276\u6577\u65A7\u6D6E\u6EA5\u7236\u7B26\u7C3F\u7F36\u8150\u8151\u819A\u8240\u8299\u83A9\u8A03\u8CA0\u8CE6\u8CFB\u8D74\u8DBA\u90E8\u91DC\u961C\u9644\u99D9\u9CE7\u5317\u5206\u5429\u5674\u58B3\u5954\u596E\u5FFF\u61A4\u626E\u6610\u6C7E\u711A\u76C6\u7C89\u7CDE\u7D1B\u82AC\u8CC1\u96F0\uF967\u4F5B\u5F17\u5F7F\u62C2\u5D29\u670B\u68DA\u787C\u7E43\u9D6C\u4E15\u5099\u5315\u532A\u5351\u5983\u5A62\u5E87\u60B2\u618A\u6249\u6279\u6590\u6787\u69A7\u6BD4\u6BD6\u6BD7\u6BD8\u6CB8\uF968\u7435\u75FA\u7812\u7891\u79D5\u79D8\u7C83\u7DCB\u7FE1\u80A5\u813E\u81C2\u83F2\u871A\u88E8\u8AB9\u8B6C\u8CBB\u9119\u975E\u98DB\u9F3B\u56AC\u5B2A\u5F6C\u658C\u6AB3\u6BAF\u6D5C\u6FF1\u7015\u725D\u73AD\u8CA7\u8CD3\u983B\u6191\u6C37\u8058\u9A01\u4E4D\u4E8B\u4E9B\u4ED5\u4F3A\u4F3C\u4F7F\u4FDF\u50FF\u53F2\u53F8\u5506\u55E3\u56DB\u58EB\u5962\u5A11\u5BEB\u5BFA\u5C04\u5DF3\u5E2B\u5F99\u601D\u6368\u659C\u65AF\u67F6\u67FB\u68AD\u6B7B\u6C99\u6CD7\u6E23\u7009\u7345\u7802\u793E\u7940\u7960\u79C1\u7BE9\u7D17\u7D72\u8086\u820D\u838E\u84D1\u86C7\u88DF\u8A50\u8A5E\u8B1D\u8CDC\u8D66\u8FAD\u90AA\u98FC\u99DF\u9E9D\u524A\uF969\u6714\uF96A\u5098\u522A\u5C71\u6563\u6C55\u73CA\u7523\u759D\u7B97\u849C\u9178\u9730\u4E77\u6492\u6BBA\u715E\u85A9\u4E09\uF96B\u6749\u68EE\u6E17\u829F\u8518\u886B\u63F7\u6F81\u9212\u98AF\u4E0A\u50B7\u50CF\u511F\u5546\u55AA\u5617\u5B40\u5C19\u5CE0\u5E38\u5E8A\u5EA0\u5EC2\u60F3\u6851\u6A61\u6E58\u723D\u7240\u72C0\u76F8\u7965\u7BB1\u7FD4\u88F3\u89F4\u8A73\u8C61\u8CDE\u971C\u585E\u74BD\u8CFD\u55C7\uF96C\u7A61\u7D22\u8272\u7272\u751F\u7525\uF96D\u7B19\u5885\u58FB\u5DBC\u5E8F\u5EB6\u5F90\u6055\u6292\u637F\u654D\u6691\u66D9\u66F8\u6816\u68F2\u7280\u745E\u7B6E\u7D6E\u7DD6\u7F72\u80E5\u8212\u85AF\u897F\u8A93\u901D\u92E4\u9ECD\u9F20\u5915\u596D\u5E2D\u60DC\u6614\u6673\u6790\u6C50\u6DC5\u6F5F\u77F3\u78A9\u84C6\u91CB\u932B\u4ED9\u50CA\u5148\u5584\u5B0B\u5BA3\u6247\u657E\u65CB\u6E32\u717D\u7401\u7444\u7487\u74BF\u766C\u79AA\u7DDA\u7E55\u7FA8\u817A\u81B3\u8239\u861A\u87EC\u8A75\u8DE3\u9078\u9291\u9425\u994D\u9BAE\u5368\u5C51\u6954\u6CC4\u6D29\u6E2B\u820C\u859B\u893B\u8A2D\u8AAA\u96EA\u9F67\u5261\u66B9\u6BB2\u7E96\u87FE\u8D0D\u9583\u965D\u651D\u6D89\u71EE\uF96E\u57CE\u59D3\u5BAC\u6027\u60FA\u6210\u661F\u665F\u7329\u73F9\u76DB\u7701\u7B6C\u8056\u8072\u8165\u8AA0\u9192\u4E16\u52E2\u6B72\u6D17\u7A05\u7B39\u7D30\uF96F\u8CB0\u53EC\u562F\u5851\u5BB5\u5C0F\u5C11\u5DE2\u6240\u6383\u6414\u662D\u68B3\u6CBC\u6D88\u6EAF\u701F\u70A4\u71D2\u7526\u758F\u758E\u7619\u7B11\u7BE0\u7C2B\u7D20\u7D39\u852C\u856D\u8607\u8A34\u900D\u9061\u90B5\u92B7\u97F6\u9A37\u4FD7\u5C6C\u675F\u6D91\u7C9F\u7E8C\u8B16\u8D16\u901F\u5B6B\u5DFD\u640D\u84C0\u905C\u98E1\u7387\u5B8B\u609A\u677E\u6DDE\u8A1F\u8AA6\u9001\u980C\u5237\uF970\u7051\u788E\u9396\u8870\u91D7\u4FEE\u53D7\u55FD\u56DA\u5782\u58FD\u5AC2\u5B88\u5CAB\u5CC0\u5E25\u6101\u620D\u624B\u6388\u641C\u6536\u6578\u6A39\u6B8A\u6C34\u6D19\u6F31\u71E7\u72E9\u7378\u7407\u74B2\u7626\u7761\u79C0\u7A57\u7AEA\u7CB9\u7D8F\u7DAC\u7E61\u7F9E\u8129\u8331\u8490\u84DA\u85EA\u8896\u8AB0\u8B90\u8F38\u9042\u9083\u916C\u9296\u92B9\u968B\u96A7\u96A8\u96D6\u9700\u9808\u9996\u9AD3\u9B1A\u53D4\u587E\u5919\u5B70\u5BBF\u6DD1\u6F5A\u719F\u7421\u74B9\u8085\u83FD\u5DE1\u5F87\u5FAA\u6042\u65EC\u6812\u696F\u6A53\u6B89\u6D35\u6DF3\u73E3\u76FE\u77AC\u7B4D\u7D14\u8123\u821C\u8340\u84F4\u8563\u8A62\u8AC4\u9187\u931E\u9806\u99B4\u620C\u8853\u8FF0\u9265\u5D07\u5D27\u5D69\u745F\u819D\u8768\u6FD5\u62FE\u7FD2\u8936\u8972\u4E1E\u4E58\u50E7\u52DD\u5347\u627F\u6607\u7E69\u8805\u965E\u4F8D\u5319\u5636\u59CB\u5AA4\u5C38\u5C4E\u5C4D\u5E02\u5F11\u6043\u65BD\u662F\u6642\u67BE\u67F4\u731C\u77E2\u793A\u7FC5\u8494\u84CD\u8996\u8A66\u8A69\u8AE1\u8C55\u8C7A\u57F4\u5BD4\u5F0F\u606F\u62ED\u690D\u6B96\u6E5C\u7184\u7BD2\u8755\u8B58\u8EFE\u98DF\u98FE\u4F38\u4F81\u4FE1\u547B\u5A20\u5BB8\u613C\u65B0\u6668\u71FC\u7533\u795E\u7D33\u814E\u81E3\u8398\u85AA\u85CE\u8703\u8A0A\u8EAB\u8F9B\uF971\u8FC5\u5931\u5BA4\u5BE6\u6089\u5BE9\u5C0B\u5FC3\u6C81\uF972\u6DF1\u700B\u751A\u82AF\u8AF6\u4EC0\u5341\uF973\u96D9\u6C0F\u4E9E\u4FC4\u5152\u555E\u5A25\u5CE8\u6211\u7259\u82BD\u83AA\u86FE\u8859\u8A1D\u963F\u96C5\u9913\u9D09\u9D5D\u580A\u5CB3\u5DBD\u5E44\u60E1\u6115\u63E1\u6A02\u6E25\u9102\u9354\u984E\u9C10\u9F77\u5B89\u5CB8\u6309\u664F\u6848\u773C\u96C1\u978D\u9854\u9B9F\u65A1\u8B01\u8ECB\u95BC\u5535\u5CA9\u5DD6\u5EB5\u6697\u764C\u83F4\u95C7\u58D3\u62BC\u72CE\u9D28\u4EF0\u592E\u600F\u663B\u6B83\u79E7\u9D26\u5393\u54C0\u57C3\u5D16\u611B\u66D6\u6DAF\u788D\u827E\u9698\u9744\u5384\u627C\u6396\u6DB2\u7E0A\u814B\u984D\u6AFB\u7F4C\u9DAF\u9E1A\u4E5F\u503B\u51B6\u591C\u60F9\u63F6\u6930\u723A\u8036\uF974\u91CE\u5F31\uF975\uF976\u7D04\u82E5\u846F\u84BB\u85E5\u8E8D\uF977\u4F6F\uF978\uF979\u58E4\u5B43\u6059\u63DA\u6518\u656D\u6698\uF97A\u694A\u6A23\u6D0B\u7001\u716C\u75D2\u760D\u79B3\u7A70\uF97B\u7F8A\uF97C\u8944\uF97D\u8B93\u91C0\u967D\uF97E\u990A\u5704\u5FA1\u65BC\u6F01\u7600\u79A6\u8A9E\u99AD\u9B5A\u9F6C\u5104\u61B6\u6291\u6A8D\u81C6\u5043\u5830\u5F66\u7109\u8A00\u8AFA\u5B7C\u8616\u4FFA\u513C\u56B4\u5944\u63A9\u6DF9\u5DAA\u696D\u5186\u4E88\u4F59\uF97F\uF980\uF981\u5982\uF982\uF983\u6B5F\u6C5D\uF984\u74B5\u7916\uF985\u8207\u8245\u8339\u8F3F\u8F5D\uF986\u9918\uF987\uF988\uF989\u4EA6\uF98A\u57DF\u5F79\u6613\uF98B\uF98C\u75AB\u7E79\u8B6F\uF98D\u9006\u9A5B\u56A5\u5827\u59F8\u5A1F\u5BB4\uF98E\u5EF6\uF98F\uF990\u6350\u633B\uF991\u693D\u6C87\u6CBF\u6D8E\u6D93\u6DF5\u6F14\uF992\u70DF\u7136\u7159\uF993\u71C3\u71D5\uF994\u784F\u786F\uF995\u7B75\u7DE3\uF996\u7E2F\uF997\u884D\u8EDF\uF998\uF999\uF99A\u925B\uF99B\u9CF6\uF99C\uF99D\uF99E\u6085\u6D85\uF99F\u71B1\uF9A0\uF9A1\u95B1\u53AD\uF9A2\uF9A3\uF9A4\u67D3\uF9A5\u708E\u7130\u7430\u8276\u82D2\uF9A6\u95BB\u9AE5\u9E7D\u66C4\uF9A7\u71C1\u8449\uF9A8\uF9A9\u584B\uF9AA\uF9AB\u5DB8\u5F71\uF9AC\u6620\u668E\u6979\u69AE\u6C38\u6CF3\u6E36\u6F41\u6FDA\u701B\u702F\u7150\u71DF\u7370\uF9AD\u745B\uF9AE\u74D4\u76C8\u7A4E\u7E93\uF9AF\uF9B0\u82F1\u8A60\u8FCE\uF9B1\u9348\uF9B2\u9719\uF9B3\uF9B4\u4E42\u502A\uF9B5\u5208\u53E1\u66F3\u6C6D\u6FCA\u730A\u777F\u7A62\u82AE\u85DD\u8602\uF9B6\u88D4\u8A63\u8B7D\u8C6B\uF9B7\u92B3\uF9B8\u9713\u9810\u4E94\u4F0D\u4FC9\u50B2\u5348\u543E\u5433\u55DA\u5862\u58BA\u5967\u5A1B\u5BE4\u609F\uF9B9\u61CA\u6556\u65FF\u6664\u68A7\u6C5A\u6FB3\u70CF\u71AC\u7352\u7B7D\u8708\u8AA4\u9C32\u9F07\u5C4B\u6C83\u7344\u7389\u923A\u6EAB\u7465\u761F\u7A69\u7E15\u860A\u5140\u58C5\u64C1\u74EE\u7515\u7670\u7FC1\u9095\u96CD\u9954\u6E26\u74E6\u7AA9\u7AAA\u81E5\u86D9\u8778\u8A1B\u5A49\u5B8C\u5B9B\u68A1\u6900\u6D63\u73A9\u7413\u742C\u7897\u7DE9\u7FEB\u8118\u8155\u839E\u8C4C\u962E\u9811\u66F0\u5F80\u65FA\u6789\u6C6A\u738B\u502D\u5A03\u6B6A\u77EE\u5916\u5D6C\u5DCD\u7325\u754F\uF9BA\uF9BB\u50E5\u51F9\u582F\u592D\u5996\u59DA\u5BE5\uF9BC\uF9BD\u5DA2\u62D7\u6416\u6493\u64FE\uF9BE\u66DC\uF9BF\u6A48\uF9C0\u71FF\u7464\uF9C1\u7A88\u7AAF\u7E47\u7E5E\u8000\u8170\uF9C2\u87EF\u8981\u8B20\u9059\uF9C3\u9080\u9952\u617E\u6B32\u6D74\u7E1F\u8925\u8FB1\u4FD1\u50AD\u5197\u52C7\u57C7\u5889\u5BB9\u5EB8\u6142\u6995\u6D8C\u6E67\u6EB6\u7194\u7462\u7528\u752C\u8073\u8338\u84C9\u8E0A\u9394\u93DE\uF9C4\u4E8E\u4F51\u5076\u512A\u53C8\u53CB\u53F3\u5B87\u5BD3\u5C24\u611A\u6182\u65F4\u725B\u7397\u7440\u76C2\u7950\u7991\u79B9\u7D06\u7FBD\u828B\u85D5\u865E\u8FC2\u9047\u90F5\u91EA\u9685\u96E8\u96E9\u52D6\u5F67\u65ED\u6631\u682F\u715C\u7A36\u90C1\u980A\u4E91\uF9C5\u6A52\u6B9E\u6F90\u7189\u8018\u82B8\u8553\u904B\u9695\u96F2\u97FB\u851A\u9B31\u4E90\u718A\u96C4\u5143\u539F\u54E1\u5713\u5712\u57A3\u5A9B\u5AC4\u5BC3\u6028\u613F\u63F4\u6C85\u6D39\u6E72\u6E90\u7230\u733F\u7457\u82D1\u8881\u8F45\u9060\uF9C6\u9662\u9858\u9D1B\u6708\u8D8A\u925E\u4F4D\u5049\u50DE\u5371\u570D\u59D4\u5A01\u5C09\u6170\u6690\u6E2D\u7232\u744B\u7DEF\u80C3\u840E\u8466\u853F\u875F\u885B\u8918\u8B02\u9055\u97CB\u9B4F\u4E73\u4F91\u5112\u516A\uF9C7\u552F\u55A9\u5B7A\u5BA5\u5E7C\u5E7D\u5EBE\u60A0\u60DF\u6108\u6109\u63C4\u6538\u6709\uF9C8\u67D4\u67DA\uF9C9\u6961\u6962\u6CB9\u6D27\uF9CA\u6E38\uF9CB\u6FE1\u7336\u7337\uF9CC\u745C\u7531\uF9CD\u7652\uF9CE\uF9CF\u7DAD\u81FE\u8438\u88D5\u8A98\u8ADB\u8AED\u8E30\u8E42\u904A\u903E\u907A\u9149\u91C9\u936E\uF9D0\uF9D1\u5809\uF9D2\u6BD3\u8089\u80B2\uF9D3\uF9D4\u5141\u596B\u5C39\uF9D5\uF9D6\u6F64\u73A7\u80E4\u8D07\uF9D7\u9217\u958F\uF9D8\uF9D9\uF9DA\uF9DB\u807F\u620E\u701C\u7D68\u878D\uF9DC\u57A0\u6069\u6147\u6BB7\u8ABE\u9280\u96B1\u4E59\u541F\u6DEB\u852D\u9670\u97F3\u98EE\u63D6\u6CE3\u9091\u51DD\u61C9\u81BA\u9DF9\u4F9D\u501A\u5100\u5B9C\u610F\u61FF\u64EC\u6905\u6BC5\u7591\u77E3\u7FA9\u8264\u858F\u87FB\u8863\u8ABC\u8B70\u91AB\u4E8C\u4EE5\u4F0A\uF9DD\uF9DE\u5937\u59E8\uF9DF\u5DF2\u5F1B\u5F5B\u6021\uF9E0\uF9E1\uF9E2\uF9E3\u723E\u73E5\uF9E4\u7570\u75CD\uF9E5\u79FB\uF9E6\u800C\u8033\u8084\u82E1\u8351\uF9E7\uF9E8\u8CBD\u8CB3\u9087\uF9E9\uF9EA\u98F4\u990C\uF9EB\uF9EC\u7037\u76CA\u7FCA\u7FCC\u7FFC\u8B1A\u4EBA\u4EC1\u5203\u5370\uF9ED\u54BD\u56E0\u59FB\u5BC5\u5F15\u5FCD\u6E6E\uF9EE\uF9EF\u7D6A\u8335\uF9F0\u8693\u8A8D\uF9F1\u976D\u9777\uF9F2\uF9F3\u4E00\u4F5A\u4F7E\u58F9\u65E5\u6EA2\u9038\u93B0\u99B9\u4EFB\u58EC\u598A\u59D9\u6041\uF9F4\uF9F5\u7A14\uF9F6\u834F\u8CC3\u5165\u5344\uF9F7\uF9F8\uF9F9\u4ECD\u5269\u5B55\u82BF\u4ED4\u523A\u54A8\u59C9\u59FF\u5B50\u5B57\u5B5C\u6063\u6148\u6ECB\u7099\u716E\u7386\u74F7\u75B5\u78C1\u7D2B\u8005\u81EA\u8328\u8517\u85C9\u8AEE\u8CC7\u96CC\u4F5C\u52FA\u56BC\u65AB\u6628\u707C\u70B8\u7235\u7DBD\u828D\u914C\u96C0\u9D72\u5B71\u68E7\u6B98\u6F7A\u76DE\u5C91\u66AB\u6F5B\u7BB4\u7C2A\u8836\u96DC\u4E08\u4ED7\u5320\u5834\u58BB\u58EF\u596C\u5C07\u5E33\u5E84\u5F35\u638C\u66B2\u6756\u6A1F\u6AA3\u6B0C\u6F3F\u7246\uF9FA\u7350\u748B\u7AE0\u7CA7\u8178\u81DF\u81E7\u838A\u846C\u8523\u8594\u85CF\u88DD\u8D13\u91AC\u9577\u969C\u518D\u54C9\u5728\u5BB0\u624D\u6750\u683D\u6893\u6E3D\u6ED3\u707D\u7E21\u88C1\u8CA1\u8F09\u9F4B\u9F4E\u722D\u7B8F\u8ACD\u931A\u4F47\u4F4E\u5132\u5480\u59D0\u5E95\u62B5\u6775\u696E\u6A17\u6CAE\u6E1A\u72D9\u732A\u75BD\u7BB8\u7D35\u82E7\u83F9\u8457\u85F7\u8A5B\u8CAF\u8E87\u9019\u90B8\u96CE\u9F5F\u52E3\u540A\u5AE1\u5BC2\u6458\u6575\u6EF4\u72C4\uF9FB\u7684\u7A4D\u7B1B\u7C4D\u7E3E\u7FDF\u837B\u8B2B\u8CCA\u8D64\u8DE1\u8E5F\u8FEA\u8FF9\u9069\u93D1\u4F43\u4F7A\u50B3\u5168\u5178\u524D\u526A\u5861\u587C\u5960\u5C08\u5C55\u5EDB\u609B\u6230\u6813\u6BBF\u6C08\u6FB1\u714E\u7420\u7530\u7538\u7551\u7672\u7B4C\u7B8B\u7BAD\u7BC6\u7E8F\u8A6E\u8F3E\u8F49\u923F\u9293\u9322\u942B\u96FB\u985A\u986B\u991E\u5207\u622A\u6298\u6D59\u7664\u7ACA\u7BC0\u7D76\u5360\u5CBE\u5E97\u6F38\u70B9\u7C98\u9711\u9B8E\u9EDE\u63A5\u647A\u8776\u4E01\u4E95\u4EAD\u505C\u5075\u5448\u59C3\u5B9A\u5E40\u5EAD\u5EF7\u5F81\u60C5\u633A\u653F\u6574\u65CC\u6676\u6678\u67FE\u6968\u6A89\u6B63\u6C40\u6DC0\u6DE8\u6E1F\u6E5E\u701E\u70A1\u738E\u73FD\u753A\u775B\u7887\u798E\u7A0B\u7A7D\u7CBE\u7D8E\u8247\u8A02\u8AEA\u8C9E\u912D\u914A\u91D8\u9266\u92CC\u9320\u9706\u9756\u975C\u9802\u9F0E\u5236\u5291\u557C\u5824\u5E1D\u5F1F\u608C\u63D0\u68AF\u6FDF\u796D\u7B2C\u81CD\u85BA\u88FD\u8AF8\u8E44\u918D\u9664\u969B\u973D\u984C\u9F4A\u4FCE\u5146\u51CB\u52A9\u5632\u5F14\u5F6B\u63AA\u64CD\u65E9\u6641\u66FA\u66F9\u671D\u689D\u68D7\u69FD\u6F15\u6F6E\u7167\u71E5\u722A\u74AA\u773A\u7956\u795A\u79DF\u7A20\u7A95\u7C97\u7CDF\u7D44\u7E70\u8087\u85FB\u86A4\u8A54\u8ABF\u8D99\u8E81\u9020\u906D\u91E3\u963B\u96D5\u9CE5\u65CF\u7C07\u8DB3\u93C3\u5B58\u5C0A\u5352\u62D9\u731D\u5027\u5B97\u5F9E\u60B0\u616B\u68D5\u6DD9\u742E\u7A2E\u7D42\u7D9C\u7E31\u816B\u8E2A\u8E35\u937E\u9418\u4F50\u5750\u5DE6\u5EA7\u632B\u7F6A\u4E3B\u4F4F\u4F8F\u505A\u59DD\u80C4\u546A\u5468\u55FE\u594F\u5B99\u5DDE\u5EDA\u665D\u6731\u67F1\u682A\u6CE8\u6D32\u6E4A\u6F8D\u70B7\u73E0\u7587\u7C4C\u7D02\u7D2C\u7DA2\u821F\u86DB\u8A3B\u8A85\u8D70\u8E8A\u8F33\u9031\u914E\u9152\u9444\u99D0\u7AF9\u7CA5\u4FCA\u5101\u51C6\u57C8\u5BEF\u5CFB\u6659\u6A3D\u6D5A\u6E96\u6FEC\u710C\u756F\u7AE3\u8822\u9021\u9075\u96CB\u99FF\u8301\u4E2D\u4EF2\u8846\u91CD\u537D\u6ADB\u696B\u6C41\u847A\u589E\u618E\u66FE\u62EF\u70DD\u7511\u75C7\u7E52\u84B8\u8B49\u8D08\u4E4B\u53EA\u54AB\u5730\u5740\u5FD7\u6301\u6307\u646F\u652F\u65E8\u667A\u679D\u67B3\u6B62\u6C60\u6C9A\u6F2C\u77E5\u7825\u7949\u7957\u7D19\u80A2\u8102\u81F3\u829D\u82B7\u8718\u8A8C\uF9FC\u8D04\u8DBE\u9072\u76F4\u7A19\u7A37\u7E54\u8077\u5507\u55D4\u5875\u632F\u6422\u6649\u664B\u686D\u699B\u6B84\u6D25\u6EB1\u73CD\u7468\u74A1\u755B\u75B9\u76E1\u771E\u778B\u79E6\u7E09\u7E1D\u81FB\u852F\u8897\u8A3A\u8CD1\u8EEB\u8FB0\u9032\u93AD\u9663\u9673\u9707\u4F84\u53F1\u59EA\u5AC9\u5E19\u684E\u74C6\u75BE\u79E9\u7A92\u81A3\u86ED\u8CEA\u8DCC\u8FED\u659F\u6715\uF9FD\u57F7\u6F57\u7DDD\u8F2F\u93F6\u96C6\u5FB5\u61F2\u6F84\u4E14\u4F98\u501F\u53C9\u55DF\u5D6F\u5DEE\u6B21\u6B64\u78CB\u7B9A\uF9FE\u8E49\u8ECA\u906E\u6349\u643E\u7740\u7A84\u932F\u947F\u9F6A\u64B0\u6FAF\u71E6\u74A8\u74DA\u7AC4\u7C12\u7E82\u7CB2\u7E98\u8B9A\u8D0A\u947D\u9910\u994C\u5239\u5BDF\u64E6\u672D\u7D2E\u50ED\u53C3\u5879\u6158\u6159\u61FA\u65AC\u7AD9\u8B92\u8B96\u5009\u5021\u5275\u5531\u5A3C\u5EE0\u5F70\u6134\u655E\u660C\u6636\u66A2\u69CD\u6EC4\u6F32\u7316\u7621\u7A93\u8139\u8259\u83D6\u84BC\u50B5\u57F0\u5BC0\u5BE8\u5F69\u63A1\u7826\u7DB5\u83DC\u8521\u91C7\u91F5\u518A\u67F5\u7B56\u8CAC\u51C4\u59BB\u60BD\u8655\u501C\uF9FF\u5254\u5C3A\u617D\u621A\u62D3\u64F2\u65A5\u6ECC\u7620\u810A\u8E60\u965F\u96BB\u4EDF\u5343\u5598\u5929\u5DDD\u64C5\u6CC9\u6DFA\u7394\u7A7F\u821B\u85A6\u8CE4\u8E10\u9077\u91E7\u95E1\u9621\u97C6\u51F8\u54F2\u5586\u5FB9\u64A4\u6F88\u7DB4\u8F1F\u8F4D\u9435\u50C9\u5C16\u6CBE\u6DFB\u751B\u77BB\u7C3D\u7C64\u8A79\u8AC2\u581E\u59BE\u5E16\u6377\u7252\u758A\u776B\u8ADC\u8CBC\u8F12\u5EF3\u6674\u6DF8\u807D\u83C1\u8ACB\u9751\u9BD6\uFA00\u5243\u66FF\u6D95\u6EEF\u7DE0\u8AE6\u902E\u905E\u9AD4\u521D\u527F\u54E8\u6194\u6284\u62DB\u68A2\u6912\u695A\u6A35\u7092\u7126\u785D\u7901\u790E\u79D2\u7A0D\u8096\u8278\u82D5\u8349\u8549\u8C82\u8D85\u9162\u918B\u91AE\u4FC3\u56D1\u71ED\u77D7\u8700\u89F8\u5BF8\u5FD6\u6751\u90A8\u53E2\u585A\u5BF5\u60A4\u6181\u6460\u7E3D\u8070\u8525\u9283\u64AE\u50AC\u5D14\u6700\u589C\u62BD\u63A8\u690E\u6978\u6A1E\u6E6B\u76BA\u79CB\u82BB\u8429\u8ACF\u8DA8\u8FFD\u9112\u914B\u919C\u9310\u9318\u939A\u96DB\u9A36\u9C0D\u4E11\u755C\u795D\u7AFA\u7B51\u7BC9\u7E2E\u84C4\u8E59\u8E74\u8EF8\u9010\u6625\u693F\u7443\u51FA\u672E\u9EDC\u5145\u5FE0\u6C96\u87F2\u885D\u8877\u60B4\u81B5\u8403\u8D05\u53D6\u5439\u5634\u5A36\u5C31\u708A\u7FE0\u805A\u8106\u81ED\u8DA3\u9189\u9A5F\u9DF2\u5074\u4EC4\u53A0\u60FB\u6E2C\u5C64\u4F88\u5024\u55E4\u5CD9\u5E5F\u6065\u6894\u6CBB\u6DC4\u71BE\u75D4\u75F4\u7661\u7A1A\u7A49\u7DC7\u7DFB\u7F6E\u81F4\u86A9\u8F1C\u96C9\u99B3\u9F52\u5247\u52C5\u98ED\u89AA\u4E03\u67D2\u6F06\u4FB5\u5BE2\u6795\u6C88\u6D78\u741B\u7827\u91DD\u937C\u87C4\u79E4\u7A31\u5FEB\u4ED6\u54A4\u553E\u58AE\u59A5\u60F0\u6253\u62D6\u6736\u6955\u8235\u9640\u99B1\u99DD\u502C\u5353\u5544\u577C\uFA01\u6258\uFA02\u64E2\u666B\u67DD\u6FC1\u6FEF\u7422\u7438\u8A17\u9438\u5451\u5606\u5766\u5F48\u619A\u6B4E\u7058\u70AD\u7DBB\u8A95\u596A\u812B\u63A2\u7708\u803D\u8CAA\u5854\u642D\u69BB\u5B95\u5E11\u6E6F\uFA03\u8569\u514C\u53F0\u592A\u6020\u614B\u6B86\u6C70\u6CF0\u7B1E\u80CE\u82D4\u8DC6\u90B0\u98B1\uFA04\u64C7\u6FA4\u6491\u6504\u514E\u5410\u571F\u8A0E\u615F\u6876\uFA05\u75DB\u7B52\u7D71\u901A\u5806\u69CC\u817F\u892A\u9000\u9839\u5078\u5957\u59AC\u6295\u900F\u9B2A\u615D\u7279\u95D6\u5761\u5A46\u5DF4\u628A\u64AD\u64FA\u6777\u6CE2\u6D3E\u722C\u7436\u7834\u7F77\u82AD\u8DDB\u9817\u5224\u5742\u677F\u7248\u74E3\u8CA9\u8FA6\u9211\u962A\u516B\u53ED\u634C\u4F69\u5504\u6096\u6557\u6C9B\u6D7F\u724C\u72FD\u7A17\u8987\u8C9D\u5F6D\u6F8E\u70F9\u81A8\u610E\u4FBF\u504F\u6241\u7247\u7BC7\u7DE8\u7FE9\u904D\u97AD\u9A19\u8CB6\u576A\u5E73\u67B0\u840D\u8A55\u5420\u5B16\u5E63\u5EE2\u5F0A\u6583\u80BA\u853D\u9589\u965B\u4F48\u5305\u530D\u530F\u5486\u54FA\u5703\u5E03\u6016\u629B\u62B1\u6355\uFA06\u6CE1\u6D66\u75B1\u7832\u80DE\u812F\u82DE\u8461\u84B2\u888D\u8912\u900B\u92EA\u98FD\u9B91\u5E45\u66B4\u66DD\u7011\u7206\uFA07\u4FF5\u527D\u5F6A\u6153\u6753\u6A19\u6F02\u74E2\u7968\u8868\u8C79\u98C7\u98C4\u9A43\u54C1\u7A1F\u6953\u8AF7\u8C4A\u98A8\u99AE\u5F7C\u62AB\u75B2\u76AE\u88AB\u907F\u9642\u5339\u5F3C\u5FC5\u6CCC\u73CC\u7562\u758B\u7B46\u82FE\u999D\u4E4F\u903C\u4E0B\u4F55\u53A6\u590F\u5EC8\u6630\u6CB3\u7455\u8377\u8766\u8CC0\u9050\u971E\u9C15\u58D1\u5B78\u8650\u8B14\u9DB4\u5BD2\u6068\u608D\u65F1\u6C57\u6F22\u6FA3\u701A\u7F55\u7FF0\u9591\u9592\u9650\u97D3\u5272\u8F44\u51FD\u542B\u54B8\u5563\u558A\u6ABB\u6DB5\u7DD8\u8266\u929C\u9677\u9E79\u5408\u54C8\u76D2\u86E4\u95A4\u95D4\u965C\u4EA2\u4F09\u59EE\u5AE6\u5DF7\u6052\u6297\u676D\u6841\u6C86\u6E2F\u7F38\u809B\u822A\uFA08\uFA09\u9805\u4EA5\u5055\u54B3\u5793\u595A\u5B69\u5BB3\u61C8\u6977\u6D77\u7023\u87F9\u89E3\u8A72\u8AE7\u9082\u99ED\u9AB8\u52BE\u6838\u5016\u5E78\u674F\u8347\u884C\u4EAB\u5411\u56AE\u73E6\u9115\u97FF\u9909\u9957\u9999\u5653\u589F\u865B\u8A31\u61B2\u6AF6\u737B\u8ED2\u6B47\u96AA\u9A57\u5955\u7200\u8D6B\u9769\u4FD4\u5CF4\u5F26\u61F8\u665B\u6CEB\u70AB\u7384\u73B9\u73FE\u7729\u774D\u7D43\u7D62\u7E23\u8237\u8852\uFA0A\u8CE2\u9249\u986F\u5B51\u7A74\u8840\u9801\u5ACC\u4FE0\u5354\u593E\u5CFD\u633E\u6D79\u72F9\u8105\u8107\u83A2\u92CF\u9830\u4EA8\u5144\u5211\u578B\u5F62\u6CC2\u6ECE\u7005\u7050\u70AF\u7192\u73E9\u7469\u834A\u87A2\u8861\u9008\u90A2\u93A3\u99A8\u516E\u5F57\u60E0\u6167\u66B3\u8559\u8E4A\u91AF\u978B\u4E4E\u4E92\u547C\u58D5\u58FA\u597D\u5CB5\u5F27\u6236\u6248\u660A\u6667\u6BEB\u6D69\u6DCF\u6E56\u6EF8\u6F94\u6FE0\u6FE9\u705D\u72D0\u7425\u745A\u74E0\u7693\u795C\u7CCA\u7E1E\u80E1\u82A6\u846B\u84BF\u864E\u865F\u8774\u8B77\u8C6A\u93AC\u9800\u9865\u60D1\u6216\u9177\u5A5A\u660F\u6DF7\u6E3E\u743F\u9B42\u5FFD\u60DA\u7B0F\u54C4\u5F18\u6C5E\u6CD3\u6D2A\u70D8\u7D05\u8679\u8A0C\u9D3B\u5316\u548C\u5B05\u6A3A\u706B\u7575\u798D\u79BE\u82B1\u83EF\u8A71\u8B41\u8CA8\u9774\uFA0B\u64F4\u652B\u78BA\u78BB\u7A6B\u4E38\u559A\u5950\u5BA6\u5E7B\u60A3\u63DB\u6B61\u6665\u6853\u6E19\u7165\u74B0\u7D08\u9084\u9A69\u9C25\u6D3B\u6ED1\u733E\u8C41\u95CA\u51F0\u5E4C\u5FA8\u604D\u60F6\u6130\u614C\u6643\u6644\u69A5\u6CC1\u6E5F\u6EC9\u6F62\u714C\u749C\u7687\u7BC1\u7C27\u8352\u8757\u9051\u968D\u9EC3\u532F\u56DE\u5EFB\u5F8A\u6062\u6094\u61F7\u6666\u6703\u6A9C\u6DEE\u6FAE\u7070\u736A\u7E6A\u81BE\u8334\u86D4\u8AA8\u8CC4\u5283\u7372\u5B96\u6A6B\u9404\u54EE\u5686\u5B5D\u6548\u6585\u66C9\u689F\u6D8D\u6DC6\u723B\u80B4\u9175\u9A4D\u4FAF\u5019\u539A\u540E\u543C\u5589\u55C5\u5E3F\u5F8C\u673D\u7166\u73DD\u9005\u52DB\u52F3\u5864\u58CE\u7104\u718F\u71FB\u85B0\u8A13\u6688\u85A8\u55A7\u6684\u714A\u8431\u5349\u5599\u6BC1\u5F59\u5FBD\u63EE\u6689\u7147\u8AF1\u8F1D\u9EBE\u4F11\u643A\u70CB\u7566\u8667\u6064\u8B4E\u9DF8\u5147\u51F6\u5308\u6D36\u80F8\u9ED1\u6615\u6B23\u7098\u75D5\u5403\u5C79\u7D07\u8A16\u6B20\u6B3D\u6B46\u5438\u6070\u6D3D\u7FD5\u8208\u50D6\u51DE\u559C\u566B\u56CD\u59EC\u5B09\u5E0C\u6199\u6198\u6231\u665E\u66E6\u7199\u71B9\u71BA\u72A7\u79A7\u7A00\u7FB2\u8A70";
-    assert_equals(TextDecoder("iso-2022-kr").decode(new Uint8Array(bytes)), string, "decoded");
-  },
-  "iso-2022-kr"
-);
-
--- a/dom/encoding/test/unit/test_singlebytes.js
+++ b/dom/encoding/test/unit/test_singlebytes.js
@@ -292,29 +292,27 @@ test(
     var expected = "\u306B\u307B\u3093"; // Nihon
     assert_equals(TextDecoder("shift_jis").decode(new Uint8Array(jis)), expected);
   },
   "Shift_JIS Decode"
 );
 
 test(
   function () {
-    var encodings = ["utf-8", "ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "hz-gb-2312", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "iso-2022-kr", "x-user-defined"];
+    var encodings = ["utf-8", "ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "hz-gb-2312", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "x-user-defined"];
 
     encodings.forEach(function (encoding) {
       var string = '', bytes = [];
       for (var i = 0; i < 128; ++i) {
 
         // Encodings that have escape codes in 0x00-0x7F
         if (encoding === "hz-gb-2312" && i === 0x7E)
           continue;
         if (encoding === "iso-2022-jp" && i === 0x1B)
           continue;
-        if (encoding === "iso-2022-kr" && (i === 0x0E || i === 0x0F || i === 0x1B))
-          continue;
 
         string += String.fromCharCode(i);
         bytes.push(i);
       }
       var ascii_encoded = TextEncoder('utf-8').encode(string);
       assert_equals(TextDecoder(encoding).decode(ascii_encoded), string, encoding);
       //assert_array_equals(TextEncoder(encoding).encode(string), bytes, encoding);
     });
@@ -339,17 +337,17 @@ test(
   "Non-fatal errors at EOF"
 );
 
 test(
   function () {
 
     var utf_encodings = ["utf-8", "utf-16le", "utf-16be"];
 
-    var legacy_encodings = ["ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "hz-gb-2312", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "iso-2022-kr", "x-user-defined"];
+    var legacy_encodings = ["ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "hz-gb-2312", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "x-user-defined"];
 
     utf_encodings.forEach(function(encoding) {
       assert_equals(TextDecoder(encoding).encoding, encoding);
       assert_equals(TextEncoder(encoding).encoding, encoding);
     });
 
     legacy_encodings.forEach(function(encoding) {
       assert_equals(TextDecoder(encoding).encoding, encoding);
--- a/dom/encoding/test/unit/xpcshell.ini
+++ b/dom/encoding/test/unit/xpcshell.ini
@@ -3,11 +3,10 @@ head = head.js
 tail =
 
 [test_big5.js]
 [test_euc-jp.js]
 [test_euc-kr.js]
 [test_gbk.js]
 [test_hz-gb-2312.js]
 [test_iso-2022-jp.js]
-[test_iso-2022-kr.js]
 [test_shift_jis.js]
 [test_singlebytes.js]
--- a/dom/indexedDB/test/test_bug937006.html
+++ b/dom/indexedDB/test/test_bug937006.html
@@ -10,27 +10,19 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
 </head>
 <body onload="runTest();">
   <script type="text/javascript;version=1.7">
 
   function runTest() {
-    if (!SpecialPowers.isMainProcess()) {
-      window.runTest = function() {
-        todo(false, "Figure out this test for child processes!");
-        SimpleTest.finish();
-        return;
-      }
-    }
-
     // doing this IDBRequest should not be able to retrieve the filename and
     // line number.
-    //setTimeout(indexedDB.deleteDatabase.bind(indexedDB), 0, 'x');
+    setTimeout(indexedDB.deleteDatabase.bind(indexedDB), 0, 'x');
     setTimeout(function() {
       ok(true, "Still alive");
       SimpleTest.finish();
     }, 10);
   }
 
   </script>
 </body>
--- a/dom/messages/SystemMessagePermissionsChecker.jsm
+++ b/dom/messages/SystemMessagePermissionsChecker.jsm
@@ -69,16 +69,19 @@ this.SystemMessagePermissionsTable = {
   	"push": []
   },
   "push-register": {
   	"push": []
   },
   "sms-delivery-success": {
     "sms": []
   },
+  "sms-read-success": {
+    "sms": []
+  },
   "sms-received": {
     "sms": []
   },
   "sms-sent": {
     "sms": []
   },
   "telephony-new-call": {
     "telephony": []
--- a/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl
@@ -6,17 +6,17 @@
 
 interface nsIDOMEventListener;
 interface nsIDOMMozSmsFilter;
 interface nsIDOMMozSmsSegmentInfo;
 interface nsIDOMDOMCursor;
 interface nsIDOMDOMRequest;
 interface nsIDOMBlob;
 
-[scriptable, builtinclass, uuid(cfcc7067-083f-4e09-91aa-75067a721b70)]
+[scriptable, builtinclass, uuid(a99c3538-a8d6-492f-9ece-f6e92f9c00c5)]
 interface nsIDOMMozMobileMessageManager : nsIDOMEventTarget
 {
   nsIDOMDOMRequest getSegmentInfoForText(in DOMString text);
 
 
   /**
    * Function to send SMS.
    *
@@ -70,9 +70,11 @@ interface nsIDOMMozMobileMessageManager 
 
   [implicit_jscontext] attribute jsval onreceived;
   [implicit_jscontext] attribute jsval onretrieving;
   [implicit_jscontext] attribute jsval onsending;
   [implicit_jscontext] attribute jsval onsent;
   [implicit_jscontext] attribute jsval onfailed;
   [implicit_jscontext] attribute jsval ondeliverysuccess;
   [implicit_jscontext] attribute jsval ondeliveryerror;
+  [implicit_jscontext] attribute jsval onreadsuccess;
+  [implicit_jscontext] attribute jsval onreaderror;
 };
--- a/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
@@ -16,16 +16,19 @@ dictionary MmsAttachment
 };
 
 dictionary MmsDeliveryInfo
 {
   DOMString? receiver;
   DOMString? deliveryStatus;
   jsval      deliveryTimestamp; // Date object; null if not available (e.g.,
                                 // |delivery| = "received" or not yet delivered).
+  DOMString? readStatus;
+  jsval      readTimestamp; // Date object. null if not available (e.g.,
+                            // |delivery| = "received" or not yet read).
 };
 
 [scriptable, builtinclass, uuid(82ca2465-f967-4107-a4da-65b7a15d5dba)]
 interface nsIDOMMozMmsMessage : nsISupports
 {
   /**
    * |type| is always "mms".
    */
--- a/dom/mobilemessage/interfaces/nsIRilMobileMessageDatabaseService.idl
+++ b/dom/mobilemessage/interfaces/nsIRilMobileMessageDatabaseService.idl
@@ -20,40 +20,37 @@ interface nsIRilMobileMessageDatabaseRec
 {
   /**
    * |aMessageRecord| Object: the mobile-message database record
    * |aDomMessage|: the nsIDOMMoz{Mms,Sms}Message. Noted, this value might be null.
    */
   void notify(in nsresult aRv, in jsval aMessageRecord, in nsISupports aDomMessage);
 };
 
-[scriptable, uuid(d5374151-7451-4590-a70e-40c49c1369ce)]
+[scriptable, uuid(a92eba51-e619-4f70-98c5-175a33590582)]
 interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
 {
   /**
    * |aMessage| Object: should contain the following properties for internal use:
    *   - |type| DOMString: "sms" or "mms"
-   *   - |sender| DOMString: the phone number of sender
    *   - |timestamp| Number: the timestamp of received message
-   *   - |iccId| DOMString: the ICC ID of the SIM for receiving message
+   *   - |iccId| DOMString: [optional] the ICC ID of the SIM for receiving
+   *                        message if available.
    *
    *   - If |type| == "sms", we also need:
    *     - |messageClass| DOMString: the message class of received message
    *     - |receiver| DOMString: the phone number of receiver
    *     - |pid| Number: the TP-PID field of the SMS TPDU, default 0.
+   *     - |sender| DOMString: the phone number of sender
    *
    *   - If |type| == "mms", we also need:
    *     - |delivery| DOMString: the delivery state of received message
-   *     - |deliveryStatus| DOMString Array: the delivery status of received message
+   *     - |deliveryStatus| DOMString: the delivery status of received message
    *     - |receivers| DOMString Array: the phone numbers of receivers
    *     - |phoneNumber| DOMString: [optional] my own phone number.
-   *     - |transactionId| DOMString: the transaction ID from MMS PDU header.
-   *
-   * Note: |deliveryStatus| should only contain single string to specify
-   *       the delivery status of MMS message for the phone owner self.
    */
   void saveReceivedMessage(in jsval aMessage,
                 [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aMessage| Object: should contain the following properties for internal use:
    *   - |type| DOMString: "sms" or "mms"
    *   - |sender| DOMString: the phone number of sender
@@ -83,25 +80,34 @@ interface nsIRilMobileMessageDatabaseSer
                                      in DOMString aDelivery,
                                      in DOMString aDeliveryStatus,
                                      in DOMString aEnvelopeId,
                           [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aEnvelopeId| DOMString: the "message-id" specified in the MMS PDU headers.
    * |aReceiver| DOMString: the phone number of receiver (for MMS; can be null).
-   * |aDelivery| DOMString: the new delivery value to update (can be null).
-   * |aDeliveryStatus| DOMString: the new delivery status to update (can be null).
+   * |aDeliveryStatus| DOMString: the new delivery status to be updated (can be null).
    * |aCallback| nsIRilMobileMessageDatabaseCallback: an optional callback.
    */
-  void setMessageDeliveryByEnvelopeId(in DOMString aEnvelopeId,
-                                      in DOMString aReceiver,
-                                      in DOMString aDelivery,
-                                      in DOMString aDeliveryStatus,
-                           [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
+  void setMessageDeliveryStatusByEnvelopeId(in DOMString aEnvelopeId,
+                                            in DOMString aReceiver,
+                                            in DOMString aDeliveryStatus,
+                                 [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
+
+  /**
+   * |aEnvelopeId| DOMString: the "message-id" specified in the MMS PDU headers.
+   * |aReceiver| DOMString: the phone number of receiver (for MMS; can be null).
+   * |aReadStatus| DOMString: the new read status to be updated.
+   * |aCallback| nsIRilMobileMessageDatabaseCallback: an optional callback.
+   */
+  void setMessageReadStatusByEnvelopeId(in DOMString aEnvelopeId,
+                                        in DOMString aReceiver,
+                                        in DOMString aReadStatus,
+                             [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aMessageId| Number: the message's DB record ID.
    * |aCallback| nsIRilMobileMessageDatabaseRecordCallback: a callback which
    *   takes result flag, message record and domMessage as parameters.
    */
   void getMessageRecordById(in long aMessageId,
                             in nsIRilMobileMessageDatabaseRecordCallback aCallback);
--- a/dom/mobilemessage/src/Constants.cpp
+++ b/dom/mobilemessage/src/Constants.cpp
@@ -10,12 +10,14 @@ namespace mobilemessage {
 const char* kSmsReceivedObserverTopic        = "sms-received";
 const char* kSmsRetrievingObserverTopic      = "sms-retrieving";
 const char* kSmsSendingObserverTopic         = "sms-sending";
 const char* kSmsSentObserverTopic            = "sms-sent";
 const char* kSmsFailedObserverTopic          = "sms-failed";
 const char* kSmsDeliverySuccessObserverTopic = "sms-delivery-success";
 const char* kSmsDeliveryErrorObserverTopic   = "sms-delivery-error";
 const char* kSilentSmsReceivedObserverTopic  = "silent-sms-received";
+const char* kSmsReadSuccessObserverTopic     = "sms-read-success";
+const char* kSmsReadErrorObserverTopic       = "sms-read-error";
 
 } // namespace mobilemessage
 } // namespace dom
 } // namespace mozilla
--- a/dom/mobilemessage/src/Constants.h
+++ b/dom/mobilemessage/src/Constants.h
@@ -14,30 +14,37 @@ namespace mobilemessage {
 extern const char* kSmsReceivedObserverTopic;
 extern const char* kSmsRetrievingObserverTopic;
 extern const char* kSmsSendingObserverTopic;
 extern const char* kSmsSentObserverTopic;
 extern const char* kSmsFailedObserverTopic;
 extern const char* kSmsDeliverySuccessObserverTopic;
 extern const char* kSmsDeliveryErrorObserverTopic;
 extern const char* kSilentSmsReceivedObserverTopic;
+extern const char* kSmsReadSuccessObserverTopic;
+extern const char* kSmsReadErrorObserverTopic;
 
 #define DELIVERY_RECEIVED       NS_LITERAL_STRING("received")
 #define DELIVERY_SENDING        NS_LITERAL_STRING("sending")
 #define DELIVERY_SENT           NS_LITERAL_STRING("sent")
 #define DELIVERY_ERROR          NS_LITERAL_STRING("error")
 #define DELIVERY_NOT_DOWNLOADED NS_LITERAL_STRING("not-downloaded")
 
 #define DELIVERY_STATUS_NOT_APPLICABLE NS_LITERAL_STRING("not-applicable")
 #define DELIVERY_STATUS_SUCCESS        NS_LITERAL_STRING("success")
 #define DELIVERY_STATUS_PENDING        NS_LITERAL_STRING("pending")
 #define DELIVERY_STATUS_ERROR          NS_LITERAL_STRING("error")
 #define DELIVERY_STATUS_REJECTED       NS_LITERAL_STRING("rejected")
 #define DELIVERY_STATUS_MANUAL         NS_LITERAL_STRING("manual")
 
+#define READ_STATUS_NOT_APPLICABLE NS_LITERAL_STRING("not-applicable")
+#define READ_STATUS_SUCCESS        NS_LITERAL_STRING("success")
+#define READ_STATUS_PENDING        NS_LITERAL_STRING("pending")
+#define READ_STATUS_ERROR          NS_LITERAL_STRING("error")
+
 #define MESSAGE_CLASS_NORMAL  NS_LITERAL_STRING("normal")
 #define MESSAGE_CLASS_CLASS_0 NS_LITERAL_STRING("class-0")
 #define MESSAGE_CLASS_CLASS_1 NS_LITERAL_STRING("class-1")
 #define MESSAGE_CLASS_CLASS_2 NS_LITERAL_STRING("class-2")
 #define MESSAGE_CLASS_CLASS_3 NS_LITERAL_STRING("class-3")
 
 #define MESSAGE_TYPE_SMS NS_LITERAL_STRING("sms")
 #define MESSAGE_TYPE_MMS NS_LITERAL_STRING("mms")
--- a/dom/mobilemessage/src/MmsMessage.cpp
+++ b/dom/mobilemessage/src/MmsMessage.cpp
@@ -140,16 +140,50 @@ MmsMessage::MmsMessage(const mobilemessa
         dateObj(cx, JS_NewDateObjectMsec(cx, infoData.deliveryTimestamp()));
       if (!dateObj) {
         NS_WARNING("MmsMessage: Unable to create Date for deliveryTimestamp.");
       } else {
         info.deliveryTimestamp = OBJECT_TO_JSVAL(dateObj);
       }
     }
 
+    // Prepare |info.readStatus|.
+    nsString statusReadString;
+    switch(infoData.readStatus()) {
+      case eReadStatus_NotApplicable:
+        statusReadString = READ_STATUS_NOT_APPLICABLE;
+        break;
+      case eReadStatus_Success:
+        statusReadString = READ_STATUS_SUCCESS;
+        break;
+      case eReadStatus_Pending:
+        statusReadString = READ_STATUS_PENDING;
+        break;
+      case eReadStatus_Error:
+        statusReadString = READ_STATUS_ERROR;
+        break;
+      case eReadStatus_EndGuard:
+      default:
+        MOZ_CRASH("We shouldn't get any other read status!");
+    }
+    info.readStatus = statusReadString;
+
+    // Prepare |info.readTimestamp|.
+    info.readTimestamp = JSVAL_NULL;
+    if (infoData.readTimestamp() != 0) {
+      AutoJSContext cx;
+      JS::Rooted<JSObject*>
+        dateObj(cx, JS_NewDateObjectMsec(cx, infoData.readTimestamp()));
+      if (!dateObj) {
+        NS_WARNING("MmsMessage: Unable to create Data for readTimestamp.");
+      } else {
+        info.readTimestamp = OBJECT_TO_JSVAL(dateObj);
+      }
+    }
+
     mDeliveryInfo.AppendElement(info);
   }
 }
 
 /**
  * A helper function to convert the JS value to an integer value for time.
  *
  * @params aCx
@@ -371,16 +405,39 @@ MmsMessage::GetData(ContentParent* aPare
     // Prepare |infoData.deliveryTimestamp|.
     if (info.deliveryTimestamp == JSVAL_NULL) {
       infoData.deliveryTimestamp() = 0;
     } else {
       AutoJSContext cx;
       convertTimeToInt(cx, info.deliveryTimestamp, infoData.deliveryTimestamp());
     }
 
+    // Prepare |infoData.readStatus|.
+    ReadStatus readStatus;
+    if (info.readStatus.Equals(READ_STATUS_NOT_APPLICABLE)) {
+      readStatus = eReadStatus_NotApplicable;
+    } else if (info.readStatus.Equals(READ_STATUS_SUCCESS)) {
+      readStatus = eReadStatus_Success;
+    } else if (info.readStatus.Equals(READ_STATUS_PENDING)) {
+      readStatus = eReadStatus_Pending;
+    } else if (info.readStatus.Equals(READ_STATUS_ERROR)) {
+      readStatus = eReadStatus_Error;
+    } else {
+      return false;
+    }
+    infoData.readStatus() = readStatus;
+
+    // Prepare |infoData.readTimestamp|.
+    if (info.readTimestamp == JSVAL_NULL) {
+      infoData.readTimestamp() = 0;
+    } else {
+      AutoJSContext cx;
+      convertTimeToInt(cx, info.readTimestamp, infoData.readTimestamp());
+    }
+
     aData.deliveryInfo().AppendElement(infoData);
   }
 
   aData.attachments().SetCapacity(mAttachments.Length());
   for (uint32_t i = 0; i < mAttachments.Length(); i++) {
     MmsAttachmentData mma;
     const MmsAttachment &element = mAttachments[i];
     mma.id().Assign(element.id);
@@ -516,16 +573,34 @@ MmsMessage::GetDeliveryInfo(JSContext* a
 
     // Get |info.deliveryTimestamp|.
     if (!JS_DefineProperty(aCx, infoJsObj,
                            "deliveryTimestamp", info.deliveryTimestamp,
                            nullptr, nullptr, JSPROP_ENUMERATE)) {
       return NS_ERROR_FAILURE;
     }
 
+    // Get |info.readStatus|.
+    tmpJsStr = JS_NewUCStringCopyN(aCx,
+                                   info.readStatus.get(),
+                                   info.readStatus.Length());
+    NS_ENSURE_TRUE(tmpJsStr, NS_ERROR_OUT_OF_MEMORY);
+
+    tmpJsVal.setString(tmpJsStr);
+    if (!JS_DefineProperty(aCx, infoJsObj, "readStatus", tmpJsVal,
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    // Get |info.readTimestamp|.
+    if (!JS_DefineProperty(aCx, infoJsObj, "readTimestamp", info.readTimestamp,
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+      return NS_ERROR_FAILURE;
+    }
+
     tmpJsVal = OBJECT_TO_JSVAL(infoJsObj);
     if (!JS_SetElement(aCx, deliveryInfo, i, &tmpJsVal)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   aDeliveryInfo->setObject(*deliveryInfo);
   return NS_OK;
--- a/dom/mobilemessage/src/MobileMessageManager.cpp
+++ b/dom/mobilemessage/src/MobileMessageManager.cpp
@@ -33,16 +33,18 @@
 
 #define RECEIVED_EVENT_NAME         NS_LITERAL_STRING("received")
 #define RETRIEVING_EVENT_NAME       NS_LITERAL_STRING("retrieving")
 #define SENDING_EVENT_NAME          NS_LITERAL_STRING("sending")
 #define SENT_EVENT_NAME             NS_LITERAL_STRING("sent")
 #define FAILED_EVENT_NAME           NS_LITERAL_STRING("failed")
 #define DELIVERY_SUCCESS_EVENT_NAME NS_LITERAL_STRING("deliverysuccess")
 #define DELIVERY_ERROR_EVENT_NAME   NS_LITERAL_STRING("deliveryerror")
+#define READ_SUCCESS_EVENT_NAME     NS_LITERAL_STRING("readsuccess")
+#define READ_ERROR_EVENT_NAME       NS_LITERAL_STRING("readerror")
 
 using namespace mozilla::dom::mobilemessage;
 
 DOMCI_DATA(MozMobileMessageManager, mozilla::dom::MobileMessageManager)
 
 namespace mozilla {
 namespace dom {
 
@@ -57,16 +59,18 @@ NS_IMPL_RELEASE_INHERITED(MobileMessageM
 
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, received)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, retrieving)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, sending)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, sent)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, failed)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, deliverysuccess)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, deliveryerror)
+NS_IMPL_EVENT_HANDLER(MobileMessageManager, readsuccess)
+NS_IMPL_EVENT_HANDLER(MobileMessageManager, readerror)
 
 void
 MobileMessageManager::Init(nsPIDOMWindow *aWindow)
 {
   BindToOwner(aWindow);
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   // GetObserverService() can return null is some situations like shutdown.
@@ -76,16 +80,18 @@ MobileMessageManager::Init(nsPIDOMWindow
 
   obs->AddObserver(this, kSmsReceivedObserverTopic, false);
   obs->AddObserver(this, kSmsRetrievingObserverTopic, false);
   obs->AddObserver(this, kSmsSendingObserverTopic, false);
   obs->AddObserver(this, kSmsSentObserverTopic, false);
   obs->AddObserver(this, kSmsFailedObserverTopic, false);
   obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false);
   obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false);
+  obs->AddObserver(this, kSmsReadSuccessObserverTopic, false);
+  obs->AddObserver(this, kSmsReadErrorObserverTopic, false);
 }
 
 void
 MobileMessageManager::Shutdown()
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   // GetObserverService() can return null is some situations like shutdown.
   if (!obs) {
@@ -94,16 +100,18 @@ MobileMessageManager::Shutdown()
 
   obs->RemoveObserver(this, kSmsReceivedObserverTopic);
   obs->RemoveObserver(this, kSmsRetrievingObserverTopic);
   obs->RemoveObserver(this, kSmsSendingObserverTopic);
   obs->RemoveObserver(this, kSmsSentObserverTopic);
   obs->RemoveObserver(this, kSmsFailedObserverTopic);
   obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic);
   obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic);
+  obs->RemoveObserver(this, kSmsReadSuccessObserverTopic);
+  obs->RemoveObserver(this, kSmsReadErrorObserverTopic);
 }
 
 NS_IMETHODIMP
 MobileMessageManager::GetSegmentInfoForText(const nsAString& aText,
                                             nsIDOMDOMRequest** aRequest)
 {
   nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(smsService, NS_ERROR_FAILURE);
@@ -531,16 +539,24 @@ MobileMessageManager::Observe(nsISupport
   if (!strcmp(aTopic, kSmsDeliverySuccessObserverTopic)) {
     return DispatchTrustedSmsEventToSelf(aTopic, DELIVERY_SUCCESS_EVENT_NAME, aSubject);
   }
 
   if (!strcmp(aTopic, kSmsDeliveryErrorObserverTopic)) {
     return DispatchTrustedSmsEventToSelf(aTopic, DELIVERY_ERROR_EVENT_NAME, aSubject);
   }
 
+  if (!strcmp(aTopic, kSmsReadSuccessObserverTopic)) {
+    return DispatchTrustedSmsEventToSelf(aTopic, READ_SUCCESS_EVENT_NAME, aSubject);
+  }
+
+  if (!strcmp(aTopic, kSmsReadErrorObserverTopic)) {
+    return DispatchTrustedSmsEventToSelf(aTopic, READ_ERROR_EVENT_NAME, aSubject);
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageManager::GetSmscAddress(uint32_t aServiceId, uint8_t aArgc,
                                      nsIDOMDOMRequest** aRequest)
 {
   nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
--- a/dom/mobilemessage/src/Types.h
+++ b/dom/mobilemessage/src/Types.h
@@ -33,16 +33,26 @@ enum DeliveryStatus {
   eDeliveryStatus_Pending,
   eDeliveryStatus_Error,
   eDeliveryStatus_Reject,
   eDeliveryStatus_Manual,
   // This state should stay at the end.
   eDeliveryStatus_EndGuard
 };
 
+// For MmsMessageData.readStatus.
+enum ReadStatus {
+  eReadStatus_NotApplicable = 0,
+  eReadStatus_Success,
+  eReadStatus_Pending,
+  eReadStatus_Error,
+  // This state should stay at the end.
+  eReadStatus_EndGuard
+};
+
 // For {Mms,Sms}FilterData.read.
 enum ReadState {
   eReadState_Unknown = -1,
   eReadState_Unread,
   eReadState_Read,
   // This state should stay at the end.
   eReadState_EndGuard
 };
@@ -88,16 +98,26 @@ struct ParamTraits<mozilla::dom::mobilem
 template <>
 struct ParamTraits<mozilla::dom::mobilemessage::DeliveryStatus>
   : public EnumSerializer<mozilla::dom::mobilemessage::DeliveryStatus,
                           mozilla::dom::mobilemessage::eDeliveryStatus_NotApplicable,
                           mozilla::dom::mobilemessage::eDeliveryStatus_EndGuard>
 {};
 
 /**
+ * Read status serializer.
+ */
+template <>
+struct ParamTraits<mozilla::dom::mobilemessage::ReadStatus>
+  : public EnumSerializer<mozilla::dom::mobilemessage::ReadStatus,
+                          mozilla::dom::mobilemessage::eReadStatus_NotApplicable,
+                          mozilla::dom::mobilemessage::eReadStatus_EndGuard>
+{};
+
+/**
  * Read state serializer.
  */
 template <>
 struct ParamTraits<mozilla::dom::mobilemessage::ReadState>
   : public EnumSerializer<mozilla::dom::mobilemessage::ReadState,
                           mozilla::dom::mobilemessage::eReadState_Unknown,
                           mozilla::dom::mobilemessage::eReadState_EndGuard>
 {};
--- a/dom/mobilemessage/src/gonk/MmsPduHelper.jsm
+++ b/dom/mobilemessage/src/gonk/MmsPduHelper.jsm
@@ -40,16 +40,58 @@ this.translatePduErrorToStatus = functio
 
 function defineLazyRegExp(obj, name, pattern) {
   obj.__defineGetter__(name, function() {
     delete obj[name];
     return obj[name] = new RegExp(pattern);
   });
 }
 
+function RangedValue(name, min, max) {
+  this.name = name;
+  this.min = min;
+  this.max = max;
+}
+RangedValue.prototype = {
+  name: null,
+  min: null,
+  max: null,
+
+  /**
+   * @param data
+   *        A wrapped object containing raw PDU data.
+   *
+   * @return A decoded integer.
+   *
+   * @throws CodeError if decoded value is not in the range [this.min, this.max].
+   */
+  decode: function decode(data) {
+    let value = WSP.Octet.decode(data);
+    if ((value >= this.min) && (value <= this.max)) {
+      return value;
+    }
+
+    throw new WSP.CodeError(this.name + ": invalid value " + value);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An integer value within thr range [this.min, this.max].
+   */
+  encode: function encode(data, value) {
+    if ((value < this.min) || (value > this.max)) {
+      throw new WSP.CodeError(this.name + ": invalid value " + value);
+    }
+
+    WSP.Octet.encode(data, value);
+  },
+};
+
 /**
  * Internal decoding function for boolean values.
  *
  * Boolean-value = Yes | No
  * Yes = <Octet 128>
  * No = <Octet 129>
  */
 this.BooleanValue = {
@@ -333,53 +375,30 @@ this.MmsHeader = {
     }
 
     WSP.ShortInteger.encode(data, entry.number);
     entry.coder.encode(data, header.value);
   },
 };
 
 /**
+ * Cancel-status-value = Cancel Request Successfully received |
+ *                       Cancel Request corrupted
+ *
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.7
+ */
+this.CancelStatusValue = new RangedValue("Cancel-status-value", 128, 129);
+
+/**
  * Content-class-value = text | image-basic| image-rich | video-basic |
  *                       video-rich | megapixel | content-basic | content-rich
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.9
  */
-this.ContentClassValue = {
-  /**
-   * @param data
-   *        A wrapped object containing raw PDU data.
-   *
-   * @return A integer value for each class.
-   *
-   * @throws CodeError if decoded value is not in range 128..135.
-   */
-  decode: function decode(data) {
-    let value = WSP.Octet.decode(data);
-    if ((value >= 128) && (value <= 135)) {
-      return value;
-    }
-
-    throw new WSP.CodeError("Content-class-value: invalid class " + value);
-  },
-
-  /**
-   * @param data
-   *        A wrapped object to store encoded raw data.
-   * @param value
-   *        A numeric content class value to be encoded.
-   */
-  encode: function encode(data, value) {
-    if ((value < 128) || (value > 135)) {
-      throw new WSP.CodeError("Content-class-value: invalid class " + value);
-    }
-
-    WSP.Octet.encode(data, value);
-  },
-};
+this.ContentClassValue = new RangedValue("Content-class-value", 128, 135);
 
 /**
  * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
  *
  *   Content-location-value = Uri-value
  *
  * When used in the M-Mbox-Delete.conf and M-Delete.conf PDU:
  *
@@ -964,50 +983,17 @@ this.MessageClassValue = {
   },
 };
 
  /**
  * Message-type-value = <Octet 128..151>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.30
  */
-this.MessageTypeValue = {
-  /**
-   * @param data
-   *        A wrapped object containing raw PDU data.
-   *
-   * @return A decoded integer.
-   *
-   * @throws CodeError if decoded value is not in the range 128..151.
-   */
-  decode: function decode(data) {
-    let type = WSP.Octet.decode(data);
-    if ((type >= 128) && (type <= 151)) {
-      return type;
-    }
-
-    throw new WSP.CodeError("Message-type-value: invalid type " + type);
-  },
-
-  /**
-   * @param data
-   *        A wrapped object to store encoded raw data.
-   * @param type
-   *        A numeric message type value to be encoded.
-   *
-   * @throws CodeError if the value is not in the range 128..151.
-   */
-  encode: function encode(data, type) {
-    if ((type < 128) || (type > 151)) {
-      throw new WSP.CodeError("Message-type-value: invalid type " + type);
-    }
-
-    WSP.Octet.encode(data, type);
-  },
-};
+this.MessageTypeValue = new RangedValue("Message-type-value", 128, 151);
 
 /**
  * MM-flags-value = Value-length ( Add-token | Remove-token | Filter-token ) Encoded-string-value
  * Add-token = <Octet 128>
  * Remove-token = <Octet 129>
  * Filter-token = <Octet 130>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.32
@@ -1070,91 +1056,34 @@ this.MmFlagsValue = {
  * Draft = <Octet 128>
  * Sent = <Octet 129>
  * New = <Octet 130>
  * Retrieved = <Octet 131>
  * Forwarded = <Octet 132>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.33
  */
-this.MmStateValue = {
-  /**
-   * @param data
-   *        A wrapped object containing raw PDU data.
-   *
-   * @return A decoded integer.
-   *
-   * @throws CodeError if decoded value is not in the range 128..132.
-   */
-  decode: function decode(data) {
-    let state = WSP.Octet.decode(data);
-    if ((state >= 128) && (state <= 132)) {
-      return state;
-    }
-
-    throw new WSP.CodeError("MM-state-value: invalid state " + state);
-  },
-
-  /**
-   * @param data
-   *        A wrapped object to store encoded raw data.
-   * @param state
-   *        A numeric state value to be encoded.
-   *
-   * @throws CodeError if state is not in the range 128..132.
-   */
-  encode: function encode(data, state) {
-    if ((state < 128) || (state > 132)) {
-      throw new WSP.CodeError("MM-state-value: invalid state " + state);
-    }
-
-    WSP.Octet.encode(data, state);
-  },
-};
+this.MmStateValue = new RangedValue("MM-state-value", 128, 132);
 
 /**
  * Priority-value = Low | Normal | High
  * Low = <Octet 128>
  * Normal = <Octet 129>
  * High = <Octet 130>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.35
  */
-this.PriorityValue = {
-  /**
-   * @param data
-   *        A wrapped object containing raw PDU data.
-   *
-   * @return A decoded integer.
-   *
-   * @throws CodeError if decoded value is not in the range 128..130.
-   */
-  decode: function decode(data) {
-    let priority = WSP.Octet.decode(data);
-    if ((priority >= 128) && (priority <= 130)) {
-      return priority;
-    }
+this.PriorityValue = new RangedValue("Priority-value", 128, 130);
 
-    throw new WSP.CodeError("Priority-value: invalid priority " + priority);
-  },
-
-  /**
-   * @param data
-   *        A wrapped object to store encoded raw data.
-   * @param priority
-   *        A numeric priority value to be encoded.
-   */
-  encode: function encode(data, priority) {
-    if ((priority < 128) || (priority > 130)) {
-      throw new WSP.CodeError("Priority-value: invalid priority " + priority);
-    }
-
-    WSP.Octet.encode(data, priority);
-  },
-};
+/**
+ * Read-status-value = Read | Deleted without being read
+ *
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.38
+ */
+this.ReadStatusValue = new RangedValue("Read-status-value", 128, 129);
 
 /**
  * Recommended-Retrieval-Mode-value = Manual
  * Manual = <Octet 128>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.39
  */
 this.RecommendedRetrievalModeValue = {
@@ -1174,48 +1103,17 @@ this.RecommendedRetrievalModeValue = {
  *                        Accepted text only
  * Requested = <Octet 128>
  * Requested text only = <Octet 129>
  * Accepted = <Octet 130>
  * Accepted text only = <Octet 131>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.43
  */
-this.ReplyChargingValue = {
-  /**
-   * @param data
-   *        A wrapped object containing raw PDU data.
-   *
-   * @return A decoded integer.
-   *
-   * @throws CodeError if decoded value is not in the range 128..131.
-   */
-  decode: function decode(data) {
-    let value = WSP.Octet.decode(data);
-    if ((value >= 128) && (value <= 131)) {
-      return value;
-    }
-
-    throw new WSP.CodeError("Reply-charging-value: invalid value " + value);
-  },
-
-  /**
-   * @param data
-   *        A wrapped object to store encoded raw data.
-   * @param value
-   *        An integer value within thr range 128..131.
-   */
-  encode: function encode(data, value) {
-    if ((value < 128) || (value > 131)) {
-      throw new WSP.CodeError("Reply-charging-value: invalid value " + value);
-    }
-
-    WSP.Octet.encode(data, value);
-  },
-};
+this.ReplyChargingValue = new RangedValue("Reply-charging-value", 128, 131);
 
 /**
  * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
  *
  *   Response-text-value = Encoded-string-value
  *
  * When used in the M-Mbox-Delete.conf and M-Delete.conf PDUs:
  *
@@ -1295,63 +1193,37 @@ this.RetrieveStatusValue = {
     // Any other values SHALL NOT be used. They are reserved for future use.
     // An MMS Client that receives such a reserved value MUST react the same
     // as it does to the value 224 (Error-permanent-failure).
     return MMS_PDU_ERROR_PERMANENT_FAILURE;
   },
 };
 
 /**
+ * Sender-visibility-value = Hide | Show
+ *
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.52
+ */
+this.SenderVisibilityValue = new RangedValue("Sender-visibility-value", 128, 129);
+
+/**
  * Status-value = Expired | Retrieved | Rejected | Deferred | Unrecognised |
  *                Indeterminate | Forwarded | Unreachable
  * Expired = <Octet 128>
  * Retrieved = <Octet 129>
  * Rejected = <Octet 130>
  * Deferred = <Octet 131>
  * Unrecognised = <Octet 132>
  * Indeterminate = <Octet 133>
  * Forwarded = <Octet 134>
  * Unreachable = <Octet 135>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.54
  */
-this.StatusValue = {
-  /**
-   * @param data
-   *        A wrapped object containing raw PDU data.
-   *
-   * @return A decoded integer.
-   *
-   * @throws CodeError if decoded value is not in the range 128..135.
-   */
-  decode: function decode(data) {
-    let status = WSP.Octet.decode(data);
-    if ((status >= 128) && (status <= 135)) {
-      return status;
-    }
-
-    throw new WSP.CodeError("Status-value: invalid status " + status);
-  },
-
-  /**
-   * @param data
-   *        A wrapped object to store encoded raw data.
-   * @param value
-   *        A numeric status value to be encoded.
-   *
-   * @throws CodeError if the value is not in the range 128..135.
-   */
-  encode: function encode(data, value) {
-    if ((value < 128) || (value > 135)) {
-      throw new WSP.CodeError("Status-value: invalid status " + value);
-    }
-
-    WSP.Octet.encode(data, value);
-  },
-};
+this.StatusValue = new RangedValue("Status-value", 128, 135);
 
 this.PduHelper = {
   /**
    * @param data
    *        A wrapped object containing raw PDU data.
    * @param headers
    *        An optional object to store parsed header fields. Created
    *        automatically if undefined.
@@ -1627,16 +1499,23 @@ const MMS_PDU_TYPES = (function () {
                                             "x-mms-transaction-id",
                                             "x-mms-mms-version"]);
   add(MMS_PDU_TYPE_READ_REC_IND, false, ["x-mms-message-type",
                                          "message-id",
                                          "x-mms-mms-version",
                                          "to",
                                          "from",
                                          "x-mms-read-status"]);
+  add(MMS_PDU_TYPE_READ_ORIG_IND, false, ["x-mms-message-type",
+                                          "x-mms-mms-version",
+                                          "message-id",
+                                          "to",
+                                          "from",
+                                          "date",
+                                          "x-mms-read-status"]);
 
   return pdus;
 })();
 
 /**
  * Header field names and assigned numbers.
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.4
@@ -1666,24 +1545,24 @@ const MMS_HEADER_FIELDS = (function () {
   add("x-mms-message-type",                      0x0C, MessageTypeValue);
   add("x-mms-mms-version",                       0x0D, WSP.ShortInteger);
   add("x-mms-message-size",                      0x0E, WSP.LongInteger);
   add("x-mms-priority",                          0x0F, PriorityValue);
   add("x-mms-read-report",                       0x10, BooleanValue);
   add("x-mms-report-allowed",                    0x11, BooleanValue);
   add("x-mms-response-status",                   0x12, RetrieveStatusValue);
   add("x-mms-response-text",                     0x13, ResponseText);
-  add("x-mms-sender-visibility",                 0x14, BooleanValue);
+  add("x-mms-sender-visibility",                 0x14, SenderVisibilityValue);
   add("x-mms-status",                            0x15, StatusValue);
   add("subject",                                 0x16, EncodedStringValue);
   add("to",                                      0x17, Address);
   add("x-mms-transaction-id",                    0x18, WSP.TextString);
   add("x-mms-retrieve-status",                   0x19, RetrieveStatusValue);
   add("x-mms-retrieve-text",                     0x1A, EncodedStringValue);
-  add("x-mms-read-status",                       0x1B, BooleanValue);
+  add("x-mms-read-status",                       0x1B, ReadStatusValue);
   add("x-mms-reply-charging",                    0x1C, ReplyChargingValue);
   add("x-mms-reply-charging-deadline",           0x1D, ExpiryValue);
   add("x-mms-reply-charging-id",                 0x1E, WSP.TextString);
   add("x-mms-reply-charging-size",               0x1F, WSP.LongInteger);
   add("x-mms-previously-sent-by",                0x20, PreviouslySentByValue);
   add("x-mms-previously-sent-date",              0x21, PreviouslySentDateValue);
   add("x-mms-store",                             0x22, BooleanValue);
   add("x-mms-mm-state",                          0x23, MmStateValue);
@@ -1709,17 +1588,17 @@ const MMS_HEADER_FIELDS = (function () {
   add("x-mms-applic-id",                         0x37, WSP.TextString);
   add("x-mms-reply-applic-id",                   0x38, WSP.TextString);
   add("x-mms-aux-applic-id",                     0x39, WSP.TextString);
   add("x-mms-content-class",                     0x3A, ContentClassValue);
   add("x-mms-drm-content",                       0x3B, BooleanValue);
   add("x-mms-adaptation-allowed",                0x3C, BooleanValue);
   add("x-mms-replace-id",                        0x3D, WSP.TextString);
   add("x-mms-cancel-id",                         0x3E, WSP.TextString);
-  add("x-mms-cancel-status",                     0x3F, BooleanValue);
+  add("x-mms-cancel-status",                     0x3F, CancelStatusValue);
 
   return names;
 })();
 
 // @see OMA-TS-MMS_ENC-V1_3-20110913-A Table 27: Parameter Name Assignments
 const MMS_WELL_KNOWN_PARAMS = (function () {
   let params = {};
 
@@ -1754,32 +1633,35 @@ this.EXPORTED_SYMBOLS = ALL_CONST_SYMBOL
   // Utility functions
   "translatePduErrorToStatus",
 
   // Decoders
   "BooleanValue",
   "Address",
   "HeaderField",
   "MmsHeader",
+  "CancelStatusValue",
   "ContentClassValue",
   "ContentLocationValue",
   "ElementDescriptorValue",
   "Parameter",
   "EncodedStringValue",
   "ExpiryValue",
   "FromValue",
   "PreviouslySentByValue",
   "PreviouslySentDateValue",
   "MessageClassValue",
   "MessageTypeValue",
   "MmFlagsValue",
   "MmStateValue",
   "PriorityValue",
+  "ReadStatusValue",
   "RecommendedRetrievalModeValue",
   "ReplyChargingValue",
   "ResponseText",
   "RetrieveStatusValue",
+  "SenderVisibilityValue",
   "StatusValue",
 
   // Parser
   "PduHelper",
 ]);
 
--- a/dom/mobilemessage/src/gonk/MmsService.js
+++ b/dom/mobilemessage/src/gonk/MmsService.js
@@ -13,30 +13,35 @@ Cu.import("resource://gre/modules/Servic
 
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
 
 const RIL_MMSSERVICE_CONTRACTID = "@mozilla.org/mms/rilmmsservice;1";
 const RIL_MMSSERVICE_CID = Components.ID("{217ddd76-75db-4210-955d-8806cd8d87f9}");
 
 let DEBUG = false;
+function debug(s) {
+  dump("-@- MmsService: " + s + "\n");
+};
 
 // Read debug setting from pref.
 try {
   let debugPref = Services.prefs.getBoolPref("mms.debugging.enabled");
   DEBUG = DEBUG || debugPref;
 } catch (e) {}
 
 const kSmsSendingObserverTopic           = "sms-sending";
 const kSmsSentObserverTopic              = "sms-sent";
 const kSmsFailedObserverTopic            = "sms-failed";
 const kSmsReceivedObserverTopic          = "sms-received";
 const kSmsRetrievingObserverTopic        = "sms-retrieving";
 const kSmsDeliverySuccessObserverTopic   = "sms-delivery-success";
 const kSmsDeliveryErrorObserverTopic     = "sms-delivery-error";
+const kSmsReadSuccessObserverTopic       = "sms-read-success";
+const kSmsReadErrorObserverTopic         = "sms-read-error";
 
 const NS_XPCOM_SHUTDOWN_OBSERVER_ID      = "xpcom-shutdown";
 const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
 const kMobileMessageDeletedObserverTopic = "mobile-message-deleted";
 
 const kPrefRilRadioDisabled              = "ril.radio.disabled";
 
 // HTTP status codes:
@@ -1349,17 +1354,17 @@ function ReadRecTransaction(mmsConnectio
   headers["x-mms-message-type"] = MMS.MMS_PDU_TYPE_READ_REC_IND;
   headers["x-mms-mms-version"] = MMS.MMS_VERSION;
   headers["message-id"] = messageID;
   let type = MMS.Address.resolveType(toAddress);
   let to = {address: toAddress,
             type: type}
   headers["to"] = to;
   headers["from"] = null;
-  headers["x-mms-read-status"] = true;
+  headers["x-mms-read-status"] = MMS.MMS_PDU_READ_STATUS_READ;
 
   this.istream = MMS.PduHelper.compose(null, {headers: headers});
   if (!this.istream) {
     throw Cr.NS_ERROR_FAILURE;
   }
 }
 ReadRecTransaction.prototype = {
   run: function() {
@@ -1426,48 +1431,43 @@ MmsService.prototype = {
    * @param intermediate
    *        Intermediate MMS message parsed from PDU.
    */
   convertIntermediateToSavable: function convertIntermediateToSavable(mmsConnection,
                                                                       intermediate,
                                                                       retrievalMode) {
     intermediate.type = "mms";
     intermediate.delivery = DELIVERY_NOT_DOWNLOADED;
-    // As a receiver, we don't need to care about the delivery status of others.
-    let deliveryInfo = intermediate.deliveryInfo = [{
-      receiver: mmsConnection.getPhoneNumber(),
-      deliveryStatus: DELIVERY_STATUS_NOT_APPLICABLE }];
 
+    let deliveryStatus;
     switch (retrievalMode) {
       case RETRIEVAL_MODE_MANUAL:
-        deliveryInfo[0].deliveryStatus = DELIVERY_STATUS_MANUAL;
+        deliveryStatus = DELIVERY_STATUS_MANUAL;
         break;
       case RETRIEVAL_MODE_NEVER:
-        deliveryInfo[0].deliveryStatus = DELIVERY_STATUS_REJECTED;
+        deliveryStatus = DELIVERY_STATUS_REJECTED;
         break;
       case RETRIEVAL_MODE_AUTOMATIC:
-        deliveryInfo[0].deliveryStatus = DELIVERY_STATUS_PENDING;
+        deliveryStatus = DELIVERY_STATUS_PENDING;
         break;
       case RETRIEVAL_MODE_AUTOMATIC_HOME:
         if (mmsConnection.isVoiceRoaming()) {
-          deliveryInfo[0].deliveryStatus = DELIVERY_STATUS_MANUAL;
+          deliveryStatus = DELIVERY_STATUS_MANUAL;
         } else {
-          deliveryInfo[0].deliveryStatus = DELIVERY_STATUS_PENDING;
+          deliveryStatus = DELIVERY_STATUS_PENDING;
         }
         break;
+      default:
+        deliveryStatus = DELIVERY_STATUS_NOT_APPLICABLE;
+        break;
     }
+    // |intermediate.deliveryStatus| will be deleted after being stored in db.
+    intermediate.deliveryStatus = deliveryStatus;
 
     intermediate.timestamp = Date.now();
-    intermediate.sender = null;
-    intermediate.transactionId = intermediate.headers["x-mms-transaction-id"];
-    if (intermediate.headers.from) {
-      intermediate.sender = intermediate.headers.from.address;
-    } else {
-      intermediate.sender = "anonymous";
-    }
     intermediate.receivers = [];
     intermediate.phoneNumber = mmsConnection.getPhoneNumber();
     intermediate.iccId = mmsConnection.getIccId();
     return intermediate;
   },
 
   /**
    * Merge the retrieval confirmation into the savable message.
@@ -1480,40 +1480,33 @@ MmsService.prototype = {
    * @param savable
    *        The indexedDB savable MMS message, which is going to be
    *        merged with the extra retrieval confirmation.
    */
   mergeRetrievalConfirmation: function mergeRetrievalConfirmation(mmsConnection,
                                                                   intermediate,
                                                                   savable) {
     savable.timestamp = Date.now();
-    if (intermediate.headers.from) {
-      savable.sender = intermediate.headers.from.address;
-    } else {
-      savable.sender = "anonymous";
-    }
     savable.receivers = [];
     // We don't have Bcc in recevied MMS message.
     for each (let type in ["cc", "to"]) {
       if (intermediate.headers[type]) {
         if (intermediate.headers[type] instanceof Array) {
           for (let index in intermediate.headers[type]) {
             savable.receivers.push(intermediate.headers[type][index].address);
           }
         } else {
           savable.receivers.push(intermediate.headers[type].address);
         }
       }
     }
 
     savable.delivery = DELIVERY_RECEIVED;
-    // As a receiver, we don't need to care about the delivery status of others.
-    savable.deliveryInfo = [{
-      receiver: mmsConnection.getPhoneNumber(),
-      deliveryStatus: DELIVERY_STATUS_SUCCESS }];
+    // |savable.deliveryStatus| will be deleted after being stored in db.
+    savable.deliveryStatus = DELIVERY_STATUS_SUCCESS;
     for (let field in intermediate.headers) {
       savable.headers[field] = intermediate.headers[field];
     }
     if (intermediate.parts) {
       savable.parts = intermediate.parts;
     }
     if (intermediate.content) {
       savable.content = intermediate.content;
@@ -1610,16 +1603,18 @@ MmsService.prototype = {
    */
   retrieveMessageCallback: function retrieveMessageCallback(mmsConnection,
                                                             wish,
                                                             savableMessage,
                                                             mmsStatus,
                                                             retrievedMessage) {
     if (DEBUG) debug("retrievedMessage = " + JSON.stringify(retrievedMessage));
 
+    let transactionId = savableMessage.headers["x-mms-transaction-id"];
+
     // The absence of the field does not indicate any default
     // value. So we go check the same field in the retrieved
     // message instead.
     if (wish == null && retrievedMessage) {
       wish = retrievedMessage.headers["x-mms-delivery-report"];
     }
 
     let reportAllowed = this.getReportAllowed(this.confSendDeliveryReport,
@@ -1649,18 +1644,16 @@ MmsService.prototype = {
         this.broadcastReceivedMessageEvent(domMessage);
       }).bind(this));
       return;
     }
 
     savableMessage = this.mergeRetrievalConfirmation(mmsConnection,
                                                      retrievedMessage,
                                                      savableMessage);
-    let transactionId = savableMessage.headers["x-mms-transaction-id"];
-
     gMobileMessageDatabaseService.saveReceivedMessage(savableMessage,
         (function (rv, domMessage) {
       let success = Components.isSuccessCode(rv);
 
       // Cite 6.2.1 "Transaction Flow" in OMA-TS-MMS_ENC-V1_3-20110913-A:
       // The M-NotifyResp.ind response PDU SHALL provide a message retrieval
       // status code. The status ‘retrieved’ SHALL be used only if the MMS
       // Client has successfully retrieved the MM prior to sending the
@@ -1800,21 +1793,16 @@ MmsService.prototype = {
 
   /**
    * Handle incoming M-Delivery.ind PDU.
    *
    * @param aMsg
    *        The MMS message object.
    */
   handleDeliveryIndication: function handleDeliveryIndication(aMsg) {
-    if (DEBUG) {
-      debug("handleDeliveryIndication: got delivery report" +
-            JSON.stringify(aMsg));
-    }
-
     let headers = aMsg.headers;
     let envelopeId = headers["message-id"];
     let address = headers.to.address;
     let mmsStatus = headers["x-mms-status"];
     if (DEBUG) {
       debug("Start updating the delivery status for envelopeId: " + envelopeId +
             " address: " + address + " mmsStatus: " + mmsStatus);
     }
@@ -1842,21 +1830,18 @@ MmsService.prototype = {
         break;
       default:
         if (DEBUG) debug("Cannot handle this MMS status. Returning.");
         return;
     }
 
     if (DEBUG) debug("Updating the delivery status to: " + deliveryStatus);
     gMobileMessageDatabaseService
-      .setMessageDeliveryByEnvelopeId(envelopeId,
-                                      address,
-                                      null,
-                                      deliveryStatus,
-                                      (function notifySetDeliveryResult(aRv, aDomMessage) {
+      .setMessageDeliveryStatusByEnvelopeId(envelopeId, address, deliveryStatus,
+                                            (function(aRv, aDomMessage) {
       if (DEBUG) debug("Marking the delivery status is done.");
       // TODO bug 832140 handle !Components.isSuccessCode(aRv)
 
       let topic;
       if (mmsStatus === MMS.MMS_PDU_STATUS_RETRIEVED) {
         topic = kSmsDeliverySuccessObserverTopic;
 
         // Broadcasting a 'sms-delivery-success' system message to open apps.
@@ -1869,16 +1854,67 @@ MmsService.prototype = {
       }
 
       // Notifying observers the delivery status is updated.
       Services.obs.notifyObservers(aDomMessage, topic, null);
     }).bind(this));
   },
 
   /**
+   * Handle incoming M-Read-Orig.ind PDU.
+   *
+   * @param aIndication
+   *        The MMS message object.
+   */
+  handleReadOriginateIndication:
+    function handleReadOriginateIndication(aIndication) {
+
+    let headers = aIndication.headers;
+    let envelopeId = headers["message-id"];
+    let address = headers.from.address;
+    let mmsReadStatus = headers["x-mms-read-status"];
+    if (DEBUG) {
+      debug("Start updating the read status for envelopeId: " + envelopeId +
+            ", address: " + address + ", mmsReadStatus: " + mmsReadStatus);
+    }
+
+    // From OMA-TS-MMS_ENC-V1_3-20110913-A subclause 9.4 "X-Mms-Read-Status",
+    // in M-Read-Rec-Orig.ind the X-Mms-Read-Status could be
+    // MMS.MMS_READ_STATUS_{ READ, DELETED_WITHOUT_BEING_READ }.
+    let readStatus = mmsReadStatus == MMS.MMS_PDU_READ_STATUS_READ
+                   ? MMS.DOM_READ_STATUS_SUCCESS
+                   : MMS.DOM_READ_STATUS_ERROR;
+    if (DEBUG) debug("Updating the read status to: " + readStatus);
+
+    gMobileMessageDatabaseService
+      .setMessageReadStatusByEnvelopeId(envelopeId, address, readStatus,
+                                        (function(aRv, aDomMessage) {
+      if (!Components.isSuccessCode(aRv)) {
+        // Notifying observers the read status is error.
+        Services.obs.notifyObservers(aDomMessage, kSmsReadSuccessObserverTopic, null);
+        return;
+      }
+
+      if (DEBUG) debug("Marking the read status is done.");
+      let topic;
+      if (mmsReadStatus == MMS.MMS_PDU_READ_STATUS_READ) {
+        topic = kSmsReadSuccessObserverTopic;
+
+        // Broadcasting a 'sms-read-success' system message to open apps.
+        this.broadcastMmsSystemMessage(topic, aDomMessage);
+      } else {
+        topic = kSmsReadErrorObserverTopic;
+      }
+
+      // Notifying observers the read status is updated.
+      Services.obs.notifyObservers(aDomMessage, topic, null);
+    }).bind(this));
+  },
+
+  /**
    * A utility function to convert the MmsParameters dictionary object
    * to a database-savable message.
    *
    * @param aMmsConnection
    *        The MMS connection.
    * @param aParams
    *        The MmsParameters dictionay object.
    * @param aMessage (output)
@@ -2108,50 +2144,48 @@ MmsService.prototype = {
                           function notifySendingResult(aRv, aDomMessage) {
       if (DEBUG) debug("Saving sending message is done. Start to send.");
 
       // TODO bug 832140 handle !Components.isSuccessCode(aRv)
       Services.obs.notifyObservers(aDomMessage, kSmsSendingObserverTopic, null);
 
       if (errorCode !== Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR) {
         if (DEBUG) debug("Error! The params for sending MMS are invalid.");
-        sendTransactionCb(aDomMessage, errorCode);
+        sendTransactionCb(aDomMessage, errorCode, null);
         return;
       }
 
       // This is the entry point starting to send MMS.
       let sendTransaction;
       try {
         sendTransaction =
           new SendTransaction(mmsConnection, aDomMessage.id, savableMessage,
                               savableMessage["deliveryStatusRequested"]);
       } catch (e) {
         if (DEBUG) debug("Exception: fail to create a SendTransaction instance.");
         sendTransactionCb(aDomMessage,
-                          Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
+                          Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null);
         return;
       }
       sendTransaction.run(function callback(aMmsStatus, aMsg) {
         if (DEBUG) debug("The sending status of sendTransaction.run(): " + aMmsStatus);
         let errorCode;
         if (aMmsStatus == _MMS_ERROR_MESSAGE_DELETED) {
           errorCode = Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR;
         } else if (aMmsStatus == _MMS_ERROR_RADIO_DISABLED) {
           errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
         } else if (aMmsStatus == _MMS_ERROR_NO_SIM_CARD) {
           errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR;
         } else if (aMmsStatus != MMS.MMS_PDU_ERROR_OK) {
           errorCode = Ci.nsIMobileMessageCallback.INTERNAL_ERROR;
         } else {
           errorCode = Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR;
         }
-        let envelopeId = null;
-        if (aMsg) {
-          envelopeId = aMsg.headers ? aMsg.headers["message-id"] : null;
-        }
+        let envelopeId =
+          aMsg && aMsg.headers && aMsg.headers["message-id"] || null;
         sendTransactionCb(aDomMessage, errorCode, envelopeId);
       });
     });
   },
 
   retrieve: function retrieve(aMessageId, aRequest) {
     if (DEBUG) debug("Retrieving message with ID " + aMessageId);
     gMobileMessageDatabaseService.getMessageRecordById(aMessageId,
@@ -2176,17 +2210,18 @@ MmsService.prototype = {
         aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
         return;
       }
       if (DELIVERY_NOT_DOWNLOADED != aMessageRecord.delivery) {
         if (DEBUG) debug("Delivery of message record is not 'not-downloaded'.");
         aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
         return;
       }
-      if (DELIVERY_STATUS_PENDING == aMessageRecord.deliveryStatus) {
+      let deliveryStatus = aMessageRecord.deliveryInfo[0].deliveryStatus;
+      if (DELIVERY_STATUS_PENDING == deliveryStatus) {
         if (DEBUG) debug("Delivery status of message record is 'pending'.");
         aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
         return;
       }
 
       // Cite 6.2 "Multimedia Message Notification" in OMA-TS-MMS_ENC-V1_3-20110913-A:
       // The field has only one format, relative. The recipient client calculates
       // this length of time relative to the time it receives the notification.
@@ -2370,16 +2405,19 @@ MmsService.prototype = {
 
     switch (msg.type) {
       case MMS.MMS_PDU_TYPE_NOTIFICATION_IND:
         this.handleNotificationIndication(options.serviceId, msg);
         break;
       case MMS.MMS_PDU_TYPE_DELIVERY_IND:
         this.handleDeliveryIndication(msg);
         break;
+      case MMS.MMS_PDU_TYPE_READ_ORIG_IND:
+        this.handleReadOriginateIndication(msg);
+        break;
       default:
         if (DEBUG) debug("Unsupported X-MMS-Message-Type: " + msg.type);
         break;
     }
   },
 
   // nsIObserver
 
@@ -2390,17 +2428,8 @@ MmsService.prototype = {
           this.mmsDefaultServiceId = getDefaultServiceId();
         }
         break;
     }
   }
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MmsService]);
-
-let debug;
-if (DEBUG) {
-  debug = function (s) {
-    dump("-@- MmsService: " + s + "\n");
-  };
-} else {
-  debug = function (s) {};
-}
--- a/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js
+++ b/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js
@@ -23,17 +23,17 @@ const RIL_GETMESSAGESCURSOR_CID =
 const RIL_GETTHREADSCURSOR_CID =
   Components.ID("{95ee7c3e-d6f2-4ec4-ade5-0c453c036d35}");
 
 const DEBUG = false;
 const DISABLE_MMS_GROUPING_FOR_RECEIVING = true;
 
 
 const DB_NAME = "sms";
-const DB_VERSION = 19;
+const DB_VERSION = 20;
 const MESSAGE_STORE_NAME = "sms";
 const THREAD_STORE_NAME = "thread";
 const PARTICIPANT_STORE_NAME = "participant";
 const MOST_RECENT_STORE_NAME = "most-recent";
 
 const DELIVERY_SENDING = "sending";
 const DELIVERY_SENT = "sent";
 const DELIVERY_RECEIVED = "received";
@@ -255,16 +255,20 @@ MobileMessageDatabaseService.prototype =
             if (DEBUG) debug("Upgrade to version 18. Add last message subject into threadRecord.");
             self.upgradeSchema17(event.target.transaction, next);
             break;
           case 18:
             if (DEBUG) debug("Upgrade to version 19. Add pid for incoming SMS.");
             self.upgradeSchema18(event.target.transaction, next);
             break;
           case 19:
+            if (DEBUG) debug("Upgrade to version 20. Add readStatus and readTimestamp.");
+            self.upgradeSchema19(event.target.transaction, next);
+            break;
+          case 20:
             // This will need to be moved for each new version
             if (DEBUG) debug("Upgrade finished.");
             break;
           default:
             event.target.transaction.abort();
             callback("Old database version: " + event.oldVersion, null);
             break;
         }
@@ -1176,16 +1180,73 @@ MobileMessageDatabaseService.prototype =
       if (messageRecord.type == "sms") {
         messageRecord.pid = RIL.PDU_PID_DEFAULT;
         cursor.update(messageRecord);
       }
       cursor.continue();
     };
   },
 
+  /**
+   * Add readStatus and readTimestamp.
+   */
+  upgradeSchema19: function upgradeSchema19(transaction, next) {
+    let messageStore = transaction.objectStore(MESSAGE_STORE_NAME);
+    messageStore.openCursor().onsuccess = function(event) {
+      let cursor = event.target.result;
+      if (!cursor) {
+        next();
+        return;
+      }
+
+      let messageRecord = cursor.value;
+      if (messageRecord.type == "sms") {
+        cursor.continue();
+        return;
+      }
+
+      // We can always retrieve transaction id from
+      // |messageRecord.headers["x-mms-transaction-id"]|.
+      if (messageRecord.hasOwnProperty("transactionId")) {
+        delete messageRecord.transactionId;
+      }
+
+      // xpconnect gives "undefined" for an unassigned argument of an interface
+      // method.
+      if (messageRecord.envelopeIdIndex === "undefined") {
+        delete messageRecord.envelopeIdIndex;
+      }
+
+      // Convert some header fields that were originally decoded as BooleanValue
+      // to numeric enums.
+      for (let field of ["x-mms-cancel-status",
+                         "x-mms-sender-visibility",
+                         "x-mms-read-status"]) {
+        let value = messageRecord.headers[field];
+        if (value !== undefined) {
+          messageRecord.headers[field] = value ? 128 : 129;
+        }
+      }
+
+      // For all sent and received MMS messages, we have to add their
+      // |readStatus| and |readTimestamp| attributes in |deliveryInfo| array.
+      let readReportRequested =
+        messageRecord.headers["x-mms-read-report"] || false;
+      for (let element of messageRecord.deliveryInfo) {
+        element.readStatus = readReportRequested
+                           ? MMS.DOM_READ_STATUS_PENDING
+                           : MMS.DOM_READ_STATUS_NOT_APPLICABLE;
+        element.readTimestamp = 0;
+      }
+
+      cursor.update(messageRecord);
+      cursor.continue();
+    };
+  },
+
   matchParsedPhoneNumbers: function matchParsedPhoneNumbers(addr1, parsedAddr1,
                                                             addr2, parsedAddr2) {
     if ((parsedAddr1.internationalNumber &&
          parsedAddr1.internationalNumber === parsedAddr2.internationalNumber) ||
         (parsedAddr1.nationalNumber &&
          parsedAddr1.nationalNumber === parsedAddr2.nationalNumber)) {
       return true;
     }
@@ -1479,42 +1540,76 @@ MobileMessageDatabaseService.prototype =
           debug("findThreadRecordByParticipants: return "
                 + JSON.stringify(threadRecord));
         }
         aCallback(threadRecord, participantIds);
       };
     });
   },
 
+  newTxnWithCallback: function newTxnWithCallback(aCallback, aFunc, aStoreNames) {
+    let self = this;
+    this.newTxn(READ_WRITE, function(aError, aTransaction, aStores) {
+      let notifyResult = function(aRv, aMessageRecord) {
+        if (!aCallback) {
+          return;
+        }
+        let domMessage =
+          aMessageRecord && self.createDomMessageFromRecord(aMessageRecord);
+        aCallback.notify(aRv, domMessage);
+      };
+
+      if (aError) {
+        // TODO bug 832140 check event.target.errorCode
+        notifyResult(Cr.NS_ERROR_FAILURE, null);
+        return;
+      }
+
+      let capture = {};
+      aTransaction.oncomplete = function(event) {
+        notifyResult(Cr.NS_OK, capture.messageRecord);
+      };
+      aTransaction.onabort = function(event) {
+        // TODO bug 832140 check event.target.errorCode
+        notifyResult(Cr.NS_ERROR_FAILURE, null);
+      };
+
+      aFunc(capture, aStores);
+    }, aStoreNames);
+  },
+
   saveRecord: function saveRecord(aMessageRecord, aAddresses, aCallback) {
     if (DEBUG) debug("Going to store " + JSON.stringify(aMessageRecord));
 
     let self = this;
     this.newTxn(READ_WRITE, function(error, txn, stores) {
-      let notifyResult = function(rv) {
-        if (aCallback) {
-          aCallback.notify(rv, self.createDomMessageFromRecord(aMessageRecord));
+      let notifyResult = function(aRv, aMessageRecord) {
+        if (!aCallback) {
+          return;
         }
+        let domMessage =
+          aMessageRecord && self.createDomMessageFromRecord(aMessageRecord);
+        aCallback.notify(aRv, domMessage);
       };
 
       if (error) {
         // TODO bug 832140 check event.target.errorCode
-        notifyResult(Cr.NS_ERROR_FAILURE);
+        notifyResult(Cr.NS_ERROR_FAILURE, null);
         return;
       }
 
       txn.oncomplete = function oncomplete(event) {
         if (aMessageRecord.id > self.lastMessageId) {
           self.lastMessageId = aMessageRecord.id;
         }
-        notifyResult(Cr.NS_OK);
+        notifyResult(Cr.NS_OK, aMessageRecord);
       };
       txn.onabort = function onabort(event) {
         // TODO bug 832140 check event.target.errorCode
-        notifyResult(Cr.NS_ERROR_FAILURE);
+        notifyResult(Cr.NS_ERROR_FAILURE, null);
       };
 
       let messageStore = stores[0];
       let participantStore = stores[1];
       let threadStore = stores[2];
       self.replaceShortMessageOnSave(txn, messageStore, participantStore,
                                      threadStore, aMessageRecord, aAddresses);
     }, [MESSAGE_STORE_NAME, PARTICIPANT_STORE_NAME, THREAD_STORE_NAME]);
@@ -1729,51 +1824,29 @@ MobileMessageDatabaseService.prototype =
       debug("Setting message's delivery by " + type + " = "+ id
             + " receiver: " + receiver
             + " delivery: " + delivery
             + " deliveryStatus: " + deliveryStatus
             + " envelopeId: " + envelopeId);
     }
 
     let self = this;
-    let messageRecord;
-    function notifyResult(rv) {
-      if (!callback) {
-        return;
-      }
-      let domMessage = self.createDomMessageFromRecord(messageRecord);
-      callback.notify(rv, domMessage);
-    }
-
-    this.newTxn(READ_WRITE, function (error, txn, messageStore) {
-      if (error) {
-        // TODO bug 832140 check event.target.errorCode
-        notifyResult(Cr.NS_ERROR_FAILURE);
-        return;
-      }
-      txn.oncomplete = function oncomplete(event) {
-        notifyResult(Cr.NS_OK);
-      };
-      txn.onabort = function onabort(event) {
-        // TODO bug 832140 check event.target.errorCode
-        notifyResult(Cr.NS_ERROR_FAILURE);
-      };
-
+    this.newTxnWithCallback(callback, function(aCapture, aMessageStore) {
       let getRequest;
       if (type === "messageId") {
-        getRequest = messageStore.get(id);
+        getRequest = aMessageStore.get(id);
       } else if (type === "envelopeId") {
-        getRequest = messageStore.index("envelopeId").get(id);
+        getRequest = aMessageStore.index("envelopeId").get(id);
       }
 
       getRequest.onsuccess = function onsuccess(event) {
-        messageRecord = event.target.result;
+        let messageRecord = event.target.result;
         if (!messageRecord) {
           if (DEBUG) debug("type = " + id + " is not found");
-          return;
+          throw Cr.NS_ERROR_FAILURE;
         }
 
         let isRecordUpdated = false;
 
         // Update |messageRecord.delivery| if needed.
         if (delivery && messageRecord.delivery != delivery) {
           messageRecord.delivery = delivery;
           messageRecord.deliveryIndex = [delivery, messageRecord.timestamp];
@@ -1818,28 +1891,29 @@ MobileMessageDatabaseService.prototype =
         // Update |messageRecord.envelopeIdIndex| if needed.
         if (envelopeId) {
           if (messageRecord.envelopeIdIndex != envelopeId) {
             messageRecord.envelopeIdIndex = envelopeId;
             isRecordUpdated = true;
           }
         }
 
+        aCapture.messageRecord = messageRecord;
         if (!isRecordUpdated) {
           if (DEBUG) {
             debug("The values of delivery, deliveryStatus and envelopeId " +
                   "don't need to be updated.");
           }
           return;
         }
 
         if (DEBUG) {
           debug("The delivery, deliveryStatus or envelopeId are updated.");
         }
-        messageStore.put(messageRecord);
+        aMessageStore.put(messageRecord);
       };
     });
   },
 
   fillReceivedMmsThreadParticipants: function fillReceivedMmsThreadParticipants(aMessage, threadParticipants) {
     let receivers = aMessage.receivers;
     // If we don't want to disable the MMS grouping for receiving, we need to
     // add the receivers (excluding the user's own number) to the participants
@@ -1935,65 +2009,75 @@ MobileMessageDatabaseService.prototype =
   },
 
   /**
    * nsIRilMobileMessageDatabaseService API
    */
 
   saveReceivedMessage: function saveReceivedMessage(aMessage, aCallback) {
     if ((aMessage.type != "sms" && aMessage.type != "mms") ||
-        (aMessage.type == "sms" && aMessage.messageClass == undefined) ||
+        (aMessage.type == "sms" && (aMessage.messageClass == undefined ||
+                                    aMessage.sender == undefined)) ||
         (aMessage.type == "mms" && (aMessage.delivery == undefined ||
-                                    aMessage.transactionId == undefined ||
-                                    !Array.isArray(aMessage.deliveryInfo) ||
+                                    aMessage.deliveryStatus == undefined ||
                                     !Array.isArray(aMessage.receivers))) ||
-        aMessage.sender == undefined ||
         aMessage.timestamp == undefined) {
       if (aCallback) {
         aCallback.notify(Cr.NS_ERROR_FAILURE, null);
       }
       return;
     }
-    let threadParticipants = [aMessage.sender];
+
+    let threadParticipants;
     if (aMessage.type == "mms") {
+      if (aMessage.headers.from) {
+        aMessage.sender = aMessage.headers.from.address;
+      } else {
+        aMessage.sender = "anonymous";
+      }
+
+      threadParticipants = [aMessage.sender];
       this.fillReceivedMmsThreadParticipants(aMessage, threadParticipants);
+    } else { // SMS
+      threadParticipants = [aMessage.sender];
     }
 
     let timestamp = aMessage.timestamp;
 
     // Adding needed indexes and extra attributes for internal use.
     // threadIdIndex & participantIdsIndex are filled in saveRecord().
     aMessage.readIndex = [FILTER_READ_UNREAD, timestamp];
     aMessage.read = FILTER_READ_UNREAD;
 
     if (aMessage.type == "mms") {
-      aMessage.transactionIdIndex = aMessage.transactionId;
+      aMessage.transactionIdIndex = aMessage.headers["x-mms-transaction-id"];
       aMessage.isReadReportSent = false;
 
-      // If |deliveryTimestamp| is not specified, use 0 as default.
-      let deliveryInfo = aMessage.deliveryInfo;
-      for (let i = 0; i < deliveryInfo.length; i++) {
-        if (deliveryInfo[i].deliveryTimestamp == undefined) {
-          deliveryInfo[i].deliveryTimestamp = 0;
-        }
-      }
+      // As a receiver, we don't need to care about the delivery status of
+      // others, so we put a single element with self's phone number in the
+      // |deliveryInfo| array.
+      aMessage.deliveryInfo = [{
+        receiver: aMessage.phoneNumber,
+        deliveryStatus: aMessage.deliveryStatus,
+        deliveryTimestamp: 0,
+        readStatus: MMS.DOM_READ_STATUS_NOT_APPLICABLE,
+        readTimestamp: 0,
+      }];
+
+      delete aMessage.deliveryStatus;
     }
 
     if (aMessage.type == "sms") {
       aMessage.delivery = DELIVERY_RECEIVED;
       aMessage.deliveryStatus = DELIVERY_STATUS_SUCCESS;
+      aMessage.deliveryTimestamp = 0;
 
       if (aMessage.pid == undefined) {
         aMessage.pid = RIL.PDU_PID_DEFAULT;
       }
-
-      // If |deliveryTimestamp| is not specified, use 0 as default.
-      if (aMessage.deliveryTimestamp == undefined) {
-        aMessage.deliveryTimestamp = 0;
-      }
     }
     aMessage.deliveryIndex = [aMessage.delivery, timestamp];
 
     this.saveRecord(aMessage, threadParticipants, aCallback);
   },
 
   saveSendingMessage: function saveSendingMessage(aMessage, aCallback) {
     if ((aMessage.type != "sms" && aMessage.type != "mms") ||
@@ -2024,22 +2108,28 @@ MobileMessageDatabaseService.prototype =
         if (DEBUG) {
           debug("Need receivers for MMS. Fail to save the sending message.");
         }
         if (aCallback) {
           aCallback.notify(Cr.NS_ERROR_FAILURE, null);
         }
         return;
       }
+      let readStatus = aMessage.headers["x-mms-read-report"]
+                     ? MMS.DOM_READ_STATUS_PENDING
+                     : MMS.DOM_READ_STATUS_NOT_APPLICABLE;
       aMessage.deliveryInfo = [];
       for (let i = 0; i < receivers.length; i++) {
         aMessage.deliveryInfo.push({
           receiver: receivers[i],
           deliveryStatus: deliveryStatus,
-          deliveryTimestamp: 0 });
+          deliveryTimestamp: 0,
+          readStatus: readStatus,
+          readTimestamp: 0,
+        });
       }
     }
 
     let timestamp = aMessage.timestamp;
 
     // Adding needed indexes and extra attributes for internal use.
     // threadIdIndex & participantIdsIndex are filled in saveRecord().
     aMessage.deliveryIndex = [DELIVERY_SENDING, timestamp];
@@ -2060,22 +2150,72 @@ MobileMessageDatabaseService.prototype =
   setMessageDeliveryByMessageId: function setMessageDeliveryByMessageId(
       messageId, receiver, delivery, deliveryStatus, envelopeId, callback) {
     this.updateMessageDeliveryById(messageId, "messageId",
                                    receiver, delivery, deliveryStatus,
                                    envelopeId, callback);
 
   },
 
-  setMessageDeliveryByEnvelopeId: function setMessageDeliveryByEnvelopeId(
-      envelopeId, receiver, delivery, deliveryStatus, callback) {
-    this.updateMessageDeliveryById(envelopeId, "envelopeId",
-                                   receiver, delivery, deliveryStatus,
-                                   null, callback);
-
+  setMessageDeliveryStatusByEnvelopeId:
+    function setMessageDeliveryStatusByEnvelopeId(aEnvelopeId, aReceiver,
+                                                  aDeliveryStatus, aCallback) {
+    this.updateMessageDeliveryById(aEnvelopeId, "envelopeId", aReceiver, null,
+                                   aDeliveryStatus, null, aCallback);
+  },
+
+  setMessageReadStatusByEnvelopeId:
+    function setMessageReadStatusByEnvelopeId(aEnvelopeId, aReceiver,
+                                              aReadStatus, aCallback) {
+    if (DEBUG) {
+      debug("Setting message's read status by envelopeId = " + aEnvelopeId +
+            ", receiver: " + aReceiver + ", readStatus: " + aReadStatus);
+    }
+
+    let self = this;
+    this.newTxnWithCallback(aCallback, function(aCapture, aMessageStore) {
+      let getRequest = aMessageStore.index("envelopeId").get(aEnvelopeId);
+      getRequest.onsuccess = function onsuccess(event) {
+        let messageRecord = event.target.result;
+        if (!messageRecord) {
+          if (DEBUG) debug("envelopeId '" + aEnvelopeId + "' not found");
+          throw Cr.NS_ERROR_FAILURE;
+        }
+
+        aCapture.messageRecord = messageRecord;
+
+        let isRecordUpdated = false;
+        self.forEachMatchedMmsDeliveryInfo(messageRecord.deliveryInfo,
+                                           aReceiver, function(aEntry) {
+          if (aEntry.readStatus == aReadStatus) {
+            return;
+          }
+
+          aEntry.readStatus = aReadStatus;
+          if (aReadStatus == MMS.DOM_READ_STATUS_SUCCESS) {
+            aEntry.readTimestamp = Date.now();
+          } else {
+            aEntry.readTimestamp = 0;
+          }
+          isRecordUpdated = true;
+        });
+
+        if (!isRecordUpdated) {
+          if (DEBUG) {
+            debug("The values of readStatus don't need to be updated.");
+          }
+          return;
+        }
+
+        if (DEBUG) {
+          debug("The readStatus is updated.");
+        }
+        aMessageStore.put(messageRecord);
+      };
+    });
   },
 
   getMessageRecordByTransactionId: function getMessageRecordByTransactionId(aTransactionId, aCallback) {
     if (DEBUG) debug("Retrieving message with transaction ID " + aTransactionId);
     let self = this;
     this.newTxn(READ_ONLY, function (error, txn, messageStore) {
       if (error) {
         if (DEBUG) debug(error);
--- a/dom/mobilemessage/src/gonk/mms_consts.js
+++ b/dom/mobilemessage/src/gonk/mms_consts.js
@@ -90,22 +90,42 @@ this.MMS_PDU_STATUS_EXPIRED       = 128;
 this.MMS_PDU_STATUS_RETRIEVED     = 129;
 this.MMS_PDU_STATUS_REJECTED      = 130;
 this.MMS_PDU_STATUS_DEFERRED      = 131;
 this.MMS_PDU_STATUS_UNRECOGNISED  = 132;
 this.MMS_PDU_STATUS_INDETERMINATE = 133;
 this.MMS_PDU_STATUS_FORWARDED     = 134;
 this.MMS_PDU_STATUS_UNREACHABLE   = 135;
 
+// X-Mms-Cancel-Status values
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.7
+this.MMS_PDU_CANCEL_STATUS_RECEIVED  = 128;
+this.MMS_PDU_CANCEL_STATUS_CORRUPTED = 129;
+
+// X-Mms-Sender-Visibility
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.52
+this.MMS_PDU_SENDER_VISIBILITY_HIDE = 128;
+this.MMS_PDU_SENDER_VISIBILITY_SHOW = 129;
+
+// X-Mms-Read-Status
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.38
+this.MMS_PDU_READ_STATUS_READ           = 128;
+this.MMS_PDU_READ_STATUS_DELETED_UNREAD = 129;
+
 // Maximum Values of MMS Parameters
 // @see OMA-TS-MMS_CONF-V1_3-20110511-C 10.2.5
 this.MMS_MAX_LENGTH_SUBJECT                = 40;
 this.MMS_MAX_LENGTH_RECIPIENT              = 312;
 this.MMS_MAX_TOTAL_RECIPIENTS              = 20;
 this.MMS_MAX_LENGTH_NAME_CONTENT_TYPE      = 40;
 this.MMS_MAX_LENGTH_MAILBOX_PORTION        = 256;
 
+this.DOM_READ_STATUS_NOT_APPLICABLE = "not-applicable";
+this.DOM_READ_STATUS_SUCCESS        = "success";
+this.DOM_READ_STATUS_PENDING        = "pending";
+this.DOM_READ_STATUS_ERROR          = "error";
+
 this.ALL_CONST_SYMBOLS = undefined; // We want ALL_CONST_SYMBOLS to be exported.
 this.ALL_CONST_SYMBOLS = Object.keys(this);
 
 // Allow this file to be imported via Components.utils.import().
 this.EXPORTED_SYMBOLS = ALL_CONST_SYMBOLS;
 
--- a/dom/mobilemessage/src/ipc/PSms.ipdl
+++ b/dom/mobilemessage/src/ipc/PSms.ipdl
@@ -113,16 +113,20 @@ child:
   NotifyFailedMessage(MobileMessageData aMessageData);
 
   NotifyDeliverySuccessMessage(MobileMessageData aMessageData);
 
   NotifyDeliveryErrorMessage(MobileMessageData aMessageData);
 
   NotifyReceivedSilentMessage(MobileMessageData aMessageData);
 
+  NotifyReadSuccessMessage(MobileMessageData aMessageData);
+
+  NotifyReadErrorMessage(MobileMessageData aMessageData);
+
 parent:
   /**
    * Sent when the child no longer needs to use sms.
    */
   __delete__();
 
   /**
    * Sent when the child makes an asynchronous request to the parent.
--- a/dom/mobilemessage/src/ipc/SmsChild.cpp
+++ b/dom/mobilemessage/src/ipc/SmsChild.cpp
@@ -113,16 +113,30 @@ SmsChild::RecvNotifyDeliveryErrorMessage
 
 bool
 SmsChild::RecvNotifyReceivedSilentMessage(const MobileMessageData& aData)
 {
   NotifyObserversWithMobileMessage(kSilentSmsReceivedObserverTopic, aData);
   return true;
 }
 
+bool
+SmsChild::RecvNotifyReadSuccessMessage(const MobileMessageData& aData)
+{
+  NotifyObserversWithMobileMessage(kSmsReadSuccessObserverTopic, aData);
+  return true;
+}
+
+bool
+SmsChild::RecvNotifyReadErrorMessage(const MobileMessageData& aData)
+{
+  NotifyObserversWithMobileMessage(kSmsReadErrorObserverTopic, aData);
+  return true;
+}
+
 PSmsRequestChild*
 SmsChild::AllocPSmsRequestChild(const IPCSmsRequest& aRequest)
 {
   MOZ_CRASH("Caller is supposed to manually construct a request!");
 }
 
 bool
 SmsChild::DeallocPSmsRequestChild(PSmsRequestChild* aActor)
--- a/dom/mobilemessage/src/ipc/SmsChild.h
+++ b/dom/mobilemessage/src/ipc/SmsChild.h
@@ -53,16 +53,22 @@ protected:
   RecvNotifyDeliverySuccessMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
 
   virtual bool
   RecvNotifyDeliveryErrorMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
 
   virtual bool
   RecvNotifyReceivedSilentMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
 
+  virtual bool
+  RecvNotifyReadSuccessMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
+
+  virtual bool
+  RecvNotifyReadErrorMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
+
   virtual PSmsRequestChild*
   AllocPSmsRequestChild(const IPCSmsRequest& aRequest) MOZ_OVERRIDE;
 
   virtual bool
   DeallocPSmsRequestChild(PSmsRequestChild* aActor) MOZ_OVERRIDE;
 
   virtual PMobileMessageCursorChild*
   AllocPMobileMessageCursorChild(const IPCMobileMessageCursor& aCursor) MOZ_OVERRIDE;
--- a/dom/mobilemessage/src/ipc/SmsParent.cpp
+++ b/dom/mobilemessage/src/ipc/SmsParent.cpp
@@ -148,16 +148,18 @@ SmsParent::SmsParent()
   obs->AddObserver(this, kSmsReceivedObserverTopic, false);
   obs->AddObserver(this, kSmsRetrievingObserverTopic, false);
   obs->AddObserver(this, kSmsSendingObserverTopic, false);
   obs->AddObserver(this, kSmsSentObserverTopic, false);
   obs->AddObserver(this, kSmsFailedObserverTopic, false);
   obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false);
   obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false);
   obs->AddObserver(this, kSilentSmsReceivedObserverTopic, false);
+  obs->AddObserver(this, kSmsReadSuccessObserverTopic, false);
+  obs->AddObserver(this, kSmsReadErrorObserverTopic, false);
 }
 
 void
 SmsParent::ActorDestroy(ActorDestroyReason why)
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     return;
@@ -166,16 +168,18 @@ SmsParent::ActorDestroy(ActorDestroyReas
   obs->RemoveObserver(this, kSmsReceivedObserverTopic);
   obs->RemoveObserver(this, kSmsRetrievingObserverTopic);
   obs->RemoveObserver(this, kSmsSendingObserverTopic);
   obs->RemoveObserver(this, kSmsSentObserverTopic);
   obs->RemoveObserver(this, kSmsFailedObserverTopic);
   obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic);
   obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic);
   obs->RemoveObserver(this, kSilentSmsReceivedObserverTopic);
+  obs->RemoveObserver(this, kSmsReadSuccessObserverTopic);
+  obs->RemoveObserver(this, kSmsReadErrorObserverTopic);
 }
 
 NS_IMETHODIMP
 SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
                    const PRUnichar* aData)
 {
   if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
     MobileMessageData msgData;
@@ -267,16 +271,40 @@ SmsParent::Observe(nsISupports* aSubject
     }
 
     MobileMessageData msgData =
       static_cast<SmsMessage*>(smsMsg.get())->GetData();
     unused << SendNotifyReceivedSilentMessage(msgData);
     return NS_OK;
   }
 
+
+  if (!strcmp(aTopic, kSmsReadSuccessObserverTopic)) {
+    MobileMessageData msgData;
+    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
+      NS_ERROR("Got a 'sms-read-success' topic without a valid message!");
+      return NS_OK;
+    }
+
+    unused << SendNotifyReadSuccessMessage(msgData);
+    return NS_OK;
+  }
+
+  if (!strcmp(aTopic, kSmsReadErrorObserverTopic)) {
+    MobileMessageData msgData;
+    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
+      NS_ERROR("Got a 'sms-read-error' topic without a valid message!");
+      return NS_OK;
+    }
+
+    unused << SendNotifyReadErrorMessage(msgData);
+    return NS_OK;
+  }
+
+
   return NS_OK;
 }
 
 bool
 SmsParent::GetMobileMessageDataFromMessage(nsISupports *aMsg,
                                            MobileMessageData &aData)
 {
   nsCOMPtr<nsIDOMMozMmsMessage> mmsMsg = do_QueryInterface(aMsg);
--- a/dom/mobilemessage/src/ipc/SmsTypes.ipdlh
+++ b/dom/mobilemessage/src/ipc/SmsTypes.ipdlh
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PBlob;
 
 using DeliveryState from "mozilla/dom/mobilemessage/Types.h";
 using DeliveryStatus from "mozilla/dom/mobilemessage/Types.h";
 using MessageClass from "mozilla/dom/mobilemessage/Types.h";
+using ReadStatus from "mozilla/dom/mobilemessage/Types.h";
 using ReadState from "mozilla/dom/mobilemessage/Types.h";
 using MessageType from "mozilla/dom/mobilemessage/Types.h";
 
 namespace mozilla {
 namespace dom {
 namespace mobilemessage {
 
 struct SmsSegmentInfoData
@@ -46,16 +47,18 @@ struct MmsAttachmentData
   PBlob content;
 };
 
 struct MmsDeliveryInfoData
 {
   nsString        receiver;
   DeliveryStatus  deliveryStatus;
   uint64_t        deliveryTimestamp;
+  ReadStatus      readStatus;
+  uint64_t        readTimestamp;
 };
 
 struct MmsMessageData
 {
   int32_t               id;
   uint64_t              threadId;
   nsString              iccId;
   DeliveryState         delivery;
--- a/dom/mobilemessage/tests/test_mms_pdu_helper.js
+++ b/dom/mobilemessage/tests/test_mms_pdu_helper.js
@@ -173,16 +173,48 @@ add_test(function test_MmsHeader_encode(
   wsp_encode_test(MMS.MmsHeader, {name: "X-Mms-Message-Type",
                                   value: MMS_PDU_TYPE_SEND_REQ},
                   [0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ]);
 
   run_next_test();
 });
 
 //
+// Test target: CancelStatusValue
+//
+
+//// CancelStatusValue.decode ////
+
+add_test(function test_CancelStatusValue_decode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 129)) {
+      wsp_decode_test(MMS.CancelStatusValue, [i], i);
+    } else {
+      wsp_decode_test(MMS.CancelStatusValue, [i], null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
+//// CancelStatusValue.encode ////
+
+add_test(function test_CancelStatusValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 129)) {
+      wsp_encode_test(MMS.CancelStatusValue, i, [i]);
+    } else {
+      wsp_encode_test(MMS.CancelStatusValue, i, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
+//
 // Test target: ContentClassValue
 //
 
 //// ContentClassValue.decode ////
 
 add_test(function test_ContentClassValue_decode() {
   for (let i = 0; i < 256; i++) {
     if ((i >= 128) && (i <= 135)) {
@@ -653,16 +685,48 @@ add_test(function test_PriorityValue_enc
       wsp_encode_test(MMS.PriorityValue, i, null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
 //
+// Test target: ReadStatusValue
+//
+
+//// ReadStatusValue.decode ////
+
+add_test(function test_ReadStatusValue_decode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 129)) {
+      wsp_decode_test(MMS.ReadStatusValue, [i], i);
+    } else {
+      wsp_decode_test(MMS.ReadStatusValue, [i], null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
+//// ReadStatusValue.encode ////
+
+add_test(function test_ReadStatusValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 129)) {
+      wsp_encode_test(MMS.ReadStatusValue, i, [i]);
+    } else {
+      wsp_encode_test(MMS.ReadStatusValue, i, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
+//
 // Test target: RecommendedRetrievalModeValue
 //
 
 //// RecommendedRetrievalModeValue.decode ////
 
 add_test(function test_RecommendedRetrievalModeValue_decode() {
   for (let i = 0; i < 256; i++) {
     if (i == 128) {
@@ -761,16 +825,48 @@ add_test(function test_RetrieveStatusVal
                       MMS_PDU_ERROR_PERMANENT_FAILURE);
     }
   }
 
   run_next_test();
 });
 
 //
+// Test target: SenderVisibilityValue
+//
+
+//// SenderVisibilityValue.decode ////
+
+add_test(function test_SenderVisibilityValue_decode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 129)) {
+      wsp_decode_test(MMS.SenderVisibilityValue, [i], i);
+    } else {
+      wsp_decode_test(MMS.SenderVisibilityValue, [i], null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
+//// SenderVisibilityValue.encode ////
+
+add_test(function test_SenderVisibilityValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 129)) {
+      wsp_encode_test(MMS.SenderVisibilityValue, i, [i]);
+    } else {
+      wsp_encode_test(MMS.SenderVisibilityValue, i, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
+//
 // Test target: StatusValue
 //
 
 //// StatusValue.decode ////
 
 add_test(function test_StatusValue_decode() {
   for (let i = 0; i < 256; i++) {
     if ((i >= 128) && (i <= 135)) {
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -193,25 +193,25 @@ var WifiManager = (function() {
   }
 
   function unloadDriver(callback) {
     if (!unloadDriverEnabled) {
       // Unloading drivers is generally unnecessary and
       // can trigger bugs in some drivers.
       // On properly written drivers, bringing the interface
       // down powers down the interface.
+      notify("supplicantlost", { success: true });
       callback(0);
-      notify("supplicantlost", { success: true });
       return;
     }
 
     wifiCommand.unloadDriver(function(status) {
       driverLoaded = (status < 0);
+      notify("supplicantlost", { success: true });
       callback(status);
-      notify("supplicantlost", { success: true });
     });
   }
 
   // A note about background scanning:
   // Normally, background scanning shouldn't be necessary as wpa_supplicant
   // has the capability to automatically schedule its own scans at appropriate
   // intervals. However, with some drivers, this appears to get stuck after
   // three scans, so we enable the driver's background scanning to work around
@@ -414,22 +414,16 @@ var WifiManager = (function() {
     if (handler) {
       if (!eventObject)
         eventObject = ({});
       handler.call(eventObject);
     }
   }
 
   function notifyStateChange(fields) {
-    // Don't handle any state change when and after disabling.
-    if (manager.state === "DISABLING" ||
-        manager.state === "UNINITIALIZED") {
-      return false;
-    }
-
     // If we're already in the COMPLETED state, we might receive events from
     // the supplicant that tell us that we're re-authenticating or reminding
     // us that we're associated to a network. In those cases, we don't need to
     // do anything, so just ignore them.
     if (manager.state === "COMPLETED" &&
         fields.state !== "DISCONNECTED" &&
         fields.state !== "INTERFACE_DISABLED" &&
         fields.state !== "INACTIVE" &&
@@ -441,22 +435,29 @@ var WifiManager = (function() {
     if (manager.backgroundScanEnabled &&
         (fields.state === "ASSOCIATING" ||
          fields.state === "ASSOCIATED" ||
          fields.state === "FOUR_WAY_HANDSHAKE" ||
          fields.state === "GROUP_HANDSHAKE" ||
          fields.state === "COMPLETED")) {
       setBackgroundScan("OFF", function() {});
     }
+
     fields.prevState = manager.state;
-    manager.state = fields.state;
-
     // Detect wpa_supplicant's loop iterations.
     manager.supplicantLoopDetection(fields.prevState, fields.state);
     notify("statechange", fields);
+
+    // Don't update state when and after disabling.
+    if (manager.state === "DISABLING" ||
+        manager.state === "UNINITIALIZED") {
+      return false;
+    }
+
+    manager.state = fields.state;
     return true;
   }
 
   function parseStatus(status) {
     if (status === null) {
       debug("Unable to get wpa supplicant's status");
       return;
     }
--- a/extensions/universalchardet/src/base/LangThaiModel.cpp
+++ b/extensions/universalchardet/src/base/LangThaiModel.cpp
@@ -180,10 +180,10 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
 
 const SequenceModel TIS620ThaiModel = 
 {
   TIS620CharToOrderMap,
   ThaiLangModel,
   (float)0.926386,
   false,
-  "TIS-620"
+  "windows-874"
 };
--- a/extensions/universalchardet/tests/test_bug488426.html
+++ b/extensions/universalchardet/tests/test_bug488426.html
@@ -17,14 +17,14 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">  
 </div>
 <iframe id="testframe"></iframe>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 /** Test for Bug 488426 **/
 CharsetDetectionTests("bug488426_text.html",
-		      "TIS-620",
+		      "windows-874",
 		      new Array("universal_charset_detector"));
 </script>
 </pre>
 </body>
 </html>
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -601,29 +601,42 @@ DrawTargetSkia::Mask(const Pattern &aSou
 
   SkPaint maskPaint;
   SetPaintPattern(maskPaint, aMask);
   
   SkLayerRasterizer *raster = new SkLayerRasterizer();
   raster->addLayer(maskPaint);
   SkSafeUnref(paint.mPaint.setRasterizer(raster));
 
-  // Skia only uses the mask rasterizer when we are drawing a path/rect.
-  // Take our destination bounds and convert them into user space to use
-  // as the path to draw.
-  SkPath path;
-  path.addRect(SkRect::MakeWH(SkScalar(mSize.width), SkScalar(mSize.height)));
- 
-  Matrix temp = mTransform;
-  temp.Invert();
-  SkMatrix mat;
-  GfxMatrixToSkiaMatrix(temp, mat);
-  path.transform(mat);
+  mCanvas->drawRect(SkRectCoveringWholeSurface(), paint.mPaint);
+}
+
+void
+DrawTargetSkia::MaskSurface(const Pattern &aSource,
+                            SourceSurface *aMask,
+                            Point aOffset,
+                            const DrawOptions &aOptions)
+{
+  MarkChanged();
+  AutoPaintSetup paint(mCanvas.get(), aOptions, aSource);
 
-  mCanvas->drawPath(path, paint.mPaint);
+  SkPaint maskPaint;
+  SetPaintPattern(maskPaint, SurfacePattern(aMask, EXTEND_CLAMP));
+
+  SkMatrix transform = maskPaint.getShader()->getLocalMatrix();
+  transform.postTranslate(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y));
+  maskPaint.getShader()->setLocalMatrix(transform);
+
+  SkLayerRasterizer *raster = new SkLayerRasterizer();
+  raster->addLayer(maskPaint);
+  SkSafeUnref(paint.mPaint.setRasterizer(raster));
+
+  IntSize size = aMask->GetSize();
+  Rect rect = Rect(aOffset.x, aOffset.y, size.width, size.height);
+  mCanvas->drawRect(RectToSkRect(rect), paint.mPaint);
 }
 
 TemporaryRef<SourceSurface>
 DrawTargetSkia::CreateSourceSurfaceFromData(unsigned char *aData,
                                             const IntSize &aSize,
                                             int32_t aStride,
                                             SurfaceFormat aFormat) const
 {
@@ -864,16 +877,24 @@ void
 DrawTargetSkia::MarkChanged()
 {
   if (mSnapshot) {
     mSnapshot->DrawTargetWillChange();
     mSnapshot = nullptr;
   }
 }
 
+// Return a rect (in user space) that covers the entire surface by applying
+// the inverse of GetTransform() to (0, 0, mSize.width, mSize.height).
+SkRect
+DrawTargetSkia::SkRectCoveringWholeSurface() const
+{
+  return RectToSkRect(mTransform.TransformBounds(Rect(0, 0, mSize.width, mSize.height)));
+}
+
 void
 DrawTargetSkia::SnapshotDestroyed()
 {
   mSnapshot = nullptr;
 }
 
 }
 }
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -73,17 +73,17 @@ public:
                           const DrawOptions &aOptions = DrawOptions(),
                           const GlyphRenderingOptions *aRenderingOptions = nullptr);
   virtual void Mask(const Pattern &aSource,
                     const Pattern &aMask,
                     const DrawOptions &aOptions = DrawOptions());
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
-                           const DrawOptions &aOptions = DrawOptions()) { MOZ_ASSERT(0); };
+                           const DrawOptions &aOptions = DrawOptions());
   virtual void PushClip(const Path *aPath);
   virtual void PushClipRect(const Rect& aRect);
   virtual void PopClip();
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
                                                             SurfaceFormat aFormat) const;
   virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
@@ -120,16 +120,18 @@ public:
   }
 
 private:
   friend class SourceSurfaceSkia;
   void SnapshotDestroyed();
 
   void MarkChanged();
 
+  SkRect SkRectCoveringWholeSurface() const;
+
 #ifdef USE_SKIA_GPU
   /*
    * These members have inter-dependencies, but do not keep each other alive, so
    * destruction order is very important here: mGrContext uses mGrGLInterface, and
    * through it, uses mGLContext, so it is important that they be declared in the
    * present order.
    */
   RefPtr<GenericRefCountedBase> mGLContext;
--- a/intl/uconv/src/charsetData.properties
+++ b/intl/uconv/src/charsetData.properties
@@ -82,48 +82,51 @@ utf-16be.notForBrowser                  
 
 # charset with isInternal
 x-mac-arabic.notForBrowser              = true
 x-mac-farsi.notForBrowser               = true
 x-mac-hebrew.notForBrowser              = true
 x-imap4-modified-utf7.notForBrowser     = true
 utf-7.notForBrowser                     = true
 ibm864.notForBrowser                    = true
+replacement.notForBrowser               = true
 
 x-mac-arabic.isInternal                 = true
 x-mac-farsi.isInternal                  = true
 x-mac-hebrew.isInternal                 = true
 x-imap4-modified-utf7.isInternal        = true
 utf-7.isInternal                        = true
 t.61-8bit.isInternal                    = true
 ibm864.isInternal                       = true
+replacement.isInternal                  = true
 
 t.61-8bit.notForOutgoing                = true
 utf-7.notForOutgoing                    = true
 x-imap4-modified-utf7.notForOutgoing    = true
 us-ascii.notForOutgoing                 = true
 iso-8859-6-e.notForOutgoing             = true
 iso-8859-6-i.notForOutgoing             = true
 ibm864.notForOutgoing                   = true
 ibm869.notForOutgoing                   = true
 ibm1125.notForOutgoing                  = true
 ibm1131.notForOutgoing                  = true
 iso-8859-8-e.notForOutgoing             = true
 iso-8859-8.notForOutgoing               = true
 iso-2022-kr.notForOutgoing              = true
 x-johab.notForOutgoing                  = true
-
+replacement.notForOutgoing              = true
 
 // XXX : there are some entries only necessary for Gtk/Xlib builds
 // to map  XLFD registry-encoding pairs to langGroups. they can be
 // removed once bug 215537 is fixed.
 
 // XXX : todo: move to something based on BCP 47 (RFC 5646);
 // these should primarily specify script (and sometimes region),
 // but NOT language.
+// See also https://bugzilla.mozilla.org/show_bug.cgi?id=756022
 // e.g. x-western      -> *-Latn-155 (Western Europe)
 //      x-central-euro -> *-Latn-151 (Eastern Europe)
 //      x-baltic       -> *-Latn-154 (Northern Europe)
 //      x-cyrillic     -> *-Cyrl
 //      zh-TW          -> *-Hant-TW
 //      zh-HK          -> *-Hant-HK
 //      zh-CN          -> *-Hans
 //      ja             -> *-Jpan
@@ -189,16 +192,17 @@ iso-8859-11.LangGroup              = th
 us-ascii.LangGroup                 = x-western
 t.61-8bit.LangGroup                = x-western
 utf-8.LangGroup                    = x-unicode
 utf-16.LangGroup                   = x-unicode
 utf-16be.LangGroup                 = x-unicode
 utf-16le.LangGroup                 = x-unicode
 utf-7.LangGroup                    = x-unicode
 x-imap4-modified-utf7.LangGroup    = x-unicode
+replacement.LangGroup              = x-unicode
 viscii.LangGroup                   = x-western
 x-viet-tcvn5712.LangGroup          = x-western
 x-viet-vps.LangGroup               = x-western
 windows-1250.LangGroup             = x-central-euro
 windows-1251.LangGroup             = x-cyrillic
 windows-1252.LangGroup             = x-western
 windows-1253.LangGroup             = el
 windows-1254.LangGroup             = tr
@@ -239,8 +243,9 @@ big5-hkscs.isMultibyte      = true
 x-euc-tw.isMultibyte        = true
 gb2312.isMultibyte          = true
 hz-gb-2312.isMultibyte      = true
 iso-2022-kr.isMultibyte     = true
 euc-kr.isMultibyte          = true
 x-johab.isMultibyte         = true
 utf-7.isMultibyte           = true
 utf-8.isMultibyte           = true
+replacement.isMultibyte     = true
--- a/intl/uconv/src/moz.build
+++ b/intl/uconv/src/moz.build
@@ -6,16 +6,17 @@
 
 UNIFIED_SOURCES += [
     'nsCharsetConverterManager.cpp',
     'nsConverterInputStream.cpp',
     'nsConverterOutputStream.cpp',
     'nsCP1252ToUnicode.cpp',
     'nsISO88591ToUnicode.cpp',
     'nsMacRomanToUnicode.cpp',
+    'nsReplacementToUnicode.cpp',
     'nsScriptableUConv.cpp',
     'nsTextToSubURI.cpp',
     'nsUConvModule.cpp',
     'nsUnicodeToCP1252.cpp',
     'nsUnicodeToISO88591.cpp',
     'nsUnicodeToMacRoman.cpp',
     'nsUnicodeToUTF8.cpp',
     'nsUTF8ConverterService.cpp',
new file mode 100644
--- /dev/null
+++ b/intl/uconv/src/nsReplacementToUnicode.cpp
@@ -0,0 +1,56 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsReplacementToUnicode.h"
+
+nsReplacementToUnicode::nsReplacementToUnicode()
+ : mSeenByte(false)
+{
+}
+
+NS_IMETHODIMP
+nsReplacementToUnicode::Convert(const char* aSrc,
+                                int32_t* aSrcLength,
+                                PRUnichar* aDest,
+                                int32_t* aDestLength)
+{
+  if (mSeenByte || !(*aSrcLength)) {
+    *aDestLength = 0;
+    return NS_PARTIAL_MORE_INPUT;
+  }
+  if (mErrBehavior == kOnError_Signal) {
+    mSeenByte = true;
+    *aSrcLength = 0;
+    *aDestLength = 0;
+    return NS_ERROR_ILLEGAL_INPUT;
+  }
+  if (!(*aDestLength)) {
+    *aSrcLength = -1;
+    return NS_PARTIAL_MORE_OUTPUT;
+  }
+  mSeenByte = true;
+  *aDest = 0xFFFD;
+  *aDestLength = 1;
+  return NS_PARTIAL_MORE_INPUT;
+}
+
+NS_IMETHODIMP
+nsReplacementToUnicode::GetMaxLength(const char* aSrc,
+                          int32_t aSrcLength,
+                          int32_t* aDestLength)
+{
+  if (!mSeenByte && aSrcLength > 0) {
+    *aDestLength = 1;
+  } else {
+    *aDestLength = 0;
+  }
+  return NS_EXACT_LENGTH;
+}
+
+NS_IMETHODIMP
+nsReplacementToUnicode::Reset()
+{
+  mSeenByte = false;
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/intl/uconv/src/nsReplacementToUnicode.h
@@ -0,0 +1,37 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsReplacementToUnicode_h_
+#define nsReplacementToUnicode_h_
+
+#include "nsUCSupport.h"
+
+#define NS_REPLACEMENTTOUNICODE_CID \
+  { 0xd24b24da, 0xc607, 0x489a, \
+    { 0xb5, 0xf0, 0x67, 0x91, 0xf4, 0x45, 0x45, 0x6d } }
+
+#define NS_REPLACEMENTTOUNICODE_CONTRACTID \
+  "@mozilla.org/intl/unicode/decoder;1?charset=replacement"
+
+class nsReplacementToUnicode : public nsBasicDecoderSupport
+{
+public:
+  nsReplacementToUnicode();
+
+  NS_IMETHOD Convert(const char* aSrc,
+                     int32_t* aSrcLength,
+                     PRUnichar* aDest,
+                     int32_t* aDestLength);
+
+  NS_IMETHOD GetMaxLength(const char* aSrc,
+                          int32_t aSrcLength,
+                          int32_t* aDestLength);
+
+  NS_IMETHOD Reset();
+
+private:
+  bool mSeenByte;
+};
+
+#endif // nsReplacementToUnicode_h_
--- a/intl/uconv/src/nsUConvModule.cpp
+++ b/intl/uconv/src/nsUConvModule.cpp
@@ -16,16 +16,17 @@
 #include "nsConverterOutputStream.h"
 #include "nsScriptableUConv.h"
 #include "nsIOutputStream.h"
 #include "nsITextToSubURI.h"
 
 #include "nsISO88591ToUnicode.h"
 #include "nsCP1252ToUnicode.h"
 #include "nsMacRomanToUnicode.h"
+#include "nsReplacementToUnicode.h"
 #include "nsUTF8ToUnicode.h"
 #include "nsUnicodeToISO88591.h"
 #include "nsUnicodeToCP1252.h"
 #include "nsUnicodeToMacRoman.h"
 #include "nsUnicodeToUTF8.h"
 
 // ucvlatin
 #include "nsUCvLatinCID.h"
@@ -214,16 +215,17 @@
 #include "nsISO2022CNToUnicode.h"
 #include "gbku.h"
 
 NS_CONVERTER_REGISTRY_START
 NS_UCONV_REG_UNREG("ISO-8859-1", NS_ISO88591TOUNICODE_CID, NS_UNICODETOISO88591_CID)
 NS_UCONV_REG_UNREG("windows-1252", NS_CP1252TOUNICODE_CID, NS_UNICODETOCP1252_CID)
 NS_UCONV_REG_UNREG("macintosh", NS_MACROMANTOUNICODE_CID, NS_UNICODETOMACROMAN_CID)
 NS_UCONV_REG_UNREG("UTF-8", NS_UTF8TOUNICODE_CID, NS_UNICODETOUTF8_CID)
+NS_UCONV_REG_UNREG("replacement", NS_REPLACEMENTTOUNICODE_CID, NS_UNICODETOUTF8_CID)
 
   // ucvlatin
 NS_UCONV_REG_UNREG("us-ascii", NS_ASCIITOUNICODE_CID, NS_UNICODETOASCII_CID)
 NS_UCONV_REG_UNREG("ISO-8859-2", NS_ISO88592TOUNICODE_CID, NS_UNICODETOISO88592_CID)
 NS_UCONV_REG_UNREG("ISO-8859-3", NS_ISO88593TOUNICODE_CID, NS_UNICODETOISO88593_CID)
 NS_UCONV_REG_UNREG("ISO-8859-4", NS_ISO88594TOUNICODE_CID, NS_UNICODETOISO88594_CID)
 NS_UCONV_REG_UNREG("ISO-8859-5", NS_ISO88595TOUNICODE_CID, NS_UNICODETOISO88595_CID)
 NS_UCONV_REG_UNREG("ISO-8859-6", NS_ISO88596TOUNICODE_CID, NS_UNICODETOISO88596_CID)
@@ -327,16 +329,17 @@ NS_UCONV_REG_UNREG_DECODER("ISO-2022-CN"
 
 { NS_TITLE_BUNDLE_CATEGORY, "chrome://global/locale/charsetTitles.properties", "" },
 { NS_DATA_BUNDLE_CATEGORY, "resource://gre-resources/charsetData.properties", "" },
   
 NS_CONVERTER_REGISTRY_END
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeToUTF8)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF8ToUnicode)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsReplacementToUnicode)
 
 // ucvlatin
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF7ToUnicode)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMUTF7ToUnicode)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF16ToUnicode)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF16BEToUnicode)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF16LEToUnicode)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeToUTF7)
@@ -501,16 +504,17 @@ NS_DEFINE_NAMED_CID(NS_TEXTTOSUBURI_CID)
 NS_DEFINE_NAMED_CID(NS_CONVERTERINPUTSTREAM_CID);
 NS_DEFINE_NAMED_CID(NS_CONVERTEROUTPUTSTREAM_CID);
 NS_DEFINE_NAMED_CID(NS_ISCRIPTABLEUNICODECONVERTER_CID);
 NS_DEFINE_NAMED_CID(NS_UTF8CONVERTERSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88591TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1252TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_MACROMANTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UTF8TOUNICODE_CID);
+NS_DEFINE_NAMED_CID(NS_REPLACEMENTTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88591_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1252_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOMACROMAN_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOUTF8_CID);
 NS_DEFINE_NAMED_CID(NS_ASCIITOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88592TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88593TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88594TOUNICODE_CID);
@@ -685,16 +689,17 @@ static const mozilla::Module::CIDEntry k
   { &kNS_TEXTTOSUBURI_CID, false, nullptr, nsTextToSubURIConstructor },
   { &kNS_CONVERTERINPUTSTREAM_CID, false, nullptr, nsConverterInputStreamConstructor },
   { &kNS_CONVERTEROUTPUTSTREAM_CID, false, nullptr, nsConverterOutputStreamConstructor },
   { &kNS_ISCRIPTABLEUNICODECONVERTER_CID, false, nullptr, nsScriptableUnicodeConverterConstructor },
   { &kNS_UTF8CONVERTERSERVICE_CID, false, nullptr, nsUTF8ConverterServiceConstructor },
   { &kNS_ISO88591TOUNICODE_CID, false, nullptr, nsISO88591ToUnicodeConstructor },
   { &kNS_CP1252TOUNICODE_CID, false, nullptr, nsCP1252ToUnicodeConstructor },
   { &kNS_MACROMANTOUNICODE_CID, false, nullptr, nsMacRomanToUnicodeConstructor },
+  { &kNS_REPLACEMENTTOUNICODE_CID, false, nullptr, nsReplacementToUnicodeConstructor },
   { &kNS_UTF8TOUNICODE_CID, false, nullptr, nsUTF8ToUnicodeConstructor },
   { &kNS_UNICODETOISO88591_CID, false, nullptr, nsUnicodeToISO88591Constructor },
   { &kNS_UNICODETOCP1252_CID, false, nullptr, nsUnicodeToCP1252Constructor },
   { &kNS_UNICODETOMACROMAN_CID, false, nullptr, nsUnicodeToMacRomanConstructor },
   { &kNS_UNICODETOUTF8_CID, false, nullptr, nsUnicodeToUTF8Constructor },
   { &kNS_ASCIITOUNICODE_CID, false, nullptr, nsAsciiToUnicodeConstructor },
   { &kNS_ISO88592TOUNICODE_CID, false, nullptr, nsISO88592ToUnicodeConstructor },
   { &kNS_ISO88593TOUNICODE_CID, false, nullptr, nsISO88593ToUnicodeConstructor },
@@ -872,16 +877,17 @@ static const mozilla::Module::ContractID
   { NS_ITEXTTOSUBURI_CONTRACTID, &kNS_TEXTTOSUBURI_CID },
   { NS_CONVERTERINPUTSTREAM_CONTRACTID, &kNS_CONVERTERINPUTSTREAM_CID },
   { "@mozilla.org/intl/converter-output-stream;1", &kNS_CONVERTEROUTPUTSTREAM_CID },
   { NS_ISCRIPTABLEUNICODECONVERTER_CONTRACTID, &kNS_ISCRIPTABLEUNICODECONVERTER_CID },
   { NS_UTF8CONVERTERSERVICE_CONTRACTID, &kNS_UTF8CONVERTERSERVICE_CID },
   { NS_ISO88591TOUNICODE_CONTRACTID, &kNS_ISO88591TOUNICODE_CID },
   { NS_CP1252TOUNICODE_CONTRACTID, &kNS_CP1252TOUNICODE_CID },
   { NS_MACROMANTOUNICODE_CONTRACTID, &kNS_MACROMANTOUNICODE_CID },
+  { NS_REPLACEMENTTOUNICODE_CONTRACTID, &kNS_REPLACEMENTTOUNICODE_CID },
   { NS_UTF8TOUNICODE_CONTRACTID, &kNS_UTF8TOUNICODE_CID },
   { NS_UNICODETOISO88591_CONTRACTID, &kNS_UNICODETOISO88591_CID },
   { NS_UNICODETOCP1252_CONTRACTID, &kNS_UNICODETOCP1252_CID },
   { NS_UNICODETOMACROMAN_CONTRACTID, &kNS_UNICODETOMACROMAN_CID },
   { NS_UNICODETOUTF8_CONTRACTID, &kNS_UNICODETOUTF8_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "us-ascii", &kNS_ASCIITOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-2", &kNS_ISO88592TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-3", &kNS_ISO88593TOUNICODE_CID },
--- a/intl/uconv/tests/test_long_doc.html
+++ b/intl/uconv/tests/test_long_doc.html
@@ -29,17 +29,20 @@ var ccManager = Cc["@mozilla.org/charset
 
 var decoderList = ccManager.getDecoderList();
 SimpleTest.waitForExplicitFinish();
 while (decoderList.hasMore()) {
     var decoder =  decoderList.getNext();
 
     // Skip UTF-16 variants. (Other non-ASCII compatible encodings will be
     // ignored anyway because of bug 601429
-    if (decoder.substring(0, 6)  == "UTF-16")
+    if (decoder.substring(0, 6)  == "UTF-16" || 
+        decoder == "replacement" ||
+        decoder == "ISO-2022-KR" ||
+        decoder == "ISO-2022-CN")
 	continue;
 
     data = encodeURI(testContent);
     var dataURI = "data:text/html;charset=" + decoder + "," + data;
    
     var testFrame = document.createElement("iframe");
     frameID = decoder;
     testFrame.setAttribute("id", frameID);
--- a/intl/uconv/tests/unit/test_bug718500.js
+++ b/intl/uconv/tests/unit/test_bug718500.js
@@ -94,16 +94,17 @@ var encoderList = [
   "Big5-HKSCS",
   "hkscs-1",
   "EUC-KR",
   "x-johab",
   "GB2312",
   "gbk",
   "HZ-GB-2312",
   "gb18030",
+  "replacement",
 ];
 
 var decoderList = [
   "ISO-8859-1",
   "windows-1252",
   "macintosh",
   "UTF-8",
   "us-ascii",
@@ -178,16 +179,17 @@ var decoderList = [
   "EUC-KR",
   "x-johab",
   "GB2312",
   "gbk",
   "HZ-GB-2312",
   "gb18030",
   "ISO-2022-KR",
   "ISO-2022-CN",
+  "replacement",
 ];
 
 function verifyList(aEnumerator, aList)
 {
   var count = 0;
 
   while (aEnumerator.hasMore()) {
     var result = aEnumerator.getNext();
--- a/js/src/builtin/ParallelArray.cpp
+++ b/js/src/builtin/ParallelArray.cpp
@@ -38,16 +38,21 @@ const JSFunctionSpec ParallelArrayObject
     // TI to track the dimensionality of the receiver and (2) using a
     // hint to aggressively inline calls to get().
     // JS_SELF_HOSTED_FN("get", "ParallelArrayGet", 1, 0),
 
     JS_SELF_HOSTED_FN("toString",  "ParallelArrayToString",  0, 0),
     JS_FS_END
 };
 
+const JSPropertySpec ParallelArrayObject::properties[] = {
+    JS_SELF_HOSTED_GET("length", "ParallelArrayLength", JSPROP_PERMANENT),
+    JS_PS_END
+};
+
 const Class ParallelArrayObject::protoClass = {
     "ParallelArray",
     JSCLASS_HAS_CACHED_PROTO(JSProto_ParallelArray),
     JS_PropertyStub,         // addProperty
     JS_DeletePropertyStub,   // delProperty
     JS_PropertyStub,         // getProperty
     JS_StrictPropertyStub,   // setProperty
     JS_EnumerateStub,
@@ -215,47 +220,22 @@ ParallelArrayObject::initClass(JSContext
     if (!proto)
         return nullptr;
 
     JSProtoKey key = JSProto_ParallelArray;
     RootedFunction ctor(cx, global->createConstructor(cx, construct,
                                                       cx->names().ParallelArray, 0));
     if (!ctor ||
         !LinkConstructorAndPrototype(cx, ctor, proto) ||
-        !DefinePropertiesAndBrand(cx, proto, nullptr, methods) ||
+        !DefinePropertiesAndBrand(cx, proto, properties, methods) ||
         !DefineConstructorAndPrototype(cx, global, key, ctor, proto))
     {
         return nullptr;
     }
 
-    // Define the length getter.
-    {
-        const char lengthStr[] = "ParallelArrayLength";
-        JSAtom *atom = Atomize(cx, lengthStr, strlen(lengthStr));
-        if (!atom)
-            return nullptr;
-        Rooted<PropertyName *> lengthProp(cx, atom->asPropertyName());
-        RootedValue lengthValue(cx);
-        if (!cx->global()->getIntrinsicValue(cx, lengthProp, &lengthValue))
-            return nullptr;
-        RootedObject lengthGetter(cx, &lengthValue.toObject());
-        if (!lengthGetter)
-            return nullptr;
-
-        RootedId lengthId(cx, AtomToId(cx->names().length));
-        unsigned flags = JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_GETTER;
-        RootedValue value(cx, UndefinedValue());
-        if (!DefineNativeProperty(cx, proto, lengthId, value,
-                                  JS_DATA_TO_FUNC_PTR(PropertyOp, lengthGetter.get()), nullptr,
-                                  flags, 0, 0))
-        {
-            return nullptr;
-        }
-    }
-
     return proto;
 }
 
 bool
 ParallelArrayObject::is(const Value &v)
 {
     return v.isObject() && v.toObject().hasClass(&class_);
 }
--- a/js/src/builtin/ParallelArray.h
+++ b/js/src/builtin/ParallelArray.h
@@ -10,16 +10,17 @@
 #include "jsobj.h"
 
 namespace js {
 
 class ParallelArrayObject : public JSObject
 {
     static const Class protoClass;
     static const JSFunctionSpec methods[];
+    static const JSPropertySpec properties[];
     static const uint32_t NumFixedSlots = 4;
     static const uint32_t NumCtors = 4;
     static FixedHeapPtr<PropertyName> ctorNames[NumCtors];
 
     static bool initProps(JSContext *cx, HandleObject obj);
 
   public:
     static const Class class_;
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -867,17 +867,17 @@ ArrayType::create(JSContext *cx,
                                cx->names().prototype,
                                &prototypeVal))
     {
         return nullptr;
     }
     JS_ASSERT(prototypeVal.isObject()); // immutable binding
 
     RootedObject obj(
-        cx, NewObjectWithClassProto(cx, &ArrayType::class_,
+        cx, NewObjectWithGivenProto(cx, &ArrayType::class_,
                                     &prototypeVal.toObject(), cx->global()));
     if (!obj)
         return nullptr;
     obj->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, ObjectValue(*typeReprObj));
 
     RootedValue elementTypeVal(cx, ObjectValue(*elementType));
     if (!JSObject::defineProperty(cx, obj, cx->names().elementType,
                                   elementTypeVal, nullptr, nullptr,
@@ -1140,17 +1140,17 @@ StructType::create(JSContext *cx, Handle
     RootedValue prototypeVal(cx);
     if (!JSObject::getProperty(cx, metaTypeObject, metaTypeObject,
                                cx->names().prototype,
                                &prototypeVal))
         return nullptr;
     JS_ASSERT(prototypeVal.isObject()); // immutable binding
 
     RootedObject obj(
-        cx, NewObjectWithClassProto(cx, &StructType::class_,
+        cx, NewObjectWithGivenProto(cx, &StructType::class_,
                                     &prototypeVal.toObject(), cx->global()));
     if (!obj)
         return nullptr;
 
     if (!StructType::layout(cx, obj, fields))
         return nullptr;
 
     RootedObject fieldsProto(cx);
@@ -1244,25 +1244,25 @@ StructType::construct(JSContext *cx, uns
  *        StructType.prototype.prototype -__proto__->
  *          Objcet.prototype
  */
 
 // Here `T` is either `ScalarType` or `ReferenceType`
 template<typename T>
 static bool
 DefineSimpleTypeObject(JSContext *cx,
-                       HandleObject global,
+                       Handle<GlobalObject *> global,
                        HandleObject module,
                        typename T::TypeRepr::Type type,
                        HandlePropertyName className)
 {
-    RootedObject funcProto(cx, JS_GetFunctionPrototype(cx, global));
+    RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
     JS_ASSERT(funcProto);
 
-    RootedObject numFun(cx, NewObjectWithClassProto(cx, &T::class_, funcProto, global));
+    RootedObject numFun(cx, NewObjectWithGivenProto(cx, &T::class_, funcProto, global));
     if (!numFun)
         return false;
 
     RootedObject typeReprObj(cx, T::TypeRepr::Create(cx, type));
     if (!typeReprObj)
         return false;
 
     numFun->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR,
@@ -1516,17 +1516,17 @@ js_InitTypedObjectClass(JSContext *cx, H
 
     JS_ASSERT(obj->is<GlobalObject>());
     Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
 
     RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
     if (!objProto)
         return nullptr;
 
-    RootedObject module(cx, NewObjectWithClassProto(cx, &JSObject::class_,
+    RootedObject module(cx, NewObjectWithGivenProto(cx, &JSObject::class_,
                                                     objProto, global));
     if (!module)
         return nullptr;
 
     if (!JS_DefineFunctions(cx, module, TypedObjectMethods))
         return nullptr;
 
     // Define TypedObject global.
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -2911,36 +2911,49 @@ MOZ_ARG_WITH_STRING(nspr-cflags,
     NSPR_CFLAGS=$withval)
 MOZ_ARG_WITH_STRING(nspr-libs,
 [  --with-nspr-libs=LIBS   Pass LIBS to LD when linking code that uses NSPR.
                           See --with-nspr-cflags for more details.],
     NSPR_LIBS=$withval)
 AC_SUBST(NSPR_CFLAGS)
 AC_SUBST(NSPR_LIBS)
 
+JS_THREADSAFE=1
+MOZ_ARG_DISABLE_BOOL(threadsafe,
+[  --disable-threadsafe    Disable support for multiple threads.],
+    JS_THREADSAFE= ,
+    JS_THREADSAFE=1 )
+if test -n "$JS_THREADSAFE"; then
+    AC_DEFINE(JS_THREADSAFE)
+fi
+
 if test "$_USE_SYSTEM_NSPR" || (test "$NSPR_CFLAGS" -o "$NSPR_LIBS"); then
   _HAS_NSPR=1
 fi
 
 case "$target" in
   *linux*|*darwin*|*dragonfly*|*freebsd*|*netbsd*|*openbsd*)
-    if test -z "$_HAS_NSPR"; then JS_POSIX_NSPR_DEFAULT=1; fi
+    if test -z "$_HAS_NSPR" && test "$JS_THREADSAFE"; then
+      JS_POSIX_NSPR_DEFAULT=1
+    fi
     ;;
 esac
 
 MOZ_ARG_ENABLE_BOOL(posix-nspr-emulation,
 [  --enable-posix-nspr-emulation
                           Enable emulation of NSPR for POSIX systems],
     JS_POSIX_NSPR=1,
     JS_POSIX_NSPR=,
     JS_POSIX_NSPR="$JS_POSIX_NSPR_DEFAULT" )
 if test -n "$JS_POSIX_NSPR"; then
     AC_DEFINE(JS_POSIX_NSPR)
 fi
 
+AC_SUBST(JS_POSIX_NSPR)
+
 dnl Pass either --with-system-nspr or (--with-nspr-cflags and
 dnl --with-nspr-libs), but not both.
 if test "$_USE_SYSTEM_NSPR" && (test "$NSPR_CFLAGS" -o "$NSPR_LIBS"); then
     AC_MSG_ERROR([--with-system-nspr and --with-nspr-libs/cflags are mutually exclusive.
 See 'configure --help'.])
 fi
 
 dnl Can't use --enable-posix-nspr-emulation if compiling with NSPR.
@@ -4103,25 +4116,16 @@ dnl ====================================
 
 if test "$OS_ARCH" = "Darwin"; then
   AC_DEFINE(XP_MACOSX)
   AC_DEFINE(XP_UNIX)
 elif test "$OS_ARCH" != "WINNT" -a "$OS_ARCH" != "OS2"; then
   AC_DEFINE(XP_UNIX)
 fi
 
-JS_THREADSAFE=1
-MOZ_ARG_DISABLE_BOOL(threadsafe,
-[  --disable-threadsafe    Disable support for multiple threads.],
-    JS_THREADSAFE= ,
-    JS_THREADSAFE=1 )
-if test -n "$JS_THREADSAFE"; then
-    AC_DEFINE(JS_THREADSAFE)
-fi
-
 if test "$MOZ_DEBUG"; then
     AC_DEFINE(MOZ_REFLOW_PERF)
     AC_DEFINE(MOZ_REFLOW_PERF_DSP)
 fi
 
 if test "$ACCESSIBILITY" -a "$MOZ_ENABLE_GTK" ; then
     AC_DEFINE(MOZ_ACCESSIBILITY_ATK)
     ATK_FULL_VERSION=`$PKG_CONFIG --modversion atk`
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3237,16 +3237,25 @@ JS_DefineProperties(JSContext *cx, JSObj
 {
     RootedObject obj(cx, objArg);
     bool ok;
     for (ok = true; ps->name; ps++) {
         if (ps->selfHostedGetter) {
             // If you have self-hosted getter/setter, you can't have a
             // native one.
             JS_ASSERT(!ps->getter.op && !ps->setter.op);
+            /*
+             * During creation of the self-hosting global, we ignore all
+             * self-hosted properties, as that means we're currently setting up
+             * the global object that the self-hosted code is then compiled
+             * in. That means that Self-hosted properties can't be used in the
+             * self-hosting global itself, right now.
+             */
+            if (cx->runtime()->isSelfHostingGlobal(cx->global()))
+                continue;
 
             ok = DefineSelfHostedProperty(cx, obj, ps->name,
                                           ps->selfHostedGetter,
                                           ps->selfHostedSetter,
                                           ps->flags, Shape::HAS_SHORTID,
                                           ps->tinyid);
         } else {
             // If you do not have a self-hosted getter, you should
@@ -4141,25 +4150,25 @@ JS_DefineFunctions(JSContext *cx, JSObje
 
         /*
          * Delay cloning self-hosted functions until they are called. This is
          * achieved by passing DefineFunction a nullptr JSNative which
          * produces an interpreted JSFunction where !hasScript. Interpreted
          * call paths then call InitializeLazyFunctionScript if !hasScript.
          */
         if (fs->selfHostedName) {
+            JS_ASSERT(!fs->call.op);
+            JS_ASSERT(!fs->call.info);
             /*
              * During creation of the self-hosting global, we ignore all
              * self-hosted functions, as that means we're currently setting up
              * the global object that the self-hosted code is then compiled
              * in. Self-hosted functions can access each other via their names,
              * but not via the builtin classes they get installed into.
              */
-            JS_ASSERT(!fs->call.op);
-            JS_ASSERT(!fs->call.info);
             if (cx->runtime()->isSelfHostingGlobal(cx->global()))
                 continue;
 
             RootedAtom shName(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
             if (!shName)
                 return false;
             RootedValue funVal(cx);
             if (!cx->global()->getSelfHostedFunction(cx, shName, atom, fs->nargs, &funVal))
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -1470,17 +1470,20 @@ static const JSFunctionSpec math_static_
     JS_FN("sign",           math_sign,            1, 0),
     JS_FN("cbrt",           math_cbrt,            1, 0),
     JS_FS_END
 };
 
 JSObject *
 js_InitMathClass(JSContext *cx, HandleObject obj)
 {
-    RootedObject Math(cx, NewObjectWithClassProto(cx, &MathClass, nullptr, obj, SingletonObject));
+    RootedObject proto(cx, obj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
+    if (!proto)
+        return nullptr;
+    RootedObject Math(cx, NewObjectWithGivenProto(cx, &MathClass, proto, obj, SingletonObject));
     if (!Math)
         return nullptr;
 
     if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math),
                            JS_PropertyStub, JS_StrictPropertyStub, 0)) {
         return nullptr;
     }
 
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -868,18 +868,18 @@ js_InitJSONClass(JSContext *cx, HandleOb
     /*
      * JSON requires that Boolean.prototype.valueOf be created and stashed in a
      * reserved slot on the global object; see js::BooleanGetPrimitiveValueSlow
      * called from PreprocessValue above.
      */
     if (!global->getOrCreateBooleanPrototype(cx))
         return nullptr;
 
-    RootedObject JSON(cx, NewObjectWithClassProto(cx, &JSONClass, nullptr,
-                                                  global, SingletonObject));
+    RootedObject proto(cx, obj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
+    RootedObject JSON(cx, NewObjectWithClassProto(cx, &JSONClass, proto, global, SingletonObject));
     if (!JSON)
         return nullptr;
 
     if (!JS_DefineProperty(cx, global, js_JSON_str, OBJECT_TO_JSVAL(JSON),
                            JS_PropertyStub, JS_StrictPropertyStub, 0))
         return nullptr;
 
     if (!JS_DefineFunctions(cx, JSON, json_static_methods))
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -3308,17 +3308,20 @@ JS_PUBLIC_API(JSObject *)
 JS_InitReflect(JSContext *cx, JSObject *objArg)
 {
     static const JSFunctionSpec static_methods[] = {
         JS_FN("parse", reflect_parse, 1, 0),
         JS_FS_END
     };
 
     RootedObject obj(cx, objArg);
-    RootedObject Reflect(cx, NewObjectWithClassProto(cx, &JSObject::class_, nullptr,
+    RootedObject proto(cx, obj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
+    if (!proto)
+        return nullptr;
+    RootedObject Reflect(cx, NewObjectWithGivenProto(cx, &JSObject::class_, proto,
                                                      obj, SingletonObject));
     if (!Reflect)
         return nullptr;
 
     if (!JS_DefineProperty(cx, obj, "Reflect", OBJECT_TO_JSVAL(Reflect),
                            JS_PropertyStub, JS_StrictPropertyStub, 0)) {
         return nullptr;
     }
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -165,17 +165,16 @@ UNIFIED_SOURCES += [
     'vm/ForkJoin.cpp',
     'vm/GlobalObject.cpp',
     'vm/Id.cpp',
     'vm/Interpreter.cpp',
     'vm/MemoryMetrics.cpp',
     'vm/Monitor.cpp',
     'vm/ObjectImpl.cpp',
     'vm/OldDebugAPI.cpp',
-    'vm/PosixNSPR.cpp',
     'vm/Probes.cpp',
     'vm/PropertyKey.cpp',
     'vm/ProxyObject.cpp',
     'vm/RegExpObject.cpp',
     'vm/RegExpStatics.cpp',
     'vm/Runtime.cpp',
     'vm/ScopeObject.cpp',
     'vm/SelfHosting.cpp',
@@ -201,16 +200,21 @@ UNIFIED_SOURCES += [
 # from <stdlib.h> on Windows through a preprocessor define.
 # jsutil.cpp cannot be built in unified mode because it is needed for
 # check-vanilla-allocations.
 SOURCES += [
     'jsmath.cpp',
     'jsutil.cpp',
 ]
 
+if CONFIG['JS_POSIX_NSPR']:
+    UNIFIED_SOURCES += [
+        'vm/PosixNSPR.cpp',
+    ]
+
 if CONFIG['MOZ_INSTRUMENTS']:
     SOURCES += [
         'devtools/Instruments.cpp',
     ]
 
 if CONFIG['ENABLE_TRACE_LOGGING']:
     SOURCES += [
         'TraceLogging.cpp',
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -382,17 +382,21 @@ GlobalObject::initFunctionAndObjectClass
     if (!JSObject::preventExtensions(cx, throwTypeError))
         return nullptr;
     self->setThrowTypeError(throwTypeError);
 
     RootedObject intrinsicsHolder(cx);
     if (cx->runtime()->isSelfHostingGlobal(self)) {
         intrinsicsHolder = self;
     } else {
-        intrinsicsHolder = NewObjectWithClassProto(cx, &JSObject::class_, nullptr, self, TenuredObject);
+        RootedObject proto(cx, self->getOrCreateObjectPrototype(cx));
+        if (!proto)
+            return nullptr;
+        intrinsicsHolder = NewObjectWithGivenProto(cx, &JSObject::class_, proto, self,
+                                                   TenuredObject);
         if (!intrinsicsHolder)
             return nullptr;
     }
     self->setIntrinsicsHolder(intrinsicsHolder);
     /* Define a property 'global' with the current global as its value. */
     RootedValue global(cx, ObjectValue(*self));
     if (!JSObject::defineProperty(cx, intrinsicsHolder, cx->names().global,
                                   global, JS_PropertyStub, JS_StrictPropertyStub,
@@ -479,16 +483,19 @@ GlobalObject::initStandardClasses(JSCont
            js_InitProxyClass(cx, global) &&
            js_InitMapClass(cx, global) &&
            GlobalObject::initMapIteratorProto(cx, global) &&
            js_InitSetClass(cx, global) &&
            GlobalObject::initSetIteratorProto(cx, global) &&
 #if EXPOSE_INTL_API
            js_InitIntlClass(cx, global) &&
 #endif
+#if ENABLE_PARALLEL_JS
+           js_InitParallelArrayClass(cx, global) &&
+#endif
            true;
 }
 
 /* static */ bool
 GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx, Handle<GlobalObject*> global)
 {
     HeapSlot &v = global->getSlotRef(RUNTIME_CODEGEN_ENABLED);
     if (v.isUndefined()) {
--- a/js/src/vm/PosixNSPR.h
+++ b/js/src/vm/PosixNSPR.h
@@ -4,16 +4,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_PosixNSPR_h
 #define vm_PosixNSPR_h
 
 #ifdef JS_POSIX_NSPR
 
+#ifndef JS_THREADSAFE
+#error "This file must not be included in non-threadsafe mode"
+#endif
+
 #include <pthread.h>
 #include <stdint.h>
 
 #define PR_ATOMIC_INCREMENT(val) __sync_add_and_fetch(val, 1)
 #define PR_ATOMIC_DECREMENT(val) __sync_sub_and_fetch(val, 1)
 #define PR_ATOMIC_SET(val, newval) __sync_lock_test_and_set(val, newval)
 #define PR_ATOMIC_ADD(ptr, val) __sync_add_and_fetch(ptr, val)
 
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -326,51 +326,51 @@ InitViewList(ArrayBufferObject *obj, Arr
 
 static EncapsulatedPtr<ArrayBufferViewObject> &
 GetViewListRef(ArrayBufferObject *obj)
 {
     JS_ASSERT(obj->runtimeFromMainThread()->isHeapBusy());
     return reinterpret_cast<OldObjectRepresentationHack*>(obj->getElementsHeader())->views;
 }
 
-bool
-ArrayBufferObject::neuterViews(JSContext *cx)
+/* static */ bool
+ArrayBufferObject::neuterViews(JSContext *cx, Handle<ArrayBufferObject*> buffer)
 {
     ArrayBufferViewObject *view;
     size_t numViews = 0;
-    for (view = GetViewList(this); view; view = view->nextView()) {
+    for (view = GetViewList(buffer); view; view = view->nextView()) {
         numViews++;
         view->neuter();
 
         // Notify compiled jit code that the base pointer has moved.
         MarkObjectStateChange(cx, view);
     }
 
     // neuterAsmJSArrayBuffer adjusts state specific to the ArrayBuffer data
     // itself, but it only affects the behavior of views
-    if (isAsmJSArrayBuffer()) {
-        if (!ArrayBufferObject::neuterAsmJSArrayBuffer(cx, *this))
+    if (buffer->isAsmJSArrayBuffer()) {
+        if (!ArrayBufferObject::neuterAsmJSArrayBuffer(cx, *buffer))
             return false;
     }
 
     // Remove buffer from the list of buffers with > 1 view.
-    if (numViews > 1 && GetViewList(this)->bufferLink() != UNSET_BUFFER_LINK) {
-        ArrayBufferObject *prev = compartment()->gcLiveArrayBuffers;
-        if (prev == this) {
-            compartment()->gcLiveArrayBuffers = GetViewList(prev)->bufferLink();
+    if (numViews > 1 && GetViewList(buffer)->bufferLink() != UNSET_BUFFER_LINK) {
+        ArrayBufferObject *prev = buffer->compartment()->gcLiveArrayBuffers;
+        if (prev == buffer) {
+            buffer->compartment()->gcLiveArrayBuffers = GetViewList(prev)->bufferLink();
         } else {
-            for (ArrayBufferObject *buf = GetViewList(prev)->bufferLink();
-                 buf;
-                 buf = GetViewList(buf)->bufferLink())
+            for (ArrayBufferObject *b = GetViewList(prev)->bufferLink();
+                 b;
+                 b = GetViewList(b)->bufferLink())
             {
-                if (buf == this) {
-                    GetViewList(prev)->setBufferLink(GetViewList(buf)->bufferLink());
+                if (b == buffer) {
+                    GetViewList(prev)->setBufferLink(GetViewList(b)->bufferLink());
                     break;
                 }
-                prev = buf;
+                prev = b;
             }
         }
     }
 
     return true;
 }
 
 void
@@ -700,17 +700,17 @@ ArrayBufferObject::stealContents(JSConte
     if (!header)
         return false;
     JS_ASSERT(!IsInsideNursery(cx->runtime(), header));
     *contents = header;
     *data = reinterpret_cast<uint8_t *>(header + 1);
 
     // Neuter the views, which may also mprotect(PROT_NONE) the buffer. So do
     // it after copying out the data.
-    if (!buffer->neuterViews(cx))
+    if (!ArrayBufferObject::neuterViews(cx, buffer))
         return false;
 
     if (!own) {
         // If header has dynamically allocated elements, revert it back to
         // fixed-element storage before neutering it.
         buffer->changeContents(cx, ObjectElements::fromElements(buffer->fixedElements()));
     }
     buffer->neuter(cx);
@@ -4057,17 +4057,17 @@ JS_FRIEND_API(bool)
 JS_NeuterArrayBuffer(JSContext *cx, HandleObject obj)
 {
     if (!obj->is<ArrayBufferObject>()) {
         JS_ReportError(cx, "ArrayBuffer object required");
         return false;
     }
 
     Rooted<ArrayBufferObject*> buffer(cx, &obj->as<ArrayBufferObject>());
-    if (!buffer->neuterViews(cx))
+    if (!ArrayBufferObject::neuterViews(cx, buffer))
         return false;
     buffer->neuter(cx);
     return true;
 }
 
 JS_FRIEND_API(JSObject *)
 JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes)
 {
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -193,17 +193,17 @@ class ArrayBufferObject : public JSObjec
      * the returned contents (which is the case for inline or asm.js buffers),
      * and false if the ArrayBuffer still owns the pointer.
      */
     ObjectElements *getTransferableContents(JSContext *maybecx, bool *callerOwns);
 
     /*
      * Neuter all views of an ArrayBuffer.
      */
-    bool neuterViews(JSContext *cx);
+    static bool neuterViews(JSContext *cx, Handle<ArrayBufferObject*> buffer);
 
     inline uint8_t * dataPointer() const {
         return (uint8_t *) elements;
     }
 
     /*
      * Discard the ArrayBuffer contents. For asm.js buffers, at least, should
      * be called after neuterViews().
--- a/layout/base/tests/test_bug399284.html
+++ b/layout/base/tests/test_bug399284.html
@@ -27,16 +27,20 @@ SimpleTest.waitForExplicitFinish();
 while (decoderList.hasMore()) {
     var decoder =  decoderList.getNext();
 
     // encode the content for non-ASCII compatible encodings
     if (decoder == "UTF-16BE")
         data = encodeUTF16BE(testContent);
     else if (decoder == "UTF-16" || decoder == "UTF-16LE")
         data = encodeUTF16LE(testContent);
+    else if (decoder == "replacement" || 
+             decoder == "ISO-2022-KR" || 
+             decoder == "ISO-2022-CN")
+        continue;
     else
         data = encodeURI(testContent);
     var dataURI = "data:text/html;charset=" + decoder + "," + data;
    
     var testFrame = document.createElement("iframe");
     frameID = decoder;
     testFrame.setAttribute("id", frameID);
     var testFrameObj = document.body.appendChild(testFrame);
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -781,16 +781,77 @@ nsBlockFrame::ComputeTightBounds(gfxCont
 {
   // be conservative
   if (StyleContext()->HasTextDecorationLines()) {
     return GetVisualOverflowRect();
   }
   return ComputeSimpleTightBounds(aContext);
 }
 
+/* virtual */ nsresult
+nsBlockFrame::GetPrefWidthTightBounds(nsRenderingContext* aRenderingContext,
+                                      nscoord* aX,
+                                      nscoord* aXMost)
+{
+  nsIFrame* firstInFlow = FirstContinuation();
+  if (firstInFlow != this) {
+    return firstInFlow->GetPrefWidthTightBounds(aRenderingContext, aX, aXMost);
+  }
+
+  *aX = 0;
+  *aXMost = 0;
+
+  nsresult rv;
+  InlinePrefWidthData data;
+  for (nsBlockFrame* curFrame = this; curFrame;
+       curFrame = static_cast<nsBlockFrame*>(curFrame->GetNextContinuation())) {
+    for (line_iterator line = curFrame->begin_lines(), line_end = curFrame->end_lines();
+         line != line_end; ++line)
+    {
+      nscoord childX, childXMost;
+      if (line->IsBlock()) {
+        data.ForceBreak(aRenderingContext);
+        rv = line->mFirstChild->GetPrefWidthTightBounds(aRenderingContext,
+                                                        &childX, &childXMost);
+        NS_ENSURE_SUCCESS(rv, rv);
+        *aX = std::min(*aX, childX);
+        *aXMost = std::max(*aXMost, childXMost);
+      } else {
+        if (!curFrame->GetPrevContinuation() &&
+            line == curFrame->begin_lines()) {
+          // Only add text-indent if it has no percentages; using a
+          // percentage basis of 0 unconditionally would give strange
+          // behavior for calc(10%-3px).
+          const nsStyleCoord &indent = StyleText()->mTextIndent;
+          if (indent.ConvertsToLength()) {
+            data.currentLine += nsRuleNode::ComputeCoordPercentCalc(indent, 0);
+          }
+        }
+        // XXX Bug NNNNNN Should probably handle percentage text-indent.
+
+        data.line = &line;
+        data.lineContainer = curFrame;
+        nsIFrame *kid = line->mFirstChild;
+        for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end;
+             ++i, kid = kid->GetNextSibling()) {
+          rv = kid->GetPrefWidthTightBounds(aRenderingContext, &childX,
+                                            &childXMost);
+          NS_ENSURE_SUCCESS(rv, rv);
+          *aX = std::min(*aX, data.currentLine + childX);
+          *aXMost = std::max(*aXMost, data.currentLine + childXMost);
+          kid->AddInlinePrefWidth(aRenderingContext, &data);
+        }
+      }
+    }
+  }
+  data.ForceBreak(aRenderingContext);
+
+  return NS_OK;
+}
+
 static bool
 AvailableSpaceShrunk(const nsRect& aOldAvailableSpace,
                      const nsRect& aNewAvailableSpace)
 {
   if (aNewAvailableSpace.width == 0) {
     // Positions are not significant if the width is zero.
     return aOldAvailableSpace.width != 0;
   }
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -256,16 +256,20 @@ public:
 private:
   void CheckIntrinsicCacheAgainstShrinkWrapState();
 public:
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
   virtual nsRect ComputeTightBounds(gfxContext* aContext) const MOZ_OVERRIDE;
   
+  virtual nsresult GetPrefWidthTightBounds(nsRenderingContext* aContext,
+                                           nscoord* aX,
+                                           nscoord* aXMost) MOZ_OVERRIDE;
+
   /**
    * Compute the final height of this frame.
    *
    * @param aReflowState Data structure passed from parent during reflow.
    * @param aReflowStatus A pointed to the reflow status for when we're finished
    *        doing reflow. this will get set appropriately if the height causes
    *        us to exceed the current available (page) height.
    * @param aContentHeight The height of content, precomputed outside of this
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1558,18 +1558,18 @@ MainAxisPositionTracker::
   }
 
   if (mPackingSpaceRemaining <= 0) {
     // No available packing space to use for resolving auto margins.
     mNumAutoMarginsInMainAxis = 0;
   }
 
   mJustifyContent = aFlexContainerFrame->StylePosition()->mJustifyContent;
-  // If packing space is negative, 'justify' behaves like 'start', and
-  // 'distribute' behaves like 'center'.  In those cases, it's simplest to
+  // If packing space is negative, 'space-between' behaves like 'flex-start',
+  // and 'space-around' behaves like 'center'. In those cases, it's simplest to
   // just pretend we have a different 'justify-content' value and share code.
   if (mPackingSpaceRemaining < 0) {
     if (mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_SPACE_BETWEEN) {
       mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START;
     } else if (mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_SPACE_AROUND) {
       mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_CENTER;
     }
   }
@@ -1858,17 +1858,17 @@ SingleLineCrossAxisPositionTracker::
   if (aItem.GetNumAutoMarginsInAxis(mAxis)) {
     return;
   }
 
   switch (aItem.GetAlignSelf()) {
     case NS_STYLE_ALIGN_ITEMS_FLEX_START:
     case NS_STYLE_ALIGN_ITEMS_STRETCH:
       // No space to skip over -- we're done.
-      // NOTE: 'stretch' behaves like 'start' once we've stretched any
+      // NOTE: 'stretch' behaves like 'flex-start' once we've stretched any
       // auto-sized items (which we've already done).
       break;
     case NS_STYLE_ALIGN_ITEMS_FLEX_END:
       mPosition +=
         mLineCrossSize -
         (aItem.GetCrossSize() +
          aItem.GetMarginBorderPaddingSizeInAxis(mAxis));
       break;
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4044,16 +4044,24 @@ nsFrame::ComputeSimpleTightBounds(gfxCon
     for (; !childFrames.AtEnd(); childFrames.Next()) {
       nsIFrame* child = childFrames.get();
       r.UnionRect(r, child->ComputeTightBounds(aContext) + child->GetPosition());
     }
   }
   return r;
 }
 
+/* virtual */ nsresult
+nsIFrame::GetPrefWidthTightBounds(nsRenderingContext* aContext,
+                                  nscoord* aX,
+                                  nscoord* aXMost)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 /* virtual */ nsSize
 nsFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
                          nsSize aCBSize, nscoord aAvailableWidth,
                          nsSize aMargin, nsSize aBorder, nsSize aPadding,
                          bool aShrinkWrap)
 {
   // Use basic shrink-wrapping as a default implementation.
   nsSize result(0xdeadbeef, NS_UNCONSTRAINEDSIZE);
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1828,16 +1828,36 @@ public:
    * contribute to visual overflow.
    *
    * @param aContext a rendering context that can be used if we need
    * to do measurement
    */
   virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
 
   /**
+   * This function is similar to GetPrefWidth and ComputeTightBounds: it
+   * computes the left and right coordinates of a preferred tight bounding
+   * rectangle for the frame. This is a rectangle that would enclose the pixels
+   * that are drawn if we lay out the element without taking any optional line
+   * breaks. The rectangle is in appunits and relative to the origin of this
+   * frame. Currently, this function is only implemented for nsBlockFrame and
+   * nsTextFrame and is used to determine intrinsic widths of MathML token
+   * elements.
+
+   * @param aContext a rendering context that can be used if we need
+   * to do measurement
+   * @param aX      computed left coordinate of the tight bounding rectangle
+   * @param aXMost  computed intrinsic width of the tight bounding rectangle
+   *
+   */
+  virtual nsresult GetPrefWidthTightBounds(nsRenderingContext* aContext,
+                                           nscoord* aX,
+                                           nscoord* aXMost);
+
+  /**
    * Pre-reflow hook. Before a frame is reflowed this method will be called.
    * This call will always be invoked at least once before a subsequent Reflow
    * and DidReflow call. It may be called more than once, In general you will
    * receive on WillReflow notification before each Reflow request.
    *
    * XXX Is this really the semantics we want? Because we have the NS_FRAME_IN_REFLOW
    * bit we can ensure we don't call it more than once...
    */
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -2604,44 +2604,47 @@ GetEndOfTrimmedText(const nsTextFragment
     if (!IsTrimmableSpace(aFrag, aIterator->GetOriginalOffset(), aStyleText))
       return aIterator->GetSkippedOffset() + 1;
   }
   return aStart;
 }
 
 nsTextFrame::TrimmedOffsets
 nsTextFrame::GetTrimmedOffsets(const nsTextFragment* aFrag,
-                               bool aTrimAfter)
+                               bool aTrimAfter, bool aPostReflow)
 {
   NS_ASSERTION(mTextRun, "Need textrun here");
-  // This should not be used during reflow. We need our TEXT_REFLOW_FLAGS
-  // to be set correctly.  If our parent wasn't reflowed due to the frame
-  // tree being too deep then the return value doesn't matter.
-  NS_ASSERTION(!(GetStateBits() & NS_FRAME_FIRST_REFLOW) ||
-               (GetParent()->GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE),
-               "Can only call this on frames that have been reflowed");
-  NS_ASSERTION(!(GetStateBits() & NS_FRAME_IN_REFLOW),
-               "Can only call this on frames that are not being reflowed");
+  if (aPostReflow) {
+    // This should not be used during reflow. We need our TEXT_REFLOW_FLAGS
+    // to be set correctly.  If our parent wasn't reflowed due to the frame
+    // tree being too deep then the return value doesn't matter.
+    NS_ASSERTION(!(GetStateBits() & NS_FRAME_FIRST_REFLOW) ||
+                 (GetParent()->GetStateBits() &
+                  NS_FRAME_TOO_DEEP_IN_FRAME_TREE),
+                 "Can only call this on frames that have been reflowed");
+    NS_ASSERTION(!(GetStateBits() & NS_FRAME_IN_REFLOW),
+                 "Can only call this on frames that are not being reflowed");
+  }
 
   TrimmedOffsets offsets = { GetContentOffset(), GetContentLength() };
   const nsStyleText* textStyle = StyleText();
   // Note that pre-line newlines should still allow us to trim spaces
   // for display
   if (textStyle->WhiteSpaceIsSignificant())
     return offsets;
 
-  if (GetStateBits() & TEXT_START_OF_LINE) {
+  if (!aPostReflow || (GetStateBits() & TEXT_START_OF_LINE)) {
     int32_t whitespaceCount =
       GetTrimmableWhitespaceCount(aFrag,
                                   offsets.mStart, offsets.mLength, 1);
     offsets.mStart += whitespaceCount;
     offsets.mLength -= whitespaceCount;
   }
 
-  if (aTrimAfter && (GetStateBits() & TEXT_END_OF_LINE)) {
+  if (aTrimAfter && (!aPostReflow || (GetStateBits() & TEXT_END_OF_LINE))) {
     // This treats a trailing 'pre-line' newline as trimmable. That's fine,
     // it's actually what we want since we want whitespace before it to
     // be trimmed.
     int32_t whitespaceCount =
       GetTrimmableWhitespaceCount(aFrag,
                                   offsets.GetEnd() - 1, offsets.mLength, -1);
     offsets.mLength -= whitespaceCount;
   }
@@ -2804,16 +2807,18 @@ public:
       mWhichTextRun(aWhichTextRun)
   {
     NS_ASSERTION(mTextRun, "Textrun not initialized!");
   }
 
   // Call this after construction if you're not going to reflow the text
   void InitializeForDisplay(bool aTrimAfter);
 
+  void InitializeForMeasure();
+
   virtual void GetSpacing(uint32_t aStart, uint32_t aLength, Spacing* aSpacing);
   virtual gfxFloat GetHyphenWidth();
   virtual void GetHyphenationBreaks(uint32_t aStart, uint32_t aLength,
                                     bool* aBreakBefore);
   virtual int8_t GetHyphensOption() {
     return mTextStyle->mHyphens;
   }
 
@@ -3244,16 +3249,27 @@ PropertyProvider::InitializeForDisplay(b
 {
   nsTextFrame::TrimmedOffsets trimmed =
     mFrame->GetTrimmedOffsets(mFrag, aTrimAfter);
   mStart.SetOriginalOffset(trimmed.mStart);
   mLength = trimmed.mLength;
   SetupJustificationSpacing();
 }
 
+void
+PropertyProvider::InitializeForMeasure()
+{
+  nsTextFrame::TrimmedOffsets trimmed =
+    mFrame->GetTrimmedOffsets(mFrag, true, false);
+  mStart.SetOriginalOffset(trimmed.mStart);
+  mLength = trimmed.mLength;
+  SetupJustificationSpacing();
+}
+
+
 static uint32_t GetSkippedDistance(const gfxSkipCharsIterator& aStart,
                                    const gfxSkipCharsIterator& aEnd)
 {
   return aEnd.GetSkippedOffset() - aStart.GetSkippedOffset();
 }
 
 void
 PropertyProvider::FindJustificationRange(gfxSkipCharsIterator* aStart,
@@ -7282,16 +7298,41 @@ nsTextFrame::ComputeTightBounds(gfxConte
                               ComputeTransformedLength(provider),
                               gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS,
                               aContext, &provider);
   // mAscent should be the same as metrics.mAscent, but it's what we use to
   // paint so that's the one we'll use.
   return RoundOut(metrics.mBoundingBox) + nsPoint(0, mAscent);
 }
 
+/* virtual */ nsresult
+nsTextFrame::GetPrefWidthTightBounds(nsRenderingContext* aContext,
+                                     nscoord* aX,
+                                     nscoord* aXMost)
+{
+  gfxSkipCharsIterator iter =
+    const_cast<nsTextFrame*>(this)->EnsureTextRun(nsTextFrame::eInflated);
+  if (!mTextRun)
+    return NS_ERROR_FAILURE;
+
+  PropertyProvider provider(const_cast<nsTextFrame*>(this), iter,
+                            nsTextFrame::eInflated);
+  provider.InitializeForMeasure();
+
+  gfxTextRun::Metrics metrics =
+        mTextRun->MeasureText(provider.GetStart().GetSkippedOffset(),
+                              ComputeTransformedLength(provider),
+                              gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS,
+                              aContext->ThebesContext(), &provider);
+  *aX = metrics.mBoundingBox.x;
+  *aXMost = metrics.mBoundingBox.XMost();
+
+  return NS_OK;
+}
+
 static bool
 HasSoftHyphenBefore(const nsTextFragment* aFrag, gfxTextRun* aTextRun,
                     int32_t aStartOffset, const gfxSkipCharsIterator& aIter)
 {
   if (aIter.GetSkippedOffset() < aTextRun->GetLength() &&
       aTextRun->CanHyphenateBefore(aIter.GetSkippedOffset())) {
     return true;
   }
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -216,16 +216,19 @@ public:
                                  InlineMinWidthData *aData) MOZ_OVERRIDE;
   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
                                   InlinePrefWidthData *aData) MOZ_OVERRIDE;
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
   virtual nsRect ComputeTightBounds(gfxContext* aContext) const MOZ_OVERRIDE;
+  virtual nsresult GetPrefWidthTightBounds(nsRenderingContext* aContext,
+                                           nscoord* aX,
+                                           nscoord* aXMost) MOZ_OVERRIDE;
   NS_IMETHOD Reflow(nsPresContext* aPresContext,
                     nsHTMLReflowMetrics& aMetrics,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus& aStatus) MOZ_OVERRIDE;
   virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
   // Method that is called for a text frame that is logically
   // adjacent to the end of the line (i.e. followed only by empty text frames,
   // placeholders or inlines containing such).
@@ -506,17 +509,17 @@ public:
   // whitespace subject to start-of-line and end-of-line trimming.
   // The textrun must have been created before calling this.
   struct TrimmedOffsets {
     int32_t mStart;
     int32_t mLength;
     int32_t GetEnd() const { return mStart + mLength; }
   };
   TrimmedOffsets GetTrimmedOffsets(const nsTextFragment* aFrag,
-                                   bool aTrimAfter);
+                                   bool aTrimAfter, bool aPostReflow = true);
 
   // Similar to Reflow(), but for use from nsLineLayout
   void ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
                   nsRenderingContext* aRenderingContext,
                   nsHTMLReflowMetrics& aMetrics, nsReflowStatus& aStatus);
 
   bool IsFloatingFirstLetterChild() const;
 
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -24,16 +24,17 @@ using namespace mozilla;
 //
 // nsMathMLContainerFrame implementation
 //
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLContainerFrame)
 
 NS_QUERYFRAME_HEAD(nsMathMLContainerFrame)
   NS_QUERYFRAME_ENTRY(nsIMathMLFrame)
+  NS_QUERYFRAME_ENTRY(nsMathMLContainerFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 // =============================================================================
 
 // error handlers
 // provide a feedback to the user when a frame with bad markup can not be rendered
 nsresult
 nsMathMLContainerFrame::ReflowError(nsRenderingContext& aRenderingContext,
@@ -980,65 +981,83 @@ nsMathMLContainerFrame::Reflow(nsPresCon
   return NS_OK;
 }
 
 /* virtual */ nscoord
 nsMathMLContainerFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
 {
   nscoord result;
   DISPLAY_MIN_WIDTH(this, result);
-  result = GetIntrinsicWidth(aRenderingContext);
+  nsHTMLReflowMetrics desiredSize;
+  GetIntrinsicWidthMetrics(aRenderingContext, desiredSize);
+  nsBoundingMetrics bm = desiredSize.mBoundingMetrics;
+  // We include the overflow to compensate for FixInterFrameSpacing.
+  result = std::max(bm.width, bm.rightBearing) - std::min(0, bm.leftBearing);
   return result;
 }
 
 /* virtual */ nscoord
 nsMathMLContainerFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
 {
   nscoord result;
   DISPLAY_MIN_WIDTH(this, result);
-  result = GetIntrinsicWidth(aRenderingContext);
+  nsHTMLReflowMetrics desiredSize;
+  GetIntrinsicWidthMetrics(aRenderingContext, desiredSize);
+  nsBoundingMetrics bm = desiredSize.mBoundingMetrics;
+  // We include the overflow to compensate for FixInterFrameSpacing.
+  result = std::max(bm.width, bm.rightBearing) - std::min(0, bm.leftBearing);
   return result;
 }
 
-/* virtual */ nscoord
-nsMathMLContainerFrame::GetIntrinsicWidth(nsRenderingContext* aRenderingContext)
+/* virtual */ void
+nsMathMLContainerFrame::GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext, nsHTMLReflowMetrics& aDesiredSize)
 {
   // Get child widths
   nsIFrame* childFrame = mFrames.FirstChild();
   while (childFrame) {
-    // XXX This includes margin while Reflow currently doesn't consider
-    // margin, so we may end up with too much space, but, with stretchy
-    // characters, this is an approximation anyway.
-    nscoord width =
-      nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
-                                           nsLayoutUtils::PREF_WIDTH);
+    nsHTMLReflowMetrics childDesiredSize;
 
-    nsHTMLReflowMetrics childDesiredSize;
-    childDesiredSize.width = width;
-    childDesiredSize.mBoundingMetrics.width = width;
-    // TODO: we need nsIFrame::GetIntrinsicHBounds() for better values here.
-    childDesiredSize.mBoundingMetrics.leftBearing = 0;
-    childDesiredSize.mBoundingMetrics.rightBearing = width;
+    nsMathMLContainerFrame* containerFrame = do_QueryFrame(childFrame);
+    if (containerFrame) {
+      containerFrame->GetIntrinsicWidthMetrics(aRenderingContext,
+                                               childDesiredSize);
+    } else {
+      // XXX This includes margin while Reflow currently doesn't consider
+      // margin, so we may end up with too much space, but, with stretchy
+      // characters, this is an approximation anyway.
+      nscoord width =
+        nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
+                                             nsLayoutUtils::PREF_WIDTH);
+
+      childDesiredSize.width = width;
+      childDesiredSize.mBoundingMetrics.width = width;
+      childDesiredSize.mBoundingMetrics.leftBearing = 0;
+      childDesiredSize.mBoundingMetrics.rightBearing = width;
+
+      nscoord x, xMost;
+      if (NS_SUCCEEDED(childFrame->GetPrefWidthTightBounds(aRenderingContext,
+                                                           &x, &xMost))) {
+        childDesiredSize.mBoundingMetrics.leftBearing = x;
+        childDesiredSize.mBoundingMetrics.rightBearing = xMost;
+      }
+    }
 
     SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
                                     childDesiredSize.mBoundingMetrics);
 
     childFrame = childFrame->GetNextSibling();
   }
 
   // Measure
-  nsHTMLReflowMetrics desiredSize;
-  nsresult rv = MeasureForWidth(*aRenderingContext, desiredSize);
+  nsresult rv = MeasureForWidth(*aRenderingContext, aDesiredSize);
   if (NS_FAILED(rv)) {
-    ReflowError(*aRenderingContext, desiredSize);
+    ReflowError(*aRenderingContext, aDesiredSize);
   }
 
   ClearSavedChildMetrics();
-
-  return desiredSize.width;
 }
 
 /* virtual */ nsresult
 nsMathMLContainerFrame::MeasureForWidth(nsRenderingContext& aRenderingContext,
                                         nsHTMLReflowMetrics& aDesiredSize)
 {
   return Place(aRenderingContext, false, aDesiredSize);
 }
--- a/layout/mathml/nsMathMLContainerFrame.h
+++ b/layout/mathml/nsMathMLContainerFrame.h
@@ -28,16 +28,17 @@
 #define STRETCH_CONSIDER_EMBELLISHMENTS 0x00000002 // size calculations include embellishments
 
 class nsMathMLContainerFrame : public nsContainerFrame,
                                public nsMathMLFrame {
   friend class nsMathMLmfencedFrame;
 public:
   nsMathMLContainerFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {}
 
+  NS_DECL_QUERYFRAME_TARGET(nsMathMLContainerFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // --------------------------------------------------------------------------
   // Overloaded nsMathMLFrame methods -- see documentation in nsIMathMLFrame.h
 
   NS_IMETHOD
   Stretch(nsRenderingContext& aRenderingContext,
@@ -87,26 +88,28 @@ public:
                nsIFrame*       aPrevFrame,
                nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD
   RemoveFrame(ChildListID     aListID,
               nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
   /**
-   * Both GetMinWidth and GetPrefWidth return whatever
-   * GetIntrinsicWidth returns.
+   * Both GetMinWidth and GetPrefWidth use the intrinsic width metrics
+   * returned by GetIntrinsicMetrics, including ink overflow.
    */
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
   /**
-   * Return the intrinsic width of the frame's content area.
+   * Return the intrinsic horizontal metrics of the frame's content area.
    */
-  virtual nscoord GetIntrinsicWidth(nsRenderingContext *aRenderingContext);
+  virtual void
+  GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext,
+                           nsHTMLReflowMetrics& aDesiredSize);
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   NS_IMETHOD
--- a/layout/mathml/nsMathMLmfencedFrame.cpp
+++ b/layout/mathml/nsMathMLmfencedFrame.cpp
@@ -559,18 +559,18 @@ GetMaxCharWidth(nsPresContext*       aPr
     GetCharSpacing(aMathMLChar, aForm, aScriptLevel, em, leftSpace, rightSpace);
 
     width += leftSpace + rightSpace;
   }
   
   return width;
 }
 
-/* virtual */ nscoord
-nsMathMLmfencedFrame::GetIntrinsicWidth(nsRenderingContext* aRenderingContext)
+/* virtual */ void
+nsMathMLmfencedFrame::GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext, nsHTMLReflowMetrics& aDesiredSize)
 {
   nscoord width = 0;
 
   nsPresContext* presContext = PresContext();
   const nsStyleFont* font = StyleFont();
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
   nscoord em;
@@ -602,17 +602,20 @@ nsMathMLmfencedFrame::GetIntrinsicWidth(
   }
 
   if (mCloseChar) {
     width +=
       GetMaxCharWidth(presContext, aRenderingContext, mCloseChar,
                       NS_MATHML_OPERATOR_FORM_POSTFIX, font->mScriptLevel, em);
   }
 
-  return width;
+  aDesiredSize.width = width;
+  aDesiredSize.mBoundingMetrics.width = width;
+  aDesiredSize.mBoundingMetrics.leftBearing = 0;
+  aDesiredSize.mBoundingMetrics.rightBearing = width;
 }
 
 nscoord
 nsMathMLmfencedFrame::FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize)
 {
   nscoord gap = nsMathMLContainerFrame::FixInterFrameSpacing(aDesiredSize);
   if (!gap) return 0;
 
--- a/layout/mathml/nsMathMLmfencedFrame.h
+++ b/layout/mathml/nsMathMLmfencedFrame.h
@@ -37,18 +37,19 @@ public:
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
-  virtual nscoord
-  GetIntrinsicWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
+  virtual void
+  GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext,
+                           nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   NS_IMETHOD
   AttributeChanged(int32_t         aNameSpaceID,
                    nsIAtom*        aAttribute,
                    int32_t         aModType) MOZ_OVERRIDE;
 
   // override the base method because we must keep separators in sync
   virtual nsresult
--- a/layout/mathml/nsMathMLmoFrame.cpp
+++ b/layout/mathml/nsMathMLmoFrame.cpp
@@ -981,38 +981,46 @@ nsMathMLmoFrame::MarkIntrinsicWidthsDirt
   // we have automatic data to update in the children of the target frame
   // XXXldb This should really be marking dirty rather than rebuilding
   // so that we don't rebuild multiple times for the same change.
   RebuildAutomaticDataForChildren(target);
 
   nsMathMLContainerFrame::MarkIntrinsicWidthsDirty();
 }
 
-/* virtual */ nscoord
-nsMathMLmoFrame::GetIntrinsicWidth(nsRenderingContext *aRenderingContext)
+/* virtual */ void
+nsMathMLmoFrame::GetIntrinsicWidthMetrics(nsRenderingContext *aRenderingContext, nsHTMLReflowMetrics& aDesiredSize)
 {
   ProcessOperatorData();
-  nscoord width;
   if (UseMathMLChar()) {
     uint32_t stretchHint = GetStretchHint(mFlags, mPresentationData, true);
-    width = mMathMLChar.
+    aDesiredSize.width = mMathMLChar.
       GetMaxWidth(PresContext(), *aRenderingContext,
                   stretchHint, mMaxSize,
                   NS_MATHML_OPERATOR_MAXSIZE_IS_ABSOLUTE(mFlags));
   }
   else {
-    width = nsMathMLTokenFrame::GetIntrinsicWidth(aRenderingContext);
+    nsMathMLTokenFrame::GetIntrinsicWidthMetrics(aRenderingContext,
+                                                 aDesiredSize);
   }
 
   // leadingSpace and trailingSpace are actually applied to the outermost
   // embellished container but for determining total intrinsic width it should
   // be safe to include it for the core here instead.
-  width += mEmbellishData.leadingSpace + mEmbellishData.trailingSpace;
-
-  return width;
+  bool isRTL = StyleVisibility()->mDirection;
+  aDesiredSize.width +=
+    mEmbellishData.leadingSpace + mEmbellishData.trailingSpace;
+  aDesiredSize.mBoundingMetrics.width = aDesiredSize.width;
+  if (isRTL) {
+    aDesiredSize.mBoundingMetrics.leftBearing += mEmbellishData.trailingSpace;
+    aDesiredSize.mBoundingMetrics.rightBearing += mEmbellishData.trailingSpace;
+  } else {
+    aDesiredSize.mBoundingMetrics.leftBearing += mEmbellishData.leadingSpace;
+    aDesiredSize.mBoundingMetrics.rightBearing += mEmbellishData.leadingSpace;
+  }
 }
 
 NS_IMETHODIMP
 nsMathMLmoFrame::AttributeChanged(int32_t         aNameSpaceID,
                                   nsIAtom*        aAttribute,
                                   int32_t         aModType)
 {
   // check if this is an attribute that can affect the embellished hierarchy
--- a/layout/mathml/nsMathMLmoFrame.h
+++ b/layout/mathml/nsMathMLmoFrame.h
@@ -41,18 +41,19 @@ public:
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
 
-  virtual nscoord
-  GetIntrinsicWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual void
+  GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext,
+                           nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   NS_IMETHOD
   AttributeChanged(int32_t         aNameSpaceID,
                    nsIAtom*        aAttribute,
                    int32_t         aModType) MOZ_OVERRIDE;
 
   // This method is called by the parent frame to ask <mo> 
   // to stretch itself.
--- a/layout/mathml/nsMathMLmrootFrame.cpp
+++ b/layout/mathml/nsMathMLmrootFrame.cpp
@@ -345,42 +345,46 @@ nsMathMLmrootFrame::Reflow(nsPresContext
   mReference.x = 0;
   mReference.y = aDesiredSize.ascent;
 
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return NS_OK;
 }
 
-/* virtual */ nscoord
-nsMathMLmrootFrame::GetIntrinsicWidth(nsRenderingContext* aRenderingContext)
+/* virtual */ void
+nsMathMLmrootFrame::GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext, nsHTMLReflowMetrics& aDesiredSize)
 {
   nsIFrame* baseFrame = mFrames.FirstChild();
   nsIFrame* indexFrame = nullptr;
   if (baseFrame)
     indexFrame = baseFrame->GetNextSibling();
   if (!indexFrame || indexFrame->GetNextSibling()) {
-    nsHTMLReflowMetrics desiredSize;
-    ReflowError(*aRenderingContext, desiredSize);
-    return desiredSize.width;
+    ReflowError(*aRenderingContext, aDesiredSize);
+    return;
   }
 
   nscoord baseWidth =
     nsLayoutUtils::IntrinsicForContainer(aRenderingContext, baseFrame,
                                          nsLayoutUtils::PREF_WIDTH);
   nscoord indexWidth =
     nsLayoutUtils::IntrinsicForContainer(aRenderingContext, indexFrame,
                                          nsLayoutUtils::PREF_WIDTH);
   nscoord sqrWidth = mSqrChar.GetMaxWidth(PresContext(), *aRenderingContext);
 
   nscoord dxSqr;
   GetRadicalXOffsets(indexWidth, sqrWidth, aRenderingContext->FontMetrics(),
                      nullptr, &dxSqr);
 
-  return dxSqr + sqrWidth + baseWidth;
+  nscoord width = dxSqr + sqrWidth + baseWidth;
+
+  aDesiredSize.width = width;
+  aDesiredSize.mBoundingMetrics.width = width;
+  aDesiredSize.mBoundingMetrics.leftBearing = 0;
+  aDesiredSize.mBoundingMetrics.rightBearing = width;
 }
 
 // ----------------------
 // the Style System will use these to pass the proper style context to our MathMLChar
 nsStyleContext*
 nsMathMLmrootFrame::GetAdditionalStyleContext(int32_t aIndex) const
 {
   switch (aIndex) {
--- a/layout/mathml/nsMathMLmrootFrame.h
+++ b/layout/mathml/nsMathMLmrootFrame.h
@@ -35,18 +35,19 @@ public:
   TransmitAutomaticData() MOZ_OVERRIDE;
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
-  virtual nscoord
-  GetIntrinsicWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
+  virtual void
+  GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext,
+                           nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
 protected:
   nsMathMLmrootFrame(nsStyleContext* aContext);
   virtual ~nsMathMLmrootFrame();
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -34,16 +34,17 @@ fails-if(winWidget) == mfenced-10.html m
 == mi-mathvariant-1.xhtml mi-mathvariant-1-ref.xhtml
 == mi-mathvariant-2.xhtml mi-mathvariant-2-ref.xhtml
 != non-spacing-accent-1.xhtml non-spacing-accent-1-ref.xhtml
 == overbar-width-1.xhtml overbar-width-1-ref.xhtml
 skip-if(B2G) == quotes-1.xhtml quotes-1-ref.xhtml
 != stretchy-underbar-1.xhtml stretchy-underbar-1-ref.xhtml 
 == table-width-1.xhtml table-width-1-ref.xhtml
 == table-width-2.html table-width-2-ref.html
+fails-if(OSX||/^Windows\x20NT\x206\.[12]/.test(http.oscpu)||Android) == table-width-3.html table-width-3-ref.html
 == underbar-width-1.xhtml underbar-width-1-ref.xhtml
 == mathml-type-supported.xhtml mathml-type-supported-ref.xml
 == mtable-align-negative-rownumber.html mtable-align-negative-rownumber-ref.html
 != embellished-op-1-1.html embellished-op-1-1-ref.html
 != embellished-op-1-2.html embellished-op-1-2-ref.html
 != embellished-op-1-3.html embellished-op-1-3-ref.html
 != embellished-op-1-4.html embellished-op-1-4-ref.html
 != embellished-op-1-5.html embellished-op-1-5-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/table-width-3-ref.html
@@ -0,0 +1,100 @@
+<!doctype>
+<html>
+  <head>
+    <title>table-width-3</title>
+    <meta charset="utf-8"/>
+    <style type="text/css">
+      html { background-color: grey; }
+      td { border: 1px solid white;
+      padding: 0;
+      background-color: black;
+      color: red; }
+      mi, mtext { font-size: 3em; }
+      span { font-style: italic; display: inline-block; }
+    </style>
+  </head>
+  <body>
+
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mphantom>
+              <mi>f</mi>
+            </mphantom>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mphantom>
+              <mi>f</mi>
+            </mphantom>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mphantom>
+              <mi>f</mi>
+              <mi>f</mi>
+              <mi>f</mi>
+            </mphantom>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mphantom>
+              <mi style="font-style: italic;">fff</mi>
+            </mphantom>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mphantom>
+              <mtext><span>fff</span></mtext>
+            </mphantom>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mphantom>
+              <mtext><span>f</span></mtext>
+              <mtext><span>f</span></mtext>
+              <mtext><span>f</span></mtext>
+            </mphantom>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mphantom>
+              <mtext><span>f</span><span>f</span><span>f</span></mtext>
+            </mphantom>
+          </math>
+        </td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/table-width-3.html
@@ -0,0 +1,87 @@
+<!doctype>
+<html>
+  <head>
+    <title>table-width-3</title>
+    <meta charset="utf-8"/>
+    <style type="text/css">
+      html { background-color: grey; }
+      td { border: 1px solid white;
+      padding: 0;
+      background-color: black;
+      color: black; }
+      mi, mtext { font-size: 3em; }
+      span { font-style: italic; display: inline-block; }
+    </style>
+  </head>
+  <body>
+
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mi>f</mi>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mi>    f    </mi>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mi>f</mi>
+            <mi>f</mi>
+            <mi>f</mi>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mi style="font-style: italic;">fff</mi>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mtext><span>fff</span></mtext>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mtext><span>f</span></mtext>
+            <mtext><span>f</span></mtext>
+            <mtext><span>f</span></mtext>
+          </math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math>
+            <mtext><span>f</span><span>f</span><span>f</span></mtext>
+          </math>
+        </td>
+      </tr>
+    </table>
+
+  </body>
+</html>
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -338,8 +338,11 @@ skip-if(B2G) include ../../dom/imptests/
 # editor/
 skip-if(B2G) include ../../editor/reftests/reftest.list
 
 # box-sizing
 skip-if(B2G) include box-sizing/reftest.list
 
 # invalidation - only run on B2G
 skip-if(!B2G) include invalidation/reftest.list
+
+# encodings
+include ../../dom/encoding/test/reftest/reftest.list
--- a/media/libjpeg/jdmarker.c
+++ b/media/libjpeg/jdmarker.c
@@ -467,16 +467,18 @@ get_dht (j_decompress_ptr cinfo)
      * off the end of our table space.  jdhuff.c will check more carefully.
      */
     if (count > 256 || ((INT32) count) > length)
       ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 
     for (i = 0; i < count; i++)
       INPUT_BYTE(cinfo, huffval[i], return FALSE);
 
+    MEMZERO(&huffval[count], (256-count)*SIZEOF(UINT8));
+
     length -= count;
 
     if (index & 0x10) {		/* AC table definition */
       index -= 0x10;
       htblptr = &cinfo->ac_huff_tbl_ptrs[index];
     } else {			/* DC table definition */
       htblptr = &cinfo->dc_huff_tbl_ptrs[index];
     }
--- a/media/mtransport/logging.h
+++ b/media/mtransport/logging.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Original author: ekr@rtfm.com
 
 #ifndef logging_h__
 #define logging_h__
 
 #if defined(PR_LOG)
-#error "Must #include logging.h before before any IPDL-generated files or other files that #include prlog.h."
+#error "Must #include logging.h before any IPDL-generated files or other files that #include prlog.h."
 #endif
 
 // Enforce logging under production builds for MOZ_MTLOG friends.
 #ifndef PR_LOGGING
 #define FORCE_PR_LOG 1
 #endif
 
 #include <sstream>
--- a/mobile/android/base/home/BookmarksListAdapter.java
+++ b/mobile/android/base/home/BookmarksListAdapter.java
@@ -162,24 +162,33 @@ class BookmarksListAdapter extends Multi
      * Set a listener that can refresh this adapter.
      *
      * @param listener The listener that can refresh the adapter.
      */
     public void setOnRefreshFolderListener(OnRefreshFolderListener listener) {
         mListener = listener;
     }
 
+    private boolean isCurrentFolder(FolderInfo folderInfo) {
+        return (mParentStack.size() > 0 &&
+                mParentStack.peek().id == folderInfo.id);
+    }
+
     public void swapCursor(Cursor c, FolderInfo folderInfo, RefreshType refreshType) {
         switch(refreshType) {
             case PARENT:
-                mParentStack.removeFirst();
+                if (!isCurrentFolder(folderInfo)) {
+                    mParentStack.removeFirst();
+                }
                 break;
 
             case CHILD:
-                mParentStack.addFirst(folderInfo);
+                if (!isCurrentFolder(folderInfo)) {
+                    mParentStack.addFirst(folderInfo);
+                }
                 break;
 
             default:
                 // Do nothing;
         }
 
         swapCursor(c);
     }
--- a/netwerk/base/src/nsUnicharStreamLoader.cpp
+++ b/netwerk/base/src/nsUnicharStreamLoader.cpp
@@ -176,17 +176,26 @@ nsUnicharStreamLoader::DetermineCharset(
     mCharset.AssignLiteral("UTF-8");
   }
 
   // Create the decoder for this character set
   nsCOMPtr<nsICharsetConverterManager> ccm =
     do_GetService(kCharsetConverterManagerCID, &rv);
   if (NS_FAILED(rv)) return rv;
 
-  rv = ccm->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mDecoder));
+  // Sadly, nsIUnicharStreamLoader is exposed to extensions, so we can't
+  // assume mozilla::css::Loader to be the only caller. Since legacy
+  // charset alias code doesn't know about the replacement encoding,
+  // special-case it here, but let other stuff go through legacy alias
+  // resolution for now.
+  if (mCharset.EqualsLiteral("replacement")) {
+    rv = ccm->GetUnicodeDecoderRaw(mCharset.get(), getter_AddRefs(mDecoder));
+  } else {
+    rv = ccm->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mDecoder));
+  }
   if (NS_FAILED(rv)) return rv;
 
   // Process the data into mBuffer
   uint32_t dummy;
   rv = WriteSegmentFun(nullptr, this,
                        mRawData.BeginReading(),
                        0, mRawData.Length(),
                        &dummy);
--- a/parser/html/nsHtml5MetaScannerCppSupplement.h
+++ b/parser/html/nsHtml5MetaScannerCppSupplement.h
@@ -1,75 +1,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
-#include "nsICharsetConverterManager.h"
-#include "nsServiceManagerUtils.h"
 #include "nsEncoderDecoderUtils.h"
 #include "nsTraceRefcnt.h"
 
 #include "mozilla/dom/EncodingUtils.h"
 
 using mozilla::dom::EncodingUtils;
 
 void
-nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes, nsIUnicodeDecoder** decoder, nsACString& charset)
+nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes, nsACString& charset)
 {
   readable = bytes;
   stateLoop(stateSave);
   readable = nullptr;
-  if (mUnicodeDecoder) {
-    mUnicodeDecoder.forget(decoder);
-    charset.Assign(mCharset);
-  }
+  charset.Assign(mCharset);
 }
 
 bool
 nsHtml5MetaScanner::tryCharset(nsString* charset)
 {
   // This code needs to stay in sync with
   // nsHtml5StreamParser::internalEncodingDeclaration. Unfortunately, the
   // trickery with member fields here leads to some copy-paste reuse. :-(
-  nsresult res = NS_OK;
-  nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);
-  if (NS_FAILED(res)) {
-    NS_ERROR("Could not get CharsetConverterManager service.");
+  nsAutoCString label;
+  CopyUTF16toUTF8(*charset, label);
+  nsAutoCString encoding;
+  if (!EncodingUtils::FindEncodingForLabel(label, encoding)) {
     return false;
   }
-  nsAutoCString encoding;
-  CopyUTF16toUTF8(*charset, encoding);
-  encoding.Trim(" \t\r\n\f");
-  if (encoding.LowerCaseEqualsLiteral("utf-16") ||
-      encoding.LowerCaseEqualsLiteral("utf-16be") ||
-      encoding.LowerCaseEqualsLiteral("utf-16le")) {
+  if (encoding.EqualsLiteral("UTF-16BE") ||
+      encoding.EqualsLiteral("UTF-16LE")) {
     mCharset.Assign("UTF-8");
-    res = convManager->GetUnicodeDecoderRaw(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
-    if (NS_FAILED(res)) {
-      NS_ERROR("Could not get decoder for UTF-8.");
-      return false;
-    }
     return true;
   }
-  nsAutoCString preferred;
-  if (!EncodingUtils::FindEncodingForLabel(encoding, preferred)) {
-    return false;
-  }
-  if (preferred.LowerCaseEqualsLiteral("utf-16") ||
-      preferred.LowerCaseEqualsLiteral("utf-16be") ||
-      preferred.LowerCaseEqualsLiteral("utf-16le") ||
-      preferred.LowerCaseEqualsLiteral("utf-7") ||
-      preferred.LowerCaseEqualsLiteral("x-imap4-modified-utf7")) {
-    return false;
-  }
-  res = convManager->GetUnicodeDecoderRaw(preferred.get(), getter_AddRefs(mUnicodeDecoder));
-  if (res == NS_ERROR_UCONV_NOCONV) {
-    return false;
-  } else if (NS_FAILED(res)) {
-    NS_ERROR("Getting an encoding decoder failed in a bad way.");
-    mUnicodeDecoder = nullptr;
-    return false;
-  } else {
-    NS_ASSERTION(mUnicodeDecoder, "Getter nsresult and object don't match.");
-    mCharset.Assign(preferred);
-    return true;
-  }
+  mCharset.Assign(encoding);
+  return true;
 }
--- a/parser/html/nsHtml5MetaScannerHSupplement.h
+++ b/parser/html/nsHtml5MetaScannerHSupplement.h
@@ -1,12 +1,11 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
 private:
-  nsCOMPtr<nsIUnicodeDecoder>  mUnicodeDecoder;
   nsCString mCharset;
   inline int32_t read() {
     return readable->read();
   }
 public:
-  void sniff(nsHtml5ByteReadable* bytes, nsIUnicodeDecoder** decoder, nsACString& charset);
+  void sniff(nsHtml5ByteReadable* bytes, nsACString& charset);
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -233,36 +233,43 @@ nsHtml5StreamParser::GetChannel(nsIChann
 }
 
 NS_IMETHODIMP
 nsHtml5StreamParser::Notify(const char* aCharset, nsDetectionConfident aConf)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   if (aConf == eBestAnswer || aConf == eSureAnswer) {
     mFeedChardet = false; // just in case
+    nsAutoCString encoding;
+    if (!EncodingUtils::FindEncodingForLabel(nsDependentCString(aCharset),
+                                             encoding)) {
+      return NS_OK;
+    }
+    if (encoding.EqualsLiteral("replacement")) {
+      return NS_OK;
+    }
     if (HasDecoder()) {
-      if (mCharset.Equals(aCharset)) {
+      if (mCharset.Equals(encoding)) {
         NS_ASSERTION(mCharsetSource < kCharsetFromAutoDetection,
             "Why are we running chardet at all?");
         mCharsetSource = kCharsetFromAutoDetection;
         mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
       } else {
         // We've already committed to a decoder. Request a reload from the
         // docshell.
-        nsAutoCString charset(aCharset);
-        mTreeBuilder->NeedsCharsetSwitchTo(charset,
+        mTreeBuilder->NeedsCharsetSwitchTo(encoding,
                                            kCharsetFromAutoDetection,
                                            0);
         FlushTreeOpsAndDisarmTimer();
         Interrupt();
       }
     } else {
       // Got a confident answer from the sniffing buffer. That code will
       // take care of setting up the decoder.
-      mCharset.Assign(aCharset);
+      mCharset.Assign(encoding);
       mCharsetSource = kCharsetFromAutoDetection;
       mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
     }
   }
   return NS_OK;
 }
 
 void
@@ -294,34 +301,25 @@ nsresult
 nsHtml5StreamParser::SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment, // can be null
                                                                           uint32_t aCount,
                                                                           uint32_t* aWriteCount)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   nsresult rv = NS_OK;
   nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
+  rv = convManager->GetUnicodeDecoderRaw(mCharset.get(),
+                                         getter_AddRefs(mUnicodeDecoder));
   if (rv == NS_ERROR_UCONV_NOCONV) {
     mCharset.AssignLiteral("windows-1252"); // lower case is the raw form
     mCharsetSource = kCharsetFromFallback;
     rv = convManager->GetUnicodeDecoderRaw(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
     mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   }
   NS_ENSURE_SUCCESS(rv, rv);
-  return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
-}
-
-nsresult
-nsHtml5StreamParser::WriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment, // can be null
-                                                          uint32_t aCount,
-                                                          uint32_t* aWriteCount)
-{
-  NS_ASSERTION(IsParserThread(), "Wrong thread!");
-  nsresult rv = NS_OK;
   if (mSniffingBuffer) {
     uint32_t writeCount;
     rv = WriteStreamBytes(mSniffingBuffer, mSniffingLength, &writeCount);
     NS_ENSURE_SUCCESS(rv, rv);
     mSniffingBuffer = nullptr;
   }
   mMetaScanner = nullptr;
   if (aFromSegment) {
@@ -705,82 +703,96 @@ nsHtml5StreamParser::SniffStreamBytes(co
       default:
         mBomState = BOM_SNIFFING_OVER;
         break;
     }
   }
   // if we get here, there either was no BOM or the BOM sniffing isn't complete
   // yet
   
+  MOZ_ASSERT(mCharsetSource != kCharsetFromByteOrderMark,
+             "Should not come here if BOM was found.");
+  MOZ_ASSERT(mCharsetSource != kCharsetFromOtherComponent,
+             "kCharsetFromOtherComponent is for XSLT.");
+
   if (mBomState == BOM_SNIFFING_OVER &&
-    mCharsetSource >= kCharsetFromChannel) {
-    // There was no BOM and the charset came from channel or higher. mCharset
-    // still contains the charset from the channel or higher as set by an
+    mCharsetSource == kCharsetFromChannel) {
+    // There was no BOM and the charset came from channel. mCharset
+    // still contains the charset from the channel as set by an
     // earlier call to SetDocumentCharset(), since we didn't find a BOM and
-    // overwrite mCharset.
-    nsCOMPtr<nsICharsetConverterManager> convManager =
-      do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID);
-    convManager->GetUnicodeDecoder(mCharset.get(),
-                                   getter_AddRefs(mUnicodeDecoder));
-    if (mUnicodeDecoder) {
-      mFeedChardet = false;
-      mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
-      mMetaScanner = nullptr;
-      return WriteSniffingBufferAndCurrentSegment(aFromSegment,
-                                                  aCount,
-                                                  aWriteCount);
-    } else {
-      // nsHTMLDocument is supposed to make sure this does not happen. Let's
-      // deal with this anyway, since who knows how kCharsetFromOtherComponent
-      // is used.
-      mCharsetSource = kCharsetFromFallback;
-    }
+    // overwrite mCharset. (Note that if the user has overridden the charset,
+    // we don't come here but check <meta> for XSS-dangerous charsets first.)
+    mFeedChardet = false;
+    mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+    return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
+      aCount, aWriteCount);
   }
 
   if (!mMetaScanner && (mMode == NORMAL ||
                         mMode == VIEW_SOURCE_HTML ||
                         mMode == LOAD_AS_DATA)) {
     mMetaScanner = new nsHtml5MetaScanner();
   }
   
   if (mSniffingLength + aCount >= NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE) {
     // this is the last buffer
     uint32_t countToSniffingLimit =
         NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
     if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
       nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
           countToSniffingLimit);
-      mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
-      if (mUnicodeDecoder) {
-        // meta scan successful
+      nsAutoCString encoding;
+      mMetaScanner->sniff(&readable, encoding);
+      if (!encoding.IsEmpty()) {
+        // meta scan successful; honor overrides unless meta is XSS-dangerous
+        if ((mCharsetSource == kCharsetFromParentForced ||
+             mCharsetSource == kCharsetFromUserForced) &&
+            EncodingUtils::IsAsciiCompatible(encoding)) {
+          // Honor override
+          return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
+            aFromSegment, aCount, aWriteCount);
+        }
+        mCharset.Assign(encoding);
         mCharsetSource = kCharsetFromMetaPrescan;
         mFeedChardet = false;
         mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
-        mMetaScanner = nullptr;
-        return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount,
-            aWriteCount);
+        return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
+          aFromSegment, aCount, aWriteCount);
       }
     }
+    if (mCharsetSource == kCharsetFromParentForced ||
+        mCharsetSource == kCharsetFromUserForced) {
+      // meta not found, honor override
+      return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
+        aFromSegment, aCount, aWriteCount);
+    }
     return FinalizeSniffing(aFromSegment, aCount, aWriteCount,
         countToSniffingLimit);
   }
 
   // not the last buffer
   if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
     nsHtml5ByteReadable readable(aFromSegment, aFromSegment + aCount);
-    mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
-    if (mUnicodeDecoder) {
-      // meta scan successful
+    nsAutoCString encoding;
+    mMetaScanner->sniff(&readable, encoding);
+    if (!encoding.IsEmpty()) {
+      // meta scan successful; honor overrides unless meta is XSS-dangerous
+      if ((mCharsetSource == kCharsetFromParentForced ||
+           mCharsetSource == kCharsetFromUserForced) &&
+          EncodingUtils::IsAsciiCompatible(encoding)) {
+        // Honor override
+        return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
+            aCount, aWriteCount);
+      }
+      mCharset.Assign(encoding);
       mCharsetSource = kCharsetFromMetaPrescan;
       mFeedChardet = false;
       mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
-      mMetaScanner = nullptr;
-      return WriteSniffingBufferAndCurrentSegment(aFromSegment, 
-                                                  aCount,
-                                                  aWriteCount);
+      return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
+        aCount, aWriteCount);
     }
   }
 
   if (!mSniffingBuffer) {
     const mozilla::fallible_t fallible = mozilla::fallible_t();
     mSniffingBuffer = new (fallible)
       uint8_t[NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE];
     if (!mSniffingBuffer) {
@@ -970,19 +982,21 @@ nsHtml5StreamParser::OnStartRequest(nsIR
     return NS_OK;
   }
 
   // We are reloading a document.open()ed doc.
   mReparseForbidden = true;
   mFeedChardet = false;
 
   // Instantiate the converter here to avoid BOM sniffing.
-  nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
+  nsCOMPtr<nsICharsetConverterManager> convManager =
+    do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
+  rv = convManager->GetUnicodeDecoderRaw(mCharset.get(),
+                                         getter_AddRefs(mUnicodeDecoder));
   // if we failed to get a decoder, there will be fallback, so don't propagate
   //  the error.
   if (NS_FAILED(rv)) {
     mCharsetSource = kCharsetFromFallback;
   }
   return NS_OK;
 }
 
--- a/parser/html/nsHtml5StreamParser.h
+++ b/parser/html/nsHtml5StreamParser.h
@@ -318,31 +318,16 @@ class nsHtml5StreamParser : public nsISt
      * @param aWriteCount  Return value for how many bytes got read from the
      *                     buffer.
      */
     nsresult SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment,
                                                                   uint32_t aCount,
                                                                   uint32_t* aWriteCount);
 
     /**
-     * Write the sniffing buffer into the Unicode decoder followed by the
-     * current network buffer.
-     *
-     * @param aFromSegment The current network buffer or null if the sniffing
-     *                     buffer is being flushed due to network stream ending.
-     * @param aCount       The number of bytes in aFromSegment (ignored if
-     *                     aFromSegment is null)
-     * @param aWriteCount  Return value for how many bytes got read from the
-     *                     buffer.
-     */
-    nsresult WriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment,
-                                                  uint32_t aCount,
-                                                  uint32_t* aWriteCount);
-
-    /**
      * Initialize the Unicode decoder, mark the BOM as the source and
      * drop the sniffer.
      *
      * @param aDecoderCharsetName The name for the decoder's charset
      *                            (UTF-16BE, UTF-16LE or UTF-8; the BOM has
      *                            been swallowed)
      */
     nsresult SetupDecodingFromBom(const char* aDecoderCharsetName);
--- a/testing/mochitest/b2g-desktop.json
+++ b/testing/mochitest/b2g-desktop.json
@@ -501,16 +501,17 @@
     "dom/indexedDB/test/test_app_isolation_inproc.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_app_isolation_oop.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_autoIncrement.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_autoIncrement_indexes.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_bfcache.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_blob_archive.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_blob_worker_crash.html": "Bug 931116, b2g desktop specific, bug 927889 still present",
     "dom/indexedDB/test/test_blob_simple.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_bug937006.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_clear.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_complex_keyPaths.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_count.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_create_index.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_create_index_with_integer_keys.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_create_objectStore.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_cursor_mutation.html": "Bug 931116, b2g desktop specific, initial triage",
     "dom/indexedDB/test/test_cursor_update_updates_indexes.html": "Bug 931116, b2g desktop specific, initial triage",
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -94,17 +94,19 @@ class MochitestRunner(MozbuildObject):
         build_path = os.path.join(self.topobjdir, 'build')
         if build_path not in sys.path:
             sys.path.append(build_path)
 
         self.tests_dir = os.path.join(self.topobjdir, '_tests')
         self.mochitest_dir = os.path.join(self.tests_dir, 'testing', 'mochitest')
         self.lib_dir = os.path.join(self.topobjdir, 'dist', 'lib')
 
-    def run_b2g_test(self, test_file=None, b2g_home=None, xre_path=None, **kwargs):
+    def run_b2g_test(self, test_file=None, b2g_home=None, xre_path=None,
+                     total_chunks=None, this_chunk=None, no_window=None,
+                     **kwargs):
         """Runs a b2g mochitest.
 
         test_file is a path to a test file. It can be a relative path from the
         top source directory, an absolute filename, or a directory containing
         test files.
         """
         # Need to call relpath before os.chdir() below.
         test_path = ''
@@ -139,16 +141,19 @@ class MochitestRunner(MozbuildObject):
             options.testPath = test_path
         elif conditions.is_b2g_desktop:
             options.testManifest = 'b2g-desktop.json'
         else:
             options.testManifest = 'b2g.json'
 
         for k, v in kwargs.iteritems():
             setattr(options, k, v)
+        options.noWindow = no_window
+        options.totalChunks = total_chunks
+        options.thisChunk = this_chunk
 
         options.consoleLevel = 'INFO'
         if conditions.is_b2g_desktop(self):
             if self.substs.get('ENABLE_MARIONETTE') != '1':
                 print(MARIONETTE_DISABLED % ('mochitest-b2g-desktop',
                                              self.mozconfig['path']))
                 return 1
 
--- a/xpcom/threads/ThreadStackHelper.cpp
+++ b/xpcom/threads/ThreadStackHelper.cpp
@@ -45,18 +45,21 @@ ThreadStackHelper::Shutdown()
   if (sInitialized == 1) {
     MOZ_ALWAYS_TRUE(!::sem_destroy(&sSem));
   }
   sInitialized--;
 #endif
 }
 
 ThreadStackHelper::ThreadStackHelper()
-  : mPseudoStack(mozilla_get_pseudo_stack())
-  , mStackBuffer()
+  :
+#ifdef MOZ_ENABLE_PROFILER_SPS
+    mPseudoStack(mozilla_get_pseudo_stack()),
+#endif
+    mStackBuffer()
   , mMaxStackSize(mStackBuffer.capacity())
 {
 #if defined(XP_LINUX)
   mThreadID = ::syscall(SYS_gettid);
 #elif defined(XP_WIN)
   mInitialized = !!::DuplicateHandle(
     ::GetCurrentProcess(), ::GetCurrentThread(),
     ::GetCurrentProcess(), &mThreadID,
@@ -142,34 +145,40 @@ ThreadStackHelper::SigAction(int aSignal
   ::sem_post(&sSem);
 }
 
 #endif // XP_LINUX
 
 bool
 ThreadStackHelper::PrepareStackBuffer(Stack& aStack) {
   aStack.clear();
+#ifdef MOZ_ENABLE_PROFILER_SPS
   if (!mPseudoStack) {
     return false;
   }
   mStackBuffer.clear();
   return mStackBuffer.reserve(mMaxStackSize);
+#else
+  return false;
+#endif
 }
 
 void
 ThreadStackHelper::FillStackBuffer() {
+#ifdef MOZ_ENABLE_PROFILER_SPS
   size_t reservedSize = mMaxStackSize;
 
   // Go from front to back
   const volatile StackEntry* entry = mPseudoStack->mStack;
   const volatile StackEntry* end = entry + mPseudoStack->stackSize();
   for (; reservedSize-- && entry != end; entry++) {
     /* We only accept non-copy labels, because
        we are unable to actually copy labels here */
     if (!entry->isCopyLabel()) {
       mStackBuffer.infallibleAppend(entry->label());
     }
   }
   // If we exited early due to buffer size, expand the buffer for next time
   mMaxStackSize += (end - entry);
+#endif
 }
 
 } // namespace mozilla
--- a/xpcom/threads/ThreadStackHelper.h
+++ b/xpcom/threads/ThreadStackHelper.h
@@ -35,17 +35,19 @@ namespace mozilla {
  * with custom text and markers are not included.
  */
 class ThreadStackHelper
 {
 public:
   typedef Telemetry::HangHistogram::Stack Stack;
 
 private:
+#ifdef MOZ_ENABLE_PROFILER_SPS
   const PseudoStack* const mPseudoStack;
+#endif
   Stack mStackBuffer;
   size_t mMaxStackSize;
 
   bool PrepareStackBuffer(Stack& aStack);
   void FillStackBuffer();
 
 public:
   /**