text:
title: "Spargel Graph Processing API"
---

* This will be replaced by the TOC
{:toc}

Spargel is our [Giraph](http://giraph.apache.org) like **graph processing** Java API. It supports basic graph computations, which are run as a sequence of [supersteps](iterations.html#supersteps). Spargel and Giraph both implement the [Bulk Synchronous Parallel (BSP)](https://en.wikipedia.org/wiki/Bulk_Synchronous_Parallel) programming model, propsed by Google's [Pregel](http://googleresearch.blogspot.de/2009/06/large-scale-graph-computing-at-google.html).

The API provides a **vertex-centric** view on graph processing with two basic operations per superstep:

  1. **Send messages** to other vertices, and
  2. **Receive messages** from other vertices and **update own vertex state**.

This vertex-centric view makes it easy to express a large class of graph problems efficiently. We will list all *relevant interfaces* of the **Spargel API** to implement and walk through an **example Spargel program**.

Spargel API
-----------

The Spargel API is part of the *addons* Maven project. All relevant classes are located in the *org.apache.flink.spargel.java* package.

Add the following dependency to your `pom.xml` to use the Spargel.

~~~xml
<dependency>
	<groupId>org.apache.flink</groupId>
	<artifactId>flink-spargel</artifactId>
	<version>{{site.FLINK_VERSION_STABLE}}</version>
</dependency>
~~~

Extend **VertexUpdateFunction<***VertexKeyType*, *VertexValueType*, *MessageType***>** to implement your *custom vertex update logic*.

Extend **MessagingFunction<***VertexKeyType*, *VertexValueType*, *MessageType*, *EdgeValueType***>** to implement your *custom message logic*.

Create a **SpargelIteration** operator to include Spargel in your data flow.

Example: Propagate Minimum Vertex ID in Graph
---------------------------------------------

The Spargel operator **SpargelIteration** includes Spargel graph processing into your data flow. As usual, it can be combined with other operators like *map*, *reduce*, *join*, etc.

~~~java
FileDataSource vertices = new FileDataSource(...);
FileDataSource edges = new FileDataSource(...);

SpargelIteration iteration = new SpargelIteration(new MinMessager(), new MinNeighborUpdater());
iteration.setVertexInput(vertices);
iteration.setEdgesInput(edges);
iteration.setNumberOfIterations(maxIterations);

FileDataSink result = new FileDataSink(...);
result.setInput(iteration.getOutput());

new Plan(result);
~~~

Besides the **program logic** of vertex updates in *MinNeighborUpdater* and messages in *MinMessager*, you have to specify the **initial vertex** and **edge input**. Every vertex has a **key** and **value**. In each superstep, it **receives messages** from other vertices and updates its state:

  - **Vertex** input: **(id**: *VertexKeyType*, **value**: *VertexValueType***)**
  - **Edge** input: **(source**: *VertexKeyType*, **target**: *VertexKeyType*[, **value**: *EdgeValueType*])

For our example, we set the vertex ID as both *id and value* (initial minimum) and *leave out the edge values* as we don't need them:

In order to **propagate the minimum vertex ID**, we iterate over all received messages (which contain the neighboring IDs) and update our value, if we found a new minimum:

~~~java
public class MinNeighborUpdater extends VertexUpdateFunction<IntValue, IntValue, IntValue> {

	@Override
	public void updateVertex(IntValue id, IntValue currentMin, Iterator<IntValue> messages) {
		int min = Integer.MAX_VALUE;

		// iterate over all received messages
		while (messages.hasNext()) {
			int next = messages.next().getValue();
			min = next < min ? next : min;
		}

		// update vertex value, if new minimum
		if (min < currentMin.getValue()) {
			setNewVertexValue(new IntValue(min));
		}
	}
}
~~~

The **messages in each superstep** consist of the **current minimum ID** seen by the vertex:

~~~java
public class MinMessager extends MessagingFunction<IntValue, IntValue, IntValue, NullValue> {

	@Override
	public void sendMessages(IntValue id, IntValue currentMin) {
		// send current minimum to neighbors
		sendMessageToAllNeighbors(currentMin);
    }
}
~~~

The **API-provided method** `sendMessageToAllNeighbors(MessageType)` sends the message to all neighboring vertices. It is also possible to address specific vertices with `sendMessageTo(VertexKeyType, MessageType)`.

If the value of a vertex does not change during a superstep, it will **not send** any messages in the superstep. This allows to do incremental updates to the **hot (changing) parts** of the graph, while leaving **cold (steady) parts** untouched.

The computation **terminates** after a specified *maximum number of supersteps* **-OR-** the *vertex states stop changing*.


text:
<!--
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="right"
    android:gravity="right"
    android:padding="4dp">

    <TextView
        android:id="@+id/date_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerInParent="false"
        android:layout_centerVertical="false"
        android:layout_marginTop="5dp"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="#999999"
        android:textSize="12sp"
        android:text="asdasdasdasdasdasdasd"
        android:layout_marginBottom="5dp"
        android:phoneNumber="false" />

    <RelativeLayout
        android:id="@+id/wrapper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/date_textview">

        <ImageView
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:id="@+id/profile_imageButton"
            android:clickable="false"
            android:focusable="false"
            android:background="@drawable/chat_profile_chatto5"
            android:layout_alignParentStart="true"
            android:layout_alignTop="@+id/content_layout"
            android:layout_marginLeft="5dp" />

        <RelativeLayout
            android:orientation="vertical"
            android:layout_width="256dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="52dp"
            android:layout_centerVertical="true"
            android:gravity="left"
            android:id="@+id/content_layout"
            android:layout_marginRight="10dp"
            android:background="@drawable/chat_left_bg">

            <TextView
                android:id="@+id/chat_content_textview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/chat_left_bg"
                android:lineSpacingExtra="2dp"
                android:textColor="@color/chat_item_server_textcolor"
                android:textSize="@dimen/font_size"
                android:text="asdasdasdasdasdsadsajfjksdhfjkashfljakhfjashfjkhasldfhasjdfhlasdfhlasdhfajskdhfajklsfsdasf"
                android:autoLink="web"
                android:layout_gravity="center_vertical"
                android:layout_alignParentLeft="false"
                android:layout_alignParentTop="false" />

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/chat_loc_image_wrapper"
                android:layout_below="@+id/chat_content_textview">

                <ImageView
                    android:id="@+id/chat_content_imageview"
                    android:layout_width="256dp"
                    android:layout_height="196dp"
                    android:background="@drawable/chat_left_bg"
                    android:scaleType="centerInside"
                    android:adjustViewBounds="false"
                    android:layout_gravity="center_vertical"
                    android:layout_alignParentLeft="true" />

                <ProgressBar
                    style="?android:attr/progressBarStyleHorizontal"
                    android:layout_width="150dp"
                    android:layout_height="10dp"
                    android:id="@+id/chat_pending_progressBar"
                    android:layout_gravity="center"
                    android:progressDrawable="@drawable/chat_progressbar"
                    android:layout_alignParentLeft="false"
                    android:layout_alignParentTop="false"
                    android:layout_centerInParent="true"
                    android:layout_alignWithParentIfMissing="false"
                    android:visibility="gone" />
            </RelativeLayout>

        </RelativeLayout>

    </RelativeLayout>

</RelativeLayout>

redpajama_set_name: RedPajamaGithub


text:
<?php

$poolinfo=$sqlite->search("select * from pool where id='$id'");
$poolinfo=$poolinfo[0];
if($poolinfo){
    $membersq="select distinct server.name,server.id,server.env from server
        left join poolservermap on poolservermap.serverid = server.id
        where poolservermap.poolid = $id order by env asc";
    $poolmembers=$sqlite->search($membersq);

    echo "
Pool
";
    echo "";
    echo "
";
    echo "
".$poolinfo['name']." [".count($poolmembers)."]

";
    $servnameparts=explode("-",$poolinfo['name']);
    $lookupname=$servnameparts[0];
    echo "Docs (worth a shot)";
    echo "

";
    if($poolmembers){
        $envs=array();
        foreach($poolmembers as $box){
                $envs[$box['env']][]=$box;
         }
        foreach($envs as $env=>$boxes){
            echo "
".strtoupper($env)."
";
            foreach($boxes as $box){
                echo "
".$box['name']."
".$box['env']."
";
            }
            echo "

";
        }
    }
    echo "
";

}

?>


text:
"""
This example solves a plug flow reactor problem, where the chemistry is
surface chemistry. The specific problem simulated is the partial oxidation of
methane over a platinum catalyst in a packed bed reactor.
"""

import csv

import cantera as ct

# unit conversion factors to SI
cm = 0.01
minute = 60.0

#######################################################################
# Input Parameters
#######################################################################

tc = 800.0  # Temperature in Celsius
length = 0.3 * cm  # Catalyst bed length
area = 1.0 * cm**2  # Catalyst bed area
cat_area_per_vol = 1000.0 / cm  # Catalyst particle surface area per unit volume
velocity = 40.0 * cm / minute  # gas velocity
porosity = 0.3  # Catalyst bed porosity

# input file containing the surface reaction mechanism
cti_file = 'methane_pox_on_pt.cti'

output_filename = 'surf_pfr_output.csv'

# The PFR will be simulated by a chain of 'NReactors' stirred reactors.
NReactors = 201
dt = 1.0

#####################################################################

t = tc + 273.15  # convert to Kelvin

# import the gas model and set the initial conditions
gas = ct.Solution(cti_file, 'gas')
gas.TPX = t, ct.one_atm, 'CH4:1, O2:1.5, AR:0.1'

# import the surface model
surf = ct.Interface(cti_file,'Pt_surf', [gas])
surf.TP = t, ct.one_atm

rlen = length/(NReactors-1)
rvol = area * rlen * porosity

outfile = open(output_filename,'w')
writer = csv.writer(outfile)
writer.writerow(['Distance (mm)', 'T (C)', 'P (atm)'] +
                gas.species_names + surf.species_names)

# catalyst area in one reactor
cat_area = cat_area_per_vol * rvol

mass_flow_rate = velocity * gas.density * area

# The plug flow reactor is represented by a linear chain of zero-dimensional
# reactors. The gas at the inlet to the first one has the specified inlet
# composition, and for all others the inlet composition is fixed at the
# composition of the reactor immediately upstream. Since in a PFR model there
# is no diffusion, the upstream reactors are not affected by any downstream
# reactors, and therefore the problem may be solved by simply marching from
# the first to last reactor, integrating each one to steady state.

TDY = gas.TDY
cov = surf.coverages

print('    distance       X_CH4        X_H2        X_CO')

# create a new reactor
gas.TDY = TDY
r = ct.IdealGasReactor(gas, energy='off')
r.volume = rvol

# create a reservoir to represent the reactor immediately upstream. Note
# that the gas object is set already to the state of the upstream reactor
upstream = ct.Reservoir(gas, name='upstream')

# create a reservoir for the reactor to exhaust into. The composition of
# this reservoir is irrelevant.
downstream = ct.Reservoir(gas, name='downstream')

# use a 'Wall' object to implement the reacting surface in the reactor.
# Since walls have to be installed between two reactors/reservoirs, we'll
# install it between the upstream reservoir and the reactor.  The area is
# set to the desired catalyst area in the reactor, and surface reactions
# are included only on the side facing the reactor.
w = ct.Wall(upstream, r, A=cat_area, kinetics=[None, surf])

# The mass flow rate into the reactor will be fixed by using a
# MassFlowController object.
m = ct.MassFlowController(upstream, r, mdot=mass_flow_rate)

# We need an outlet to the downstream reservoir. This will determine the
# pressure in the reactor. The value of K will only affect the transient
# pressure difference.
v = ct.PressureController(r, downstream, master=m, K=1e-5)

sim = ct.ReactorNet([r])
sim.max_err_test_fails = 12

# set relative and absolute tolerances on the simulation
sim.rtol = 1.0e-9
sim.atol = 1.0e-21

for n in range(NReactors):
    # Set the state of the reservoir to match that of the previous reactor
    gas.TDY = r.thermo.TDY
    upstream.syncState()
    sim.reinitialize()
    sim.advance_to_steady_state()
    dist = n * rlen * 1.0e3   # distance in mm

    if not n % 10:
        print('  {0:10f}  {1:10f}  {2:10f}  {3:10f}'.format(dist, *gas['CH4','H2','CO'].X))

    # write the gas mole fractions and surface coverages vs. distance
    writer.writerow([dist, r.T - 273.15, r.thermo.P/ct.one_atm] +
                    list(gas.X) + list(surf.coverages))

outfile.close()
print("Results saved to '{0}'".format(output_filename))


text:
<?php

// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

defined('MOODLE_INTERNAL') || die();

$string['cathidden'] = '';
$string['disableenrolhelp'] = 'Desactivar la matriculación en lugar de darles de baja. Evita la posible pérdida de datos en algunas versiones y configuraciones de Moodle cuando los usuarios se eliminan y se vuelven a añadir a un curso.';
$string['lmb:unenrol'] = 'Dar de baja alumnos del curso';
$string['lmb:unenrolself'] = 'Darse de baja del curso';
$string['unenrolmember'] = 'Dar de baja miembros de un curso cuando se indique';
$string['unenrolmemberhelp'] = 'Dar de baja miembros de un curso cuando se reciba un un mensaje XML apropiado.';


text:
This provides a framework to monitor the long running scenarios through Prometheus queries.

## Setup

Ensure you have all dependencies with `pip3 install -r requirements.txt`.

## Running Tests

`./check_metrics.py`

## Writing Tests

Scenarios that need to be tested should be added to [test_cases.py](test_cases.py).

Note that the `queries` variable should contain the list of all tests.

For each thing we want to test, we create a Query object. Here is an example:

```python
Query(
    'Total requests', # Description of the query
    'sum(rate(istio_requests_total{}[10m]))', # Prometheus query
    Alarm(
        lambda qps: qps < 30, # This test will fail if this function returns True
        'Expect at least 30qps' # Failure message
    )
)
```

This example queries for the number of queries per second in total over a 10 minute period. It then asserts there are at least 30 qps.

Currently, the Prometheus query must return a single result, so `sum` is useful.

See the [Prometheus docs](https://prometheus.io/docs/prometheus/latest/querying/basics/) for more info.


text:
/**
 * The package is for the test task:
 * 7. Implement the game bomber man.
 *
 * The third version of the task.
 *
 * @author Alex Proshak (olexandr_proshak@ukr.net)
 */
package ru.job4j.bomberv2;


text:
// Yammer Group Functionlity.

SPOC.Yam.Feed.prototype.posts = function() {

    // save reference to this
    var _this = this;

    // Create object to store public methods
    var methods = {};

    // Default api endpoint to all messages
    var apiUrl = "messages/following.json";

    // If an id is passed and feedtype, formuate new endpoint
    if (_this.feedId) {
        apiUrl = "messages/" + (_this.feedType ? "in_group" : "from_user") + "/" + _this.feedId + ".json";
    }

    /**
     * Queries a Yammer Group and returns feed items
     * @return promise
     */
    methods.query = function(settings) {
        return new Promise(function(resolve, reject) {
            // Check user has access token and then then return group feed.
            SPOC.Utils.Yammer.checkLogin().then(function(result) {
                if (result) {
                    yam.platform.request({
                        url: apiUrl,
                        method: "GET",
                        data: settings ? settings : null,
                        success: function(data) {
                            // Format response to combine references with messages
                            data = SPOC.Utils.Yammer.formatFeedResponse(data);
                            resolve(data);
                        },
                        error: function(data) {
                            reject(data);
                        }
                    });
                } else {
                    resolve(false);
                }
            });
        });
    };

    return methods;

};


text:
function StatsReporter() {
  this.addedCount = 0;
  this.skippedCount = 0;
  this.passedCount = 0;
  this.failedCount = 0;
}

StatsReporter.prototype.testAdded = function(test) {
  this.addedCount++;
};

StatsReporter.prototype.testSkipped = function(test) {
  this.skippedCount++;
};

StatsReporter.prototype.testPassed = function(test) {
  this.passedCount++;
};

StatsReporter.prototype.testFailed = function(test, err, stepIdx) {
  this.failedCount++;
};

exports = module.exports = StatsReporter;


text:
import unittest

import aioppspp.channel_ids
import aioppspp.datagrams

class DatagramsTestCase(unittest.TestCase):

    def test_decode_encode_empty(self):
        data = bytes(aioppspp.channel_ids.new())

        datagram = aioppspp.datagrams.decode(memoryview(data))
        self.assertIsInstance(datagram, aioppspp.datagrams.Datagram)
        self.assertIsInstance(datagram.channel_id,
                              aioppspp.channel_ids.ChannelID)
        self.assertEqual(datagram.channel_id, data)
        self.assertEqual(datagram.messages, tuple())

        encoded_datagram = aioppspp.datagrams.encode(datagram)
        self.assertIsInstance(encoded_datagram, bytes)
        self.assertEqual(encoded_datagram, data)


text:
class ExtensionPrefValueMap;
class PrefService;

namespace base {
class Clock;
}

namespace content {
class BrowserContext;
}

namespace prefs {
class DictionaryValueUpdate;
}

namespace user_prefs {
class PrefRegistrySyncable;
}

namespace extensions {

class AppSorting;
class EarlyExtensionPrefsObserver;
class ExtensionPrefsObserver;
class URLPatternSet;

// Class for managing global and per-extension preferences.
//
// This class distinguishes the following kinds of preferences:
// - global preferences:
//       internal state for the extension system in general, not associated
//       with an individual extension, such as lastUpdateTime.
// - per-extension preferences:
//       meta-preferences describing properties of the extension like
//       installation time, whether the extension is enabled, etc.
// - extension controlled preferences:
//       browser preferences that an extension controls. For example, an
//       extension could use the proxy API to specify the browser's proxy
//       preference. Extension-controlled preferences are stored in
//       PrefValueStore::extension_prefs(), which this class populates and
//       maintains as the underlying extensions change.
class ExtensionPrefs : public KeyedService {
 public:
  using ExtensionsInfo = std::vector<std::unique_ptr<ExtensionInfo>>;

  // Vector containing identifiers for preferences.
  typedef std::set<std::string> PrefKeySet;

  // This enum is used to store the reason an extension's install has been
  // delayed.  Do not remove items or re-order this enum as it is used in
  // preferences.
  enum DelayReason {
    DELAY_REASON_NONE = 0,
    DELAY_REASON_GC = 1,
    DELAY_REASON_WAIT_FOR_IDLE = 2,
    DELAY_REASON_WAIT_FOR_IMPORTS = 3,
    DELAY_REASON_WAIT_FOR_OS_UPDATE = 4,
  };

  // This enum is used to specify the operation for bit map prefs.
  enum BitMapPrefOperation {
    BIT_MAP_PREF_ADD,
    BIT_MAP_PREF_REMOVE,
    BIT_MAP_PREF_REPLACE,
    BIT_MAP_PREF_CLEAR
  };

  // Wrappers around a prefs::ScopedDictionaryPrefUpdate, which allow us to
  // access the entry of a particular key for an extension. Use these if you
  // need a mutable record of a dictionary or list in the current settings.
  // Otherwise, prefer ReadPrefAsT() and UpdateExtensionPref() methods.
  class ScopedDictionaryUpdate {
   public:
    ScopedDictionaryUpdate(ExtensionPrefs* prefs,
                           const std::string& extension_id,
                           const std::string& key);

    ScopedDictionaryUpdate(const ScopedDictionaryUpdate&) = delete;
    ScopedDictionaryUpdate& operator=(const ScopedDictionaryUpdate&) = delete;

    ~ScopedDictionaryUpdate();

    // Returns a mutable value for the key, if one exists. Otherwise, returns
    // NULL.
    std::unique_ptr<prefs::DictionaryValueUpdate> Get();

    // Creates and returns a mutable value for the key, if one does not already
    // exist. Otherwise, returns the current value.
    std::unique_ptr<prefs::DictionaryValueUpdate> Create();

   private:
    std::unique_ptr<prefs::ScopedDictionaryPrefUpdate> update_;
    const std::string key_;
  };

  class ScopedListUpdate {
   public:
    ScopedListUpdate(ExtensionPrefs* prefs,
                     const std::string& extension_id,
                     const std::string& key);

    ScopedListUpdate(const ScopedListUpdate&) = delete;
    ScopedListUpdate& operator=(const ScopedListUpdate&) = delete;

    ~ScopedListUpdate();

    // Returns a mutable value for the key (ownership remains with the prefs),
    // if one exists. Otherwise, returns NULL.
    base::ListValue* Get();

    // Creates and returns a mutable value for the key (the prefs own the new
    // value), if one does not already exist. Otherwise, returns the current
    // value.
    base::ListValue* Create();

   private:
    std::unique_ptr<prefs::ScopedDictionaryPrefUpdate> update_;
    const std::string key_;
  };

  // Creates an ExtensionPrefs object.
  // Does not take ownership of |prefs| or |extension_pref_value_map|.
  // If |extensions_disabled| is true, extension controlled preferences and
  // content settings do not become effective. EarlyExtensionPrefsObservers
  // should be included in |early_observers| if they need to observe events
  // which occur during initialization of the ExtensionPrefs object.
  static ExtensionPrefs* Create(
      content::BrowserContext* browser_context,
      PrefService* prefs,
      const base::FilePath& root_dir,
      ExtensionPrefValueMap* extension_pref_value_map,
      bool extensions_disabled,
      const std::vector<EarlyExtensionPrefsObserver*>& early_observers);

  // A version of Create which allows injection of a custom base::Time provider.
  // Use this as needed for testing.
  static ExtensionPrefs* Create(
      content::BrowserContext* browser_context,
      PrefService* prefs,
      const base::FilePath& root_dir,
      ExtensionPrefValueMap* extension_pref_value_map,
      bool extensions_disabled,
      const std::vector<EarlyExtensionPrefsObserver*>& early_observers,
      base::Clock* clock);

  ExtensionPrefs(const ExtensionPrefs&) = delete;
  ExtensionPrefs& operator=(const ExtensionPrefs&) = delete;

  ~ExtensionPrefs() override;

  // Convenience function to get the ExtensionPrefs for a BrowserContext.
  static ExtensionPrefs* Get(content::BrowserContext* context);

  // Add or remove an observer from the ExtensionPrefs.
  void AddObserver(ExtensionPrefsObserver* observer);
  void RemoveObserver(ExtensionPrefsObserver* observer);

  // Returns true if the specified external extension was uninstalled by the
  // user.
  bool IsExternalExtensionUninstalled(const std::string& id) const;

  // Checks whether |extension_id| is disabled. If there's no state pref for
  // the extension, this will return false. Generally you should use
  // ExtensionService::IsExtensionEnabled instead.
  // Note that blocklisted extensions are NOT marked as disabled!
  bool IsExtensionDisabled(const std::string& id) const;

  // Get/Set the order that the browser actions appear in the toolbar.
  // TODO(devlin): Remove this. The pref is no longer used.
  ExtensionIdList GetToolbarOrder() const;
  void SetToolbarOrder(const ExtensionIdList& extension_ids);

  // Get/Set the set of extensions that are pinned to the toolbar. Only used
  // when the experiment ExtensionsMenu is active."
  // TODO(crbug.com/943702): Remove reference to experiment when it launches or
  // remove code if it does not.
  ExtensionIdList GetPinnedExtensions() const;
  void SetPinnedExtensions(const ExtensionIdList& extension_ids);

  // Called when an extension is installed, so that prefs get created.
  // If |page_ordinal| is invalid then a page will be found for the App.
  // |install_flags| are a bitmask of extension::InstallFlags.
  // |ruleset_install_prefs| contains install prefs needed for the Declarative
  // Net Request API.
  void OnExtensionInstalled(const Extension* extension,
                            Extension::State initial_state,
                            const syncer::StringOrdinal& page_ordinal,
                            int install_flags,
                            const std::string& install_parameter,
                            const declarative_net_request::RulesetInstallPrefs&
                                ruleset_install_prefs);
  // OnExtensionInstalled with no install flags and |ruleset_install_prefs|.
  void OnExtensionInstalled(const Extension* extension,
                            Extension::State initial_state,
                            const syncer::StringOrdinal& page_ordinal,
                            const std::string& install_parameter) {
    OnExtensionInstalled(extension, initial_state, page_ordinal,
                         kInstallFlagNone, install_parameter, {});
  }

  // Called when an extension is uninstalled, so that prefs get cleaned up.
  void OnExtensionUninstalled(const std::string& extension_id,
                              const mojom::ManifestLocation location,
                              bool external_uninstall);

  // Sets the extension's state to enabled and clears disable reasons.
  void SetExtensionEnabled(const std::string& extension_id);

  // Sets the extension's state to disabled and sets the disable reasons.
  // However, if the current state is EXTERNAL_EXTENSION_UNINSTALLED then that
  // is preserved (but the disable reasons are still set).
  void SetExtensionDisabled(const std::string& extension_id,
                            int disable_reasons);

  // Gets the value of a bit map pref. Gets the value of
  // |extension_id| from |pref_key|. If the value is not found or invalid,
  // return the |default_bit|.
  int GetBitMapPrefBits(const std::string& extension_id,
                        base::StringPiece pref_key,
                        int default_bit) const;
  // Modifies the extensions bit map pref |pref_key| to add a new bit value,
  // remove an existing bit value, or clear all bits. If |operation| is
  // BIT_MAP_PREF_CLEAR, then |pending_bits| are ignored. If the updated pref
  // value is the same as the |default_bit|, the pref value will be set to null.
  void ModifyBitMapPrefBits(const std::string& extension_id,
                            int pending_bits,
                            BitMapPrefOperation operation,
                            base::StringPiece pref_key,
                            int default_bit);

  // Gets or sets profile wide ExtensionPrefs.
  void SetIntegerPref(const PrefMap& pref, int value);
  void SetBooleanPref(const PrefMap& pref, bool value);
  void SetStringPref(const PrefMap& pref, const std::string& value);
  void SetTimePref(const PrefMap& pref, base::Time value);
  void SetGURLPref(const PrefMap& pref, const GURL& value);
  void SetDictionaryPref(const PrefMap& pref,
                         std::unique_ptr<base::DictionaryValue> value);

  int GetPrefAsInteger(const PrefMap& pref) const;
  bool GetPrefAsBoolean(const PrefMap& pref) const;
  std::string GetPrefAsString(const PrefMap& pref) const;
  base::Time GetPrefAsTime(const PrefMap& pref) const;
  GURL GetPrefAsGURL(const PrefMap& pref) const;
  const base::DictionaryValue* GetPrefAsDictionary(const PrefMap& pref) const;

  // Returns a wrapper that allows to update an ExtensionPref with a
  // PrefType::kDictionary.
  std::unique_ptr<prefs::ScopedDictionaryPrefUpdate> CreatePrefUpdate(
      const PrefMap& pref);

  // Increments/decrements an ExtensionPref with a PrefType::kInteger.
  void IncrementPref(const PrefMap& pref);
  void DecrementPref(const PrefMap& pref);

  // Populates |out| with the ids of all installed extensions.
  void GetExtensions(ExtensionIdList* out) const;

  void SetIntegerPref(const std::string& id, const PrefMap& pref, int value);
  void SetBooleanPref(const std::string& id, const PrefMap& pref, bool value);
  void SetStringPref(const std::string& id,
                     const PrefMap& pref,
                     const std::string value);
  void SetListPref(const std::string& id,
                   const PrefMap& pref,
                   base::Value value);
  void SetDictionaryPref(const std::string& id,
                         const PrefMap& pref,
                         std::unique_ptr<base::DictionaryValue> value);
  void SetTimePref(const std::string& id,
                   const PrefMap& pref,
                   const base::Time value);

  void UpdateExtensionPref(const std::string& id,
                           base::StringPiece key,
                           std::unique_ptr<base::Value> value);

  void DeleteExtensionPrefs(const std::string& id);

  void DeleteExtensionPrefsIfPrefEmpty(const std::string& id);

  bool ReadPrefAsBoolean(const std::string& extension_id,
                         const PrefMap& pref,
                         bool* out_value) const;

  bool ReadPrefAsInteger(const std::string& extension_id,
                         const PrefMap& pref,
                         int* out_value) const;

  bool ReadPrefAsString(const std::string& extension_id,
                        const PrefMap& pref,
                        std::string* out_value) const;

  bool ReadPrefAsList(const std::string& extension_id,
                      const PrefMap& pref,
                      const base::ListValue** out_value) const;

  bool ReadPrefAsDictionary(const std::string& extension_id,
                            const PrefMap& pref,
                            const base::DictionaryValue** out_value) const;

  base::Time ReadPrefAsTime(const std::string& extension_id,
                            const PrefMap& pref) const;

  bool ReadPrefAsBoolean(const std::string& extension_id,
                         base::StringPiece pref_key,
                         bool* out_value) const;

  bool ReadPrefAsInteger(const std::string& extension_id,
                         base::StringPiece pref_key,
                         int* out_value) const;

  bool ReadPrefAsString(const std::string& extension_id,
                        base::StringPiece pref_key,
                        std::string* out_value) const;

  bool ReadPrefAsList(const std::string& extension_id,
                      base::StringPiece pref_key,
                      const base::ListValue** out_value) const;

  bool ReadPrefAsDictionary(const std::string& extension_id,
                            base::StringPiece pref_key,
                            const base::DictionaryValue** out_value) const;

  // Interprets the list pref, |pref_key| in |extension_id|'s preferences, as a
  // URLPatternSet. The |valid_schemes| specify how to parse the URLPatterns.
  bool ReadPrefAsURLPatternSet(const std::string& extension_id,
                               base::StringPiece pref_key,
                               URLPatternSet* result,
                               int valid_schemes) const;

  // Converts |set| to a list of strings and sets the |pref_key| pref belonging
  // to |extension_id|. If |set| is empty, the preference for |pref_key| is
  // cleared.
  void SetExtensionPrefURLPatternSet(const std::string& extension_id,
                                     base::StringPiece pref_key,
                                     const URLPatternSet& set);

  bool HasPrefForExtension(const std::string& extension_id) const;

  // Did the extension ask to escalate its permission during an upgrade?
  bool DidExtensionEscalatePermissions(const std::string& id) const;

  // Getters and setters for disabled reason.
  // Note that you should rarely need to modify disable reasons directly -
  // pass the proper value to SetExtensionState instead when you enable/disable
  // an extension. In particular, AddDisableReason(s) is only legal when the
  // extension is not enabled.
  int GetDisableReasons(const std::string& extension_id) const;
  bool HasDisableReason(const std::string& extension_id,
                        disable_reason::DisableReason disable_reason) const;
  void AddDisableReason(const std::string& extension_id,
                        disable_reason::DisableReason disable_reason);
  void AddDisableReasons(const std::string& extension_id, int disable_reasons);
  void RemoveDisableReason(const std::string& extension_id,
                           disable_reason::DisableReason disable_reason);
  void ReplaceDisableReasons(const std::string& extension_id,
                             int disable_reasons);
  void ClearDisableReasons(const std::string& extension_id);

  // Clears disable reasons that do not apply to component extensions.
  void ClearInapplicableDisableReasonsForComponentExtension(
      const std::string& component_extension_id);

  // Returns the version string for the currently installed extension, or
  // the empty string if not found.
  std::string GetVersionString(const std::string& extension_id) const;

  // Re-writes the extension manifest into the prefs.
  // Called to change the extension's manifest when it's re-localized.
  void UpdateManifest(const Extension* extension);

  // Returns base extensions install directory.
  const base::FilePath& install_directory() const { return install_directory_; }

  // For updating the prefs when the install location is changed for the
  // extension.
  void SetInstallLocation(const std::string& extension_id,
                          mojom::ManifestLocation location);

  // Increment the count of how many times we prompted the user to acknowledge
  // the given extension, and return the new count.
  int IncrementAcknowledgePromptCount(const std::string& extension_id);

  // Whether the user has acknowledged an external extension.
  bool IsExternalExtensionAcknowledged(const std::string& extension_id) const;
  void AcknowledgeExternalExtension(const std::string& extension_id);

  // Whether the user has acknowledged a blocklisted extension.
  bool IsBlocklistedExtensionAcknowledged(
      const std::string& extension_id) const;
  void AcknowledgeBlocklistedExtension(const std::string& extension_id);

  // Whether the external extension was installed during the first run
  // of this profile.
  bool IsExternalInstallFirstRun(const std::string& extension_id) const;
  void SetExternalInstallFirstRun(const std::string& extension_id);

  // Returns true if the extension notification code has already run for the
  // first time for this profile. Currently we use this flag to mean that any
  // extensions that would trigger notifications should get silently
  // acknowledged. This is a fuse. Calling it the first time returns false.
  // Subsequent calls return true. It's not possible through an API to ever
  // reset it. Don't call it unless you mean it!
  bool SetAlertSystemFirstRun();

  // Returns the last value set via SetLastPingDay. If there isn't such a
  // pref, the returned Time will return true for is_null().
  base::Time LastPingDay(const std::string& extension_id) const;

  // The time stored is based on the server's perspective of day start time, not
  // the client's.
  void SetLastPingDay(const std::string& extension_id, const base::Time& time);

  // Similar to the 2 above, but for the extensions blocklist.
  base::Time BlocklistLastPingDay() const;
  void SetBlocklistLastPingDay(const base::Time& time);

  // Similar to LastPingDay/SetLastPingDay, but for sending "days since active"
  // ping.
  base::Time LastActivePingDay(const std::string& extension_id) const;
  void SetLastActivePingDay(const std::string& extension_id,
                            const base::Time& time);

  // A bit we use for determining if we should send the "days since active"
  // ping. A value of true means the item has been active (launched) since the
  // last update check.
  bool GetActiveBit(const std::string& extension_id) const;
  void SetActiveBit(const std::string& extension_id, bool active);

  // Returns the granted permission set for the extension with |extension_id|,
  // and NULL if no preferences were found for |extension_id|.
  // This passes ownership of the returned set to the caller.
  std::unique_ptr<const PermissionSet> GetGrantedPermissions(
      const std::string& extension_id) const;

  // Adds |permissions| to the granted permissions set for the extension with
  // |extension_id|. The new granted permissions set will be the union of
  // |permissions| and the already granted permissions.
  void AddGrantedPermissions(const std::string& extension_id,
                             const PermissionSet& permissions);

  // As above, but subtracts the given |permissions| from the granted set.
  void RemoveGrantedPermissions(const std::string& extension_id,
                                const PermissionSet& permissions);

  // Gets the active permission set for the specified extension. This may
  // differ from the permissions in the manifest due to the optional
  // permissions API. This passes ownership of the set to the caller.
  std::unique_ptr<const PermissionSet> GetActivePermissions(
      const std::string& extension_id) const;

  // Sets the active |permissions| for the extension with |extension_id|.
  void SetActivePermissions(const std::string& extension_id,
                            const PermissionSet& permissions);

  // Sets/Gets the value indicating if an extension should be granted all the
  // requested host permissions without requiring explicit runtime-granted
  // permissions from the user.
  void SetWithholdingPermissions(const ExtensionId& extension_id,
                                 bool should_withhold);
  bool GetWithholdingPermissions(const ExtensionId& extension_id) const;

  // Returns the set of runtime-granted permissions. These are permissions that
  // the user explicitly approved at runtime, rather than install time (such
  // as those granted through the permissions API or the runtime host
  // permissions feature). Note that, similar to granted permissions, this can
  // include permissions granted to the extension, even if they are not active.
  std::unique_ptr<const PermissionSet> GetRuntimeGrantedPermissions(
      const ExtensionId& extension_id) const;

  // Adds to the set of runtime-granted permissions.
  void AddRuntimeGrantedPermissions(const ExtensionId& extension_id,
                                    const PermissionSet& permissions);

  // Removes from the set of runtime-granted permissions.
  void RemoveRuntimeGrantedPermissions(const ExtensionId& extension_id,
                                       const PermissionSet& permissions);

  // Records whether or not this extension is currently running.
  void SetExtensionRunning(const std::string& extension_id, bool is_running);

  // Returns whether or not this extension is marked as running. This is used to
  // restart apps across browser restarts.
  bool IsExtensionRunning(const std::string& extension_id) const;

  // Set/Get whether or not the app is active. Used to force a launch of apps
  // that don't handle onRestarted() on a restart. We can only safely do that if
  // the app was active when it was last running.
  void SetIsActive(const std::string& extension_id, bool is_active);
  bool IsActive(const std::string& extension_id) const;

  // Returns true if the user enabled this extension to be loaded in incognito
  // mode.
  //
  // IMPORTANT: you probably want to use extensions::util::IsIncognitoEnabled
  // instead of this method.
  bool IsIncognitoEnabled(const std::string& extension_id) const;
  void SetIsIncognitoEnabled(const std::string& extension_id, bool enabled);

  // Returns true if the user has chosen to allow this extension to inject
  // scripts into pages with file URLs.
  //
  // IMPORTANT: you probably want to use extensions::util::AllowFileAccess
  // instead of this method.
  bool AllowFileAccess(const std::string& extension_id) const;
  void SetAllowFileAccess(const std::string& extension_id, bool allow);
  bool HasAllowFileAccessSetting(const std::string& extension_id) const;

  // Saves ExtensionInfo for each installed extension with the path to the
  // version directory and the location. Blocklisted extensions won't be saved
  // and neither will external extensions the user has explicitly uninstalled.
  // Caller takes ownership of returned structure.
  std::unique_ptr<ExtensionsInfo> GetInstalledExtensionsInfo(
      bool include_component_extensions = false) const;

  // Returns the ExtensionInfo from the prefs for the given extension. If the
  // extension is not present, NULL is returned.
  std::unique_ptr<ExtensionInfo> GetInstalledExtensionInfo(
      const std::string& extension_id,
      bool include_component_extensions = false) const;

  // We've downloaded an updated .crx file for the extension, but are waiting
  // to install it.
  //
  // |install_flags| are a bitmask of extension::InstallFlags.
  void SetDelayedInstallInfo(const Extension* extension,
                             Extension::State initial_state,
                             int install_flags,
                             DelayReason delay_reason,
                             const syncer::StringOrdinal& page_ordinal,
                             const std::string& install_parameter,
                             const declarative_net_request::RulesetInstallPrefs&
                                 ruleset_install_prefs = {});

  // Removes any delayed install information we have for the given
  // |extension_id|. Returns true if there was info to remove; false otherwise.
  bool RemoveDelayedInstallInfo(const std::string& extension_id);

  // Update the prefs to finish the update for an extension.
  bool FinishDelayedInstallInfo(const std::string& extension_id);

  // Returns the ExtensionInfo from the prefs for delayed install information
  // for |extension_id|, if we have any. Otherwise returns NULL.
  std::unique_ptr<ExtensionInfo> GetDelayedInstallInfo(
      const std::string& extension_id) const;

  DelayReason GetDelayedInstallReason(const std::string& extension_id) const;

  // Returns information about all the extensions that have delayed install
  // information.
  std::unique_ptr<ExtensionsInfo> GetAllDelayedInstallInfo() const;

  // Returns true if there is an extension which controls the preference value
  //  for |pref_key| *and* it is specific to incognito mode.
  bool HasIncognitoPrefValue(const std::string& pref_key) const;

  // Returns the creation flags mask for the extension.
  int GetCreationFlags(const std::string& extension_id) const;

  // Returns the creation flags mask for a delayed install extension.
  int GetDelayedInstallCreationFlags(const std::string& extension_id) const;

  // Returns true if the extension was installed from the Chrome Web Store.
  bool IsFromWebStore(const std::string& extension_id) const;

  // Returns true if the extension was installed as a default app.
  bool WasInstalledByDefault(const std::string& extension_id) const;

  // Returns true if the extension was installed as an oem app.
  bool WasInstalledByOem(const std::string& extension_id) const;

  // Helper method to acquire the installation time of an extension.
  // Returns base::Time() if the installation time could not be parsed or
  // found.
  base::Time GetInstallTime(const std::string& extension_id) const;

  // Returns true if the extension should not be synced.
  bool DoNotSync(const std::string& extension_id) const;

  // Gets/sets the last launch time of an extension.
  base::Time GetLastLaunchTime(const std::string& extension_id) const;
  void SetLastLaunchTime(const std::string& extension_id,
                         const base::Time& time);

  // Clear any launch times. This is called by the browsing data remover when
  // history is cleared.
  void ClearLastLaunchTimes();

  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);

  bool extensions_disabled() const { return extensions_disabled_; }

  // The underlying PrefService.
  PrefService* pref_service() const { return prefs_; }

  // The underlying AppSorting.
  AppSorting* app_sorting() const;

  // Schedules garbage collection of an extension's on-disk data on the next
  // start of this ExtensionService. Applies only to extensions with isolated
  // storage.
  void SetNeedsStorageGarbageCollection(bool value);
  bool NeedsStorageGarbageCollection() const;

  // Used by AppWindowGeometryCache to persist its cache. These methods
  // should not be called directly.
  const base::DictionaryValue* GetGeometryCache(
        const std::string& extension_id) const;
  void SetGeometryCache(const std::string& extension_id,
                        std::unique_ptr<base::DictionaryValue> cache);

  // Used for verification of installed extension ids. For the Set method, pass
  // null to remove the preference.
  const base::DictionaryValue* GetInstallSignature() const;
  void SetInstallSignature(const base::DictionaryValue* signature);

  // The installation parameter associated with the extension.
  std::string GetInstallParam(const std::string& extension_id) const;
  void SetInstallParam(const std::string& extension_id,
                       const std::string& install_parameter);

  // Whether the extension with the given |extension_id| needs to be synced.
  // This is set when the state (such as enabled/disabled or allowed in
  // incognito) is changed before Sync is ready.
  bool NeedsSync(const std::string& extension_id) const;
  void SetNeedsSync(const std::string& extension_id, bool needs_sync);

  // Returns false if there is no ruleset checksum corresponding to the given
  // |extension_id| and |ruleset_id|. On success, returns true and populates the
  // checksum.
  bool GetDNRStaticRulesetChecksum(
      const ExtensionId& extension_id,
      declarative_net_request::RulesetID ruleset_id,
      int* checksum) const;
  void SetDNRStaticRulesetChecksum(
      const ExtensionId& extension_id,
      declarative_net_request::RulesetID ruleset_id,
      int checksum);

  // Returns false if there is no dynamic ruleset corresponding to
  // |extension_id|. On success, returns true and populates the checksum.
  bool GetDNRDynamicRulesetChecksum(const ExtensionId& extension_id,
                                    int* checksum) const;
  void SetDNRDynamicRulesetChecksum(const ExtensionId& extension_id,
                                    int checksum);

  // Returns the set of enabled static ruleset IDs or absl::nullopt if the
  // extension hasn't updated the set of enabled static rulesets.
  absl::optional<std::set<declarative_net_request::RulesetID>>
  GetDNREnabledStaticRulesets(const ExtensionId& extension_id) const;
  // Updates the set of enabled static rulesets for the |extension_id|. This
  // preference gets cleared on extension update.
  void SetDNREnabledStaticRulesets(
      const ExtensionId& extension_id,
      const std::set<declarative_net_request::RulesetID>& ids);

  // Whether the extension with the given |extension_id| is using its ruleset's
  // matched action count for the badge text. This is set via the
  // setExtensionActionOptions API call.
  bool GetDNRUseActionCountAsBadgeText(const ExtensionId& extension_id) const;
  void SetDNRUseActionCountAsBadgeText(const ExtensionId& extension_id,
                                       bool use_action_count_as_badge_text);

  // Whether the ruleset for the given |extension_id| and |ruleset_id| should be
  // ignored while loading the extension.
  bool ShouldIgnoreDNRRuleset(
      const ExtensionId& extension_id,
      declarative_net_request::RulesetID ruleset_id) const;

  // Returns the global rule allocation for the given |extension_id|. If no
  // rules are allocated to the extension, false is returned.
  bool GetDNRAllocatedGlobalRuleCount(const ExtensionId& extension_id,
                                      size_t* rule_count) const;
  void SetDNRAllocatedGlobalRuleCount(const ExtensionId& extension_id,
                                      size_t rule_count);

  // Whether the extension with the given |extension_id| should have its excess
  // global rules allocation kept during its next load.
  bool GetDNRKeepExcessAllocation(const ExtensionId& extension_id) const;
  void SetDNRKeepExcessAllocation(const ExtensionId& extension_id,
                                  bool keep_excess_allocation);

  // Migrates the disable reasons extension pref for extensions that were
  // disabled due to a deprecated reason.
  // TODO(archanasimha): Remove this around M89.
  void MigrateDeprecatedDisableReasons();

  // Looks to see if the Youtube extension is installed, and removes the
  // FROM_BOOKMARK flag from it's creation flags.
  // TODO(dmurph): Remove this in m90.
  void MigrateYoutubeOffBookmarkApps();

  // Iterates over the extension pref entries and removes any obsolete keys. We
  // need to do this here specially (rather than in
  // MigrateObsoleteProfilePrefs()) because these entries are subkeys of the
  // extension's dictionary, which is keyed on the extension ID.
  void MigrateObsoleteExtensionPrefs();

  // Updates an extension to use the new withholding pref key if it doesn't have
  // it yet, removing the old key in the process.
  // TODO(tjudkins): Remove this and the obsolete key in M83.
  void MigrateToNewWithholdingPref();

  // Migrates to the new way of recording explicit user uninstalls of external
  // extensions (by using a list of IDs rather than a bit set in each extension
  // dictionary).
  // TODO(devlin): Remove this once clients are migrated over, around M84.
  void MigrateToNewExternalUninstallPref();

  // Returns true if the given component extension should be installed, even
  // though it has been obsoleted. Installing it allows us to ensure it is
  // cleaned/deleted up properly. After that cleanup is done, this will return
  // false.
  bool ShouldInstallObsoleteComponentExtension(const std::string& extension_id);

  // Mark the given component extension as deleted. It should not be installed /
  // loaded again after this.
  void MarkObsoleteComponentExtensionAsRemoved(
      const std::string& extension_id,
      const mojom::ManifestLocation location);

  // When called before the ExtensionService is created, alerts that are
  // normally suppressed in first run will still trigger.
  static void SetRunAlertsInFirstRunForTest();

  void ClearExternalUninstallForTesting(const ExtensionId& id);

  static const char kFakeObsoletePrefForTesting[];

 private:
  friend class ExtensionPrefsBlocklistedExtensions;  // Unit test.
  friend class ExtensionPrefsComponentExtension;     // Unit test.
  friend class ExtensionPrefsUninstallExtension;     // Unit test.
  friend class
      ExtensionPrefsBitMapPrefValueClearedIfEqualsDefaultValue;  // Unit test.

  // See the Create methods.
  ExtensionPrefs(
      content::BrowserContext* browser_context,
      PrefService* prefs,
      const base::FilePath& root_dir,
      ExtensionPrefValueMap* extension_pref_value_map,
      base::Clock* clock,
      bool extensions_disabled,
      const std::vector<EarlyExtensionPrefsObserver*>& early_observers);

  // Gets or sets profile wide ExtensionPrefs.
  const base::Value* GetPref(const PrefMap& pref) const;
  void SetPref(const PrefMap& pref, std::unique_ptr<base::Value> value);

  // Updates ExtensionPrefs for a specific extension.
  void UpdateExtensionPref(const std::string& id,
                           const PrefMap& pref,
                           std::unique_ptr<base::Value> value);

  // Converts absolute paths in the pref to paths relative to the
  // install_directory_.
  void MakePathsRelative();

  // Converts internal relative paths to be absolute. Used for export to
  // consumers who expect full paths.
  void MakePathsAbsolute(base::DictionaryValue* dict);

  // Helper function used by GetInstalledExtensionInfo() and
  // GetDelayedInstallInfo() to construct an ExtensionInfo from the provided
  // |extension| dictionary.
  std::unique_ptr<ExtensionInfo> GetInstalledInfoHelper(
      const std::string& extension_id,
      const base::Value* extension,
      bool include_component_extensions) const;

  // Read the boolean preference entry and return true if the preference exists
  // and the preference's value is true; false otherwise.
  bool ReadPrefAsBooleanAndReturn(const std::string& extension_id,
                                  base::StringPiece pref_key) const;

  // Interprets |pref_key| in |extension_id|'s preferences as an
  // PermissionSet, and passes ownership of the set to the caller.
  std::unique_ptr<const PermissionSet> ReadPrefAsPermissionSet(
      const std::string& extension_id,
      base::StringPiece pref_key) const;

  // Converts the |new_value| to its value and sets the |pref_key| pref
  // belonging to |extension_id|.
  void SetExtensionPrefPermissionSet(const std::string& extension_id,
                                     base::StringPiece pref_key,
                                     const PermissionSet& new_value);

  // Common implementation to add permissions to a stored permission set.
  void AddToPrefPermissionSet(const ExtensionId& extension_id,
                              const PermissionSet& permissions,
                              const char* pref_name);

  // Common implementation to remove permissions from a stored permission set.
  void RemoveFromPrefPermissionSet(const ExtensionId& extension_id,
                                   const PermissionSet& permissions,
                                   const char* pref_name);

  // Returns an immutable dictionary for extension |id|'s prefs, or NULL if it
  // doesn't exist.
  const base::DictionaryValue* GetExtensionPref(const std::string& id) const;

  // Modifies the extensions disable reasons to add a new reason, remove an
  // existing reason, or clear all reasons. Notifies observers if the set of
  // DisableReasons has changed.
  // If |operation| is BIT_MAP_PREF_CLEAR, then |reasons| are ignored.
  void ModifyDisableReasons(const std::string& extension_id,
                            int reasons,
                            BitMapPrefOperation operation);

  // Installs the persistent extension preferences into |prefs_|'s extension
  // pref store. Does nothing if extensions_disabled_ is true.
  void InitPrefStore();

  // Checks whether there is a state pref for the extension and if so, whether
  // it matches |check_state|.
  bool DoesExtensionHaveState(const std::string& id,
                              Extension::State check_state) const;

  // Reads the list of strings for |pref| from user prefs into
  // |id_container_out|. Returns false if the pref wasn't found in the user
  // pref store.
  template <class ExtensionIdContainer>
  bool GetUserExtensionPrefIntoContainer(
      const char* pref,
      ExtensionIdContainer* id_container_out) const;

  // Writes the list of strings contained in |strings| to |pref| in prefs.
  template <class ExtensionIdContainer>
  void SetExtensionPrefFromContainer(const char* pref,
                                     const ExtensionIdContainer& strings);

  // Helper function to populate |extension_dict| with the values needed
  // by a newly installed extension. Work is broken up between this
  // function and FinishExtensionInfoPrefs() to accommodate delayed
  // installations.
  //
  // |install_flags| are a bitmask of extension::InstallFlags.
  void PopulateExtensionInfoPrefs(
      const Extension* extension,
      const base::Time install_time,
      Extension::State initial_state,
      int install_flags,
      const std::string& install_parameter,
      const declarative_net_request::RulesetInstallPrefs& ruleset_install_prefs,
      prefs::DictionaryValueUpdate* extension_dict);

  void InitExtensionControlledPrefs(const ExtensionsInfo& extensions_info);

  // Loads preferences for the given |extension_id| into the pref value map.
  void LoadExtensionControlledPrefs(const ExtensionId& extension_id,
                                    ExtensionPrefsScope scope);

  // Helper function to complete initialization of the values in
  // |extension_dict| for an extension install. Also see
  // PopulateExtensionInfoPrefs().
  void FinishExtensionInfoPrefs(
      const std::string& extension_id,
      const base::Time install_time,
      bool needs_sort_ordinal,
      const syncer::StringOrdinal& suggested_page_ordinal,
      prefs::DictionaryValueUpdate* extension_dict);

  // Returns true if the prefs have any permission withholding setting stored
  // for a given extension.
  bool HasWithholdingPermissionsSetting(const ExtensionId& extension_id) const;

  // Clears the bit indicating that an external extension was uninstalled.
  void ClearExternalUninstallBit(const ExtensionId& extension_id);

  raw_ptr<content::BrowserContext> browser_context_;

  // The pref service specific to this set of extension prefs. Owned by the
  // BrowserContext.
  raw_ptr<PrefService> prefs_;

  // Base extensions install directory.
  base::FilePath install_directory_;

  // Weak pointer, owned by BrowserContext.
  raw_ptr<ExtensionPrefValueMap> extension_pref_value_map_;

  raw_ptr<base::Clock> clock_;

  bool extensions_disabled_;

  base::ObserverList<ExtensionPrefsObserver>::Unchecked observer_list_;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_EXTENSION_PREFS_H_


text:
<?php

namespace Csa\Bundle\GuzzleBundle\GuzzleHttp\Subscriber;

use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\CompleteEvent;
use GuzzleHttp\Event\ErrorEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use GuzzleHttp\Message\RequestInterface;
use GuzzleHttp\Message\ResponseInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\Stopwatch\StopwatchEvent;

/**
 * Csa Guzzle Stopwatch integration
 *
 * @author Charles Sarrazin <charles@sarraz.in>
 */
class DebugSubscriber implements SubscriberInterface, \IteratorAggregate, \Countable
{
    private $stopwatch;

    /** @var int The maximum number of requests to maintain in the history */
    private $limit;

    /** @var array Requests and responses that have passed through the plugin */
    private $transactions = [];

    public function __construct(Stopwatch $stopwatch, $limit = 10)
    {
        $this->stopwatch = $stopwatch;
        $this->limit = $limit;
    }

    public function getEvents()
    {
        return [
            'before'   => ['onBefore', RequestEvents::EARLY],
            'complete' => ['onComplete', RequestEvents::EARLY],
            'error'    => ['onError', RequestEvents::EARLY],
        ];
    }

    public function onBefore(BeforeEvent $event)
    {
        $this->stopwatch->start($event->getRequest()->getUrl());
    }

    public function onComplete(CompleteEvent $event)
    {
        $request = $event->getRequest();
        $stopwatchEvent = $this->stopwatch->stop($request->getUrl());
        $this->add($request, $event->getResponse(), $stopwatchEvent);
    }

    public function onError(ErrorEvent $event)
    {
        $request = $event->getRequest();
        $url = $request->getUrl();

        if (!$this->stopwatch->isStarted($url)) {
            return;
        }

        $stopwatchEvent = $this->stopwatch->stop($url);
        $this->add($request, $event->getResponse(), $stopwatchEvent);
    }

    /**
     * Returns an Iterator that yields associative array values where each
     * associative array contains a 'request' and 'response' key.
     *
     * @return \Iterator
     */
    public function getIterator()
    {
        return new \ArrayIterator($this->transactions);
    }

    /**
     * Get the number of requests in the history
     *
     * @return int
     */
    public function count()
    {
        return count($this->transactions);
    }

    /**
     * Get the last request sent
     *
     * @return RequestInterface
     */
    public function getLastRequest()
    {
        return end($this->transactions)['request'];
    }

    /**
     * Get the last response in the history
     *
     * @return ResponseInterface|null
     */
    public function getLastResponse()
    {
        return end($this->transactions)['response'];
    }

    /**
     * Get the last duration in the history
     *
     * @return integer
     */
    public function getLastDuration()
    {
        return end($this->transactions)['duration'];
    }

    /**
     * Clears the history
     */
    public function clear()
    {
        $this->transactions = array();
    }

    /**
     * Add a request to the history
     *
     * @param RequestInterface  $request  Request to add
     * @param ResponseInterface $response Response of the request
     * @param StopwatchEvent    $event    Request duration, in ms
     */
    private function add(
        RequestInterface $request,
        ResponseInterface $response = null,
        StopwatchEvent $event = null
    ) {
        $this->transactions[] = ['request' => $request, 'response' => $response, 'duration' => $event ? $event->getDuration() : 0];

        if (count($this->transactions) > $this->limit) {
            array_shift($this->transactions);
        }
    }
}


text:
EvasionMethodFactory::EvasionMethodFactory(void)
{
	// register all evasion modules here by putting them in the list
	m_evasionMethodsList.push_back(boost::shared_ptr<IEvasionMethodPlugin>(new MemoryzeUM(MEMORYZE_USERMODE)));
	m_evasionMethodsList.push_back(boost::shared_ptr<IEvasionMethodPlugin>(new KernelModeEvasion(KERNELMODE)));
	m_evasionMethodsList.push_back(boost::shared_ptr<IEvasionMethodPlugin>(new KernelModeEvasion(KERNELMODE_FSFILTER)));
}

EvasionMethodFactory::~EvasionMethodFactory(void)
{
	// intentionally left empty
}

std::list<EvasionMethodFactory::EVASION_METHOD_BASIC_INFO> EvasionMethodFactory::GetEvasionMethodsBasicInfo(void)
{
	std::list<EVASION_METHOD_BASIC_INFO> basicInfoList;
	std::list<boost::shared_ptr<IEvasionMethodPlugin>>::iterator iter;

	for(iter = m_evasionMethodsList.begin(); iter != m_evasionMethodsList.end(); ++iter)
	{
		boost::shared_ptr<IEvasionMethodPlugin> evasionMethod = *iter;

		// get basic info about the current module
		EVASION_METHOD_BASIC_INFO basicInfo;
		basicInfo.ID = (EVASION_METHOD_ID) evasionMethod->GetID();
		basicInfo.name = evasionMethod->GetName();
		basicInfo.shortDescription = evasionMethod->GetShortDescription();
		basicInfo.longDescription = evasionMethod->GetLongDescription();
		basicInfo.arguments = evasionMethod->GetArgumentDescription();
		basicInfo.example = evasionMethod->GetExample();

		basicInfoList.push_back(basicInfo);
	}

	return basicInfoList;
}

boost::shared_ptr<IEvasionMethodPlugin> EvasionMethodFactory::GetEvasionMethod(EVASION_METHOD_ID id)
{
	std::list<boost::shared_ptr<IEvasionMethodPlugin>>::iterator iter;

	// iterate through the list of modules and immediately return the correct one, if found
	for(iter = m_evasionMethodsList.begin(); iter != m_evasionMethodsList.end(); ++iter)
	{
		boost::shared_ptr<IEvasionMethodPlugin> evasionMethod = *iter;
		if(evasionMethod->GetID() == id)
		{
			return evasionMethod;
		}
	}

	return boost::shared_ptr<IEvasionMethodPlugin>();
}


text:
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const net = require("net");
const ip = require("ip");
const smart_buffer_1 = require("smart-buffer");
const constants_1 = require("../common/constants");
const helpers_1 = require("../common/helpers");
const receivebuffer_1 = require("../common/receivebuffer");
const util_1 = require("../common/util");
class SocksClient extends events_1.EventEmitter {
    constructor(options) {
        super();
        this._options = Object.assign({}, options);
        // Validate SocksClientOptions
        helpers_1.validateSocksClientOptions(options);
        // Default state
        this.state = constants_1.SocksClientState.Created;
    }
    /**
     * Creates a new SOCKS connection.
     *
     * Note: Supports callbacks and promises. Only supports the connect command.
     * @param options { SocksClientOptions } Options.
     * @param callback { Function } An optional callback function.
     * @returns { Promise }
     */
    static createConnection(options, callback) {
        // Validate SocksClientOptions
        helpers_1.validateSocksClientOptions(options, ['connect']);
        return new Promise((resolve, reject) => {
            const client = new SocksClient(options);
            client.connect(options.existing_socket);
            client.once('established', (info) => {
                client.removeAllListeners();
                if (typeof callback === 'function') {
                    callback(null, info);
                    resolve(); // Resolves pending promise (prevents memory leaks).
                }
                else {
                    resolve(info);
                }
            });
            // Error occurred, failed to establish connection.
            client.once('error', (err) => {
                client.removeAllListeners();
                if (typeof callback === 'function') {
                    callback(err);
                    resolve(); // Resolves pending promise (prevents memory leaks).
                }
                else {
                    reject(err);
                }
            });
        });
    }
    /**
     * Creates a new SOCKS connection chain to a destination host through 2 or more SOCKS proxies.
     *
     * Note: Supports callbacks and promises. Only supports the connect method.
     * Note: Implemented via createConnection() factory function.
     * @param options { SocksClientChainOptions } Options
     * @param callback { Function } An optional callback function.
     * @returns { Promise }
     */
    static createConnectionChain(options, callback) {
        // Validate SocksClientChainOptions
        helpers_1.validateSocksClientChainOptions(options);
        // Shuffle proxies
        if (options.randomizeChain) {
            util_1.shuffleArray(options.proxies);
        }
        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
            let sock;
            try {
                for (let i = 0; i < options.proxies.length; i++) {
                    const nextProxy = options.proxies[i];
                    // If we've reached the last proxy in the chain, the destination is the actual destination, otherwise it's the next proxy.
                    const nextDestination = i === options.proxies.length - 1
                        ? options.destination
                        : {
                            host: options.proxies[i + 1].ipaddress,
                            port: options.proxies[i + 1].port
                        };
                    // Creates the next connection in the chain.
                    const result = yield SocksClient.createConnection({
                        command: 'connect',
                        proxy: nextProxy,
                        destination: nextDestination
                        // Initial connection ignores this as sock is undefined. Subsequent connections re-use the first proxy socket to form a chain.
                    });
                    // If sock is undefined, assign it here.
                    if (!sock) {
                        sock = result.socket;
                    }
                }
                if (typeof callback === 'function') {
                    callback(null, { socket: sock });
                    resolve(); // Resolves pending promise (prevents memory leaks).
                }
                else {
                    resolve({ socket: sock });
                }
            }
            catch (err) {
                if (typeof callback === 'function') {
                    callback(err);
                    resolve(); // Resolves pending promise (prevents memory leaks).
                }
                else {
                    reject(err);
                }
            }
        }));
    }
    /**
     * Creates a SOCKS UDP Frame.
     * @param options
     */
    static createUDPFrame(options) {
        const buff = new smart_buffer_1.SmartBuffer();
        buff.writeUInt16BE(0);
        buff.writeUInt8(options.frameNumber || 0);
        // IPv4/IPv6/Hostname
        if (net.isIPv4(options.remoteHost.host)) {
            buff.writeUInt8(constants_1.Socks5HostType.IPv4);
            buff.writeUInt32BE(ip.toLong(options.remoteHost.host));
        }
        else if (net.isIPv6(options.remoteHost.host)) {
            buff.writeUInt8(constants_1.Socks5HostType.IPv6);
            buff.writeBuffer(ip.toBuffer(options.remoteHost.host));
        }
        else {
            buff.writeUInt8(constants_1.Socks5HostType.Hostname);
            buff.writeUInt8(Buffer.byteLength(options.remoteHost.host));
            buff.writeString(options.remoteHost.host);
        }
        // Port
        buff.writeUInt16BE(options.remoteHost.port);
        // Data
        buff.writeBuffer(options.data);
        return buff.toBuffer();
    }
    /**
     * Parses a SOCKS UDP frame.
     * @param data
     */
    static parseUDPFrame(data) {
        const buff = smart_buffer_1.SmartBuffer.fromBuffer(data);
        buff.readOffset = 2;
        const frameNumber = buff.readUInt8();
        const hostType = buff.readUInt8();
        let remoteHost;
        if (hostType === constants_1.Socks5HostType.IPv4) {
            remoteHost = ip.fromLong(buff.readUInt32BE());
        }
        else if (hostType === constants_1.Socks5HostType.IPv6) {
            remoteHost = ip.toString(buff.readBuffer(16));
        }
        else {
            remoteHost = buff.readString(buff.readUInt8());
        }
        const remotePort = buff.readUInt16BE();
        return {
            frameNumber,
            remoteHost: {
                host: remoteHost,
                port: remotePort
            },
            data: buff.readBuffer()
        };
    }
    /**
     * Gets the SocksClient internal state.
     */
    get state() {
        return this._state;
    }
    /**
     * Internal state setter. If the SocksClient is in an error state, it cannot be changed to a non error state.
     */
    set state(newState) {
        if (this._state !== constants_1.SocksClientState.Error) {
            this._state = newState;
        }
    }
    /**
     * Starts the connection establishment to the proxy and destination.
     * @param existing_socket Connected socket to use instead of creating a new one (internal use).
     */
    connect(existing_socket) {
        this._onDataReceived = (data) => this.onDataReceived(data);
        this._onClose = () => this.onClose();
        this._onError = (err) => this.onError(err);
        this._onConnect = () => this.onConnect();
        // Start timeout timer (defaults to 30 seconds)
        const timer = setTimeout(() => this.onEstablishedTimeout(), this._options.timeout || constants_1.DEFAULT_TIMEOUT);
        // check whether unref is available as it differs from browser to NodeJS (#33)
        if (timer.unref && typeof timer.unref === 'function') {
            timer.unref();
        }
        // If an existing socket is provided, use it to negotiate SOCKS handshake. Otherwise create a new Socket.
        if (existing_socket) {
            this._socket = existing_socket;
        }
        else {
            this._socket = new net.Socket();
        }
        // Attach Socket error handlers.
        this._socket.once('close', this._onClose);
        this._socket.once('error', this._onError);
        this._socket.once('connect', this._onConnect);
        this._socket.on('data', this._onDataReceived);
        this.state = constants_1.SocksClientState.Connecting;
        this._receiveBuffer = new receivebuffer_1.ReceiveBuffer();
        if (existing_socket) {
            this._socket.emit('connect');
        }
        else {
            this._socket.connect(this._options.proxy.port, this._options.proxy.host || this._options.proxy.ipaddress);
            if (this._options.set_tcp_nodelay !== undefined &&
                this._options.set_tcp_nodelay !== null) {
                this._socket.setNoDelay(!!this._options.set_tcp_nodelay);
            }
        }
        // Listen for established event so we can re-emit any excess data received during handshakes.
        this.prependOnceListener('established', info => {
            setImmediate(() => {
                if (this._receiveBuffer.length > 0) {
                    const excessData = this._receiveBuffer.get(this._receiveBuffer.length);
                    info.socket.emit('data', excessData);
                }
                info.socket.resume();
            });
        });
    }
    /**
     * Handles internal Socks timeout callback.
     * Note: If the Socks client is not BoundWaitingForConnection or Established, the connection will be closed.
     */
    onEstablishedTimeout() {
        if (this.state !== constants_1.SocksClientState.Established &&
            this.state !== constants_1.SocksClientState.BoundWaitingForConnection) {
            this._closeSocket(constants_1.ERRORS.ProxyConnectionTimedOut);
        }
    }
    /**
     * Handles Socket connect event.
     */
    onConnect() {
        this.state = constants_1.SocksClientState.Connected;
        // Send initial handshake.
        if (this._options.proxy.type === 4) {
            this.sendSocks4InitialHandshake();
        }
        else {
            this.sendSocks5InitialHandshake();
        }
        this.state = constants_1.SocksClientState.SentInitialHandshake;
    }
    /**
     * Handles Socket data event.
     * @param data
     */
    onDataReceived(data) {
        /*
          All received data is appended to a ReceiveBuffer.
          This makes sure that all the data we need is received before we attempt to process it.
        */
        this._receiveBuffer.append(data);
        // Process data that we have.
        this.processData();
    }
    /**
     * Handles processing of the data we have received.
     */
    processData() {
        // If we have enough data to process the next step in the SOCKS handshake, proceed.
        if (this._receiveBuffer.length >= this._nextRequiredPacketBufferSize) {
            // Sent initial handshake, waiting for response.
            if (this.state === constants_1.SocksClientState.SentInitialHandshake) {
                if (this._options.proxy.type === 4) {
                    // Socks v4 only has one handshake response.
                    this.handleSocks4FinalHandshakeResponse();
                }
                else {
                    // Socks v5 has two handshakes, handle initial one here.
                    this.handleInitialSocks5HandshakeResponse();
                }
                // Sent auth request for Socks v5, waiting for response.
            }
            else if (this.state === constants_1.SocksClientState.SentAuthentication) {
                this.handleInitialSocks5AuthenticationHandshakeResponse();
                // Sent final Socks v5 handshake, waiting for final response.
            }
            else if (this.state === constants_1.SocksClientState.SentFinalHandshake) {
                this.handleSocks5FinalHandshakeResponse();
                // Socks BIND established. Waiting for remote connection via proxy.
            }
            else if (this.state === constants_1.SocksClientState.BoundWaitingForConnection) {
                if (this._options.proxy.type === 4) {
                    this.handleSocks4IncomingConnectionResponse();
                }
                else {
                    this.handleSocks5IncomingConnectionResponse();
                }
            }
            else if (this.state === constants_1.SocksClientState.Established) {
                // do nothing (prevents closing of the socket)
            }
            else {
                this._closeSocket(constants_1.ERRORS.InternalError);
            }
        }
    }
    /**
     * Handles Socket close event.
     * @param had_error
     */
    onClose() {
        this._closeSocket(constants_1.ERRORS.SocketClosed);
    }
    /**
     * Handles Socket error event.
     * @param err
     */
    onError(err) {
        this._closeSocket(err.message);
    }
    /**
     * Removes internal event listeners on the underlying Socket.
     */
    removeInternalSocketHandlers() {
        // Pauses data flow of the socket (this is internally resumed after 'established' is emitted)
        this._socket.pause();
        this._socket.removeListener('data', this._onDataReceived);
        this._socket.removeListener('close', this._onClose);
        this._socket.removeListener('error', this._onError);
        this._socket.removeListener('connect', this.onConnect);
    }
    /**
     * Closes and destroys the underlying Socket. Emits an error event.
     * @param err { String } An error string to include in error event.
     */
    _closeSocket(err) {
        // Make sure only one 'error' event is fired for the lifetime of this SocksClient instance.
        if (this.state !== constants_1.SocksClientState.Error) {
            // Set internal state to Error.
            this.state = constants_1.SocksClientState.Error;
            // Destroy Socket
            this._socket.destroy();
            // Remove internal listeners
            this.removeInternalSocketHandlers();
            // Fire 'error' event.
            this.emit('error', new util_1.SocksClientError(err, this._options));
        }
    }
    /**
     * Sends initial Socks v4 handshake request.
     */
    sendSocks4InitialHandshake() {
        const userId = this._options.proxy.userId || '';
        const buff = new smart_buffer_1.SmartBuffer();
        buff.writeUInt8(0x04);
        buff.writeUInt8(constants_1.SocksCommand[this._options.command]);
        buff.writeUInt16BE(this._options.destination.port);
        // Socks 4 (IPv4)
        if (net.isIPv4(this._options.destination.host)) {
            buff.writeBuffer(ip.toBuffer(this._options.destination.host));
            buff.writeStringNT(userId);
            // Socks 4a (hostname)
        }
        else {
            buff.writeUInt8(0x00);
            buff.writeUInt8(0x00);
            buff.writeUInt8(0x00);
            buff.writeUInt8(0x01);
            buff.writeStringNT(userId);
            buff.writeStringNT(this._options.destination.host);
        }
        this._nextRequiredPacketBufferSize =
            constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks4Response;
        this._socket.write(buff.toBuffer());
    }
    /**
     * Handles Socks v4 handshake response.
     * @param data
     */
    handleSocks4FinalHandshakeResponse() {
        const data = this._receiveBuffer.get(8);
        if (data[1] !== constants_1.Socks4Response.Granted) {
            this._closeSocket(`${constants_1.ERRORS.Socks4ProxyRejectedConnection} - (${constants_1.Socks4Response[data[1]]})`);
        }
        else {
            // Bind response
            if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.bind) {
                const buff = smart_buffer_1.SmartBuffer.fromBuffer(data);
                buff.readOffset = 2;
                const remoteHost = {
                    port: buff.readUInt16BE(),
                    host: ip.fromLong(buff.readUInt32BE())
                };
                // If host is 0.0.0.0, set to proxy host.
                if (remoteHost.host === '0.0.0.0') {
                    remoteHost.host = this._options.proxy.ipaddress;
                }
                this.state = constants_1.SocksClientState.BoundWaitingForConnection;
                this.emit('bound', { socket: this._socket, remoteHost });
                // Connect response
            }
            else {
                this.state = constants_1.SocksClientState.Established;
                this.removeInternalSocketHandlers();
                this.emit('established', { socket: this._socket });
            }
        }
    }
    /**
     * Handles Socks v4 incoming connection request (BIND)
     * @param data
     */
    handleSocks4IncomingConnectionResponse() {
        const data = this._receiveBuffer.get(8);
        if (data[1] !== constants_1.Socks4Response.Granted) {
            this._closeSocket(`${constants_1.ERRORS.Socks4ProxyRejectedIncomingBoundConnection} - (${constants_1.Socks4Response[data[1]]})`);
        }
        else {
            const buff = smart_buffer_1.SmartBuffer.fromBuffer(data);
            buff.readOffset = 2;
            const remoteHost = {
                port: buff.readUInt16BE(),
                host: ip.fromLong(buff.readUInt32BE())
            };
            this.state = constants_1.SocksClientState.Established;
            this.removeInternalSocketHandlers();
            this.emit('established', { socket: this._socket, remoteHost });
        }
    }
    /**
     * Sends initial Socks v5 handshake request.
     */
    sendSocks5InitialHandshake() {
        const buff = new smart_buffer_1.SmartBuffer();
        buff.writeUInt8(0x05);
        // We should only tell the proxy we support user/pass auth if auth info is actually provided.
        // Note: As of Tor v0.3.5.7+, if user/pass auth is an option from the client, by default it will always take priority.
        if (this._options.proxy.userId || this._options.proxy.password) {
            buff.writeUInt8(2);
            buff.writeUInt8(constants_1.Socks5Auth.NoAuth);
            buff.writeUInt8(constants_1.Socks5Auth.UserPass);
        }
        else {
            buff.writeUInt8(1);
            buff.writeUInt8(constants_1.Socks5Auth.NoAuth);
        }
        this._nextRequiredPacketBufferSize =
            constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5InitialHandshakeResponse;
        this._socket.write(buff.toBuffer());
        this.state = constants_1.SocksClientState.SentInitialHandshake;
    }
    /**
     * Handles initial Socks v5 handshake response.
     * @param data
     */
    handleInitialSocks5HandshakeResponse() {
        const data = this._receiveBuffer.get(2);
        if (data[0] !== 0x05) {
            this._closeSocket(constants_1.ERRORS.InvalidSocks5IntiailHandshakeSocksVersion);
        }
        else if (data[1] === 0xff) {
            this._closeSocket(constants_1.ERRORS.InvalidSocks5InitialHandshakeNoAcceptedAuthType);
        }
        else {
            // If selected Socks v5 auth method is no auth, send final handshake request.
            if (data[1] === constants_1.Socks5Auth.NoAuth) {
                this.sendSocks5CommandRequest();
                // If selected Socks v5 auth method is user/password, send auth handshake.
            }
            else if (data[1] === constants_1.Socks5Auth.UserPass) {
                this.sendSocks5UserPassAuthentication();
            }
            else {
                this._closeSocket(constants_1.ERRORS.InvalidSocks5InitialHandshakeUnknownAuthType);
            }
        }
    }
    /**
     * Sends Socks v5 user & password auth handshake.
     *
     * Note: No auth and user/pass are currently supported.
     */
    sendSocks5UserPassAuthentication() {
        const userId = this._options.proxy.userId || '';
        const password = this._options.proxy.password || '';
        const buff = new smart_buffer_1.SmartBuffer();
        buff.writeUInt8(0x01);
        buff.writeUInt8(Buffer.byteLength(userId));
        buff.writeString(userId);
        buff.writeUInt8(Buffer.byteLength(password));
        buff.writeString(password);
        this._nextRequiredPacketBufferSize =
            constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5UserPassAuthenticationResponse;
        this._socket.write(buff.toBuffer());
        this.state = constants_1.SocksClientState.SentAuthentication;
    }
    /**
     * Handles Socks v5 auth handshake response.
     * @param data
     */
    handleInitialSocks5AuthenticationHandshakeResponse() {
        this.state = constants_1.SocksClientState.ReceivedAuthenticationResponse;
        const data = this._receiveBuffer.get(2);
        if (data[1] !== 0x00) {
            this._closeSocket(constants_1.ERRORS.Socks5AuthenticationFailed);
        }
        else {
            this.sendSocks5CommandRequest();
        }
    }
    /**
     * Sends Socks v5 final handshake request.
     */
    sendSocks5CommandRequest() {
        const buff = new smart_buffer_1.SmartBuffer();
        buff.writeUInt8(0x05);
        buff.writeUInt8(constants_1.SocksCommand[this._options.command]);
        buff.writeUInt8(0x00);
        // ipv4, ipv6, domain?
        if (net.isIPv4(this._options.destination.host)) {
            buff.writeUInt8(constants_1.Socks5HostType.IPv4);
            buff.writeBuffer(ip.toBuffer(this._options.destination.host));
        }
        else if (net.isIPv6(this._options.destination.host)) {
            buff.writeUInt8(constants_1.Socks5HostType.IPv6);
            buff.writeBuffer(ip.toBuffer(this._options.destination.host));
        }
        else {
            buff.writeUInt8(constants_1.Socks5HostType.Hostname);
            buff.writeUInt8(this._options.destination.host.length);
            buff.writeString(this._options.destination.host);
        }
        buff.writeUInt16BE(this._options.destination.port);
        this._nextRequiredPacketBufferSize =
            constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHeader;
        this._socket.write(buff.toBuffer());
        this.state = constants_1.SocksClientState.SentFinalHandshake;
    }
    /**
     * Handles Socks v5 final handshake response.
     * @param data
     */
    handleSocks5FinalHandshakeResponse() {
        // Peek at available data (we need at least 5 bytes to get the hostname length)
        const header = this._receiveBuffer.peek(5);
        if (header[0] !== 0x05 || header[1] !== constants_1.Socks5Response.Granted) {
            this._closeSocket(`${constants_1.ERRORS.InvalidSocks5FinalHandshakeRejected} - ${constants_1.Socks5Response[header[1]]}`);
        }
        else {
            // Read address type
            const addressType = header[3];
            let remoteHost;
            let buff;
            // IPv4
            if (addressType === constants_1.Socks5HostType.IPv4) {
                // Check if data is available.
                const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv4;
                if (this._receiveBuffer.length < dataNeeded) {
                    this._nextRequiredPacketBufferSize = dataNeeded;
                    return;
                }
                buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
                remoteHost = {
                    host: ip.fromLong(buff.readUInt32BE()),
                    port: buff.readUInt16BE()
                };
                // If given host is 0.0.0.0, assume remote proxy ip instead.
                if (remoteHost.host === '0.0.0.0') {
                    remoteHost.host = this._options.proxy.ipaddress;
                }
                // Hostname
            }
            else if (addressType === constants_1.Socks5HostType.Hostname) {
                const hostLength = header[4];
                const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHostname(hostLength); // header + host length + host + port
                // Check if data is available.
                if (this._receiveBuffer.length < dataNeeded) {
                    this._nextRequiredPacketBufferSize = dataNeeded;
                    return;
                }
                buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(5) // Slice at 5 to skip host length
                );
                remoteHost = {
                    host: buff.readString(hostLength),
                    port: buff.readUInt16BE()
                };
                // IPv6
            }
            else if (addressType === constants_1.Socks5HostType.IPv6) {
                // Check if data is available.
                const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv6;
                if (this._receiveBuffer.length < dataNeeded) {
                    this._nextRequiredPacketBufferSize = dataNeeded;
                    return;
                }
                buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
                remoteHost = {
                    host: ip.toString(buff.readBuffer(16)),
                    port: buff.readUInt16BE()
                };
            }
            // We have everything we need
            this.state = constants_1.SocksClientState.ReceivedFinalResponse;
            // If using CONNECT, the client is now in the established state.
            if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.connect) {
                this.state = constants_1.SocksClientState.Established;
                this.removeInternalSocketHandlers();
                this.emit('established', { socket: this._socket });
            }
            else if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.bind) {
                /* If using BIND, the Socks client is now in BoundWaitingForConnection state.
                   This means that the remote proxy server is waiting for a remote connection to the bound port. */
                this.state = constants_1.SocksClientState.BoundWaitingForConnection;
                this._nextRequiredPacketBufferSize =
                    constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHeader;
                this.emit('bound', { socket: this._socket, remoteHost });
                /*
                  If using Associate, the Socks client is now Established. And the proxy server is now accepting UDP packets at the
                  given bound port. This initial Socks TCP connection must remain open for the UDP relay to continue to work.
                */
            }
            else if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.associate) {
                this.state = constants_1.SocksClientState.Established;
                this.removeInternalSocketHandlers();
                this.emit('established', { socket: this._socket, remoteHost });
            }
        }
    }
    /**
     * Handles Socks v5 incoming connection request (BIND).
     */
    handleSocks5IncomingConnectionResponse() {
        // Peek at available data (we need at least 5 bytes to get the hostname length)
        const header = this._receiveBuffer.peek(5);
        if (header[0] !== 0x05 || header[1] !== constants_1.Socks5Response.Granted) {
            this._closeSocket(`${constants_1.ERRORS.Socks5ProxyRejectedIncomingBoundConnection} - ${constants_1.Socks5Response[header[1]]}`);
        }
        else {
            // Read address type
            const addressType = header[3];
            let remoteHost;
            let buff;
            // IPv4
            if (addressType === constants_1.Socks5HostType.IPv4) {
                // Check if data is available.
                const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv4;
                if (this._receiveBuffer.length < dataNeeded) {
                    this._nextRequiredPacketBufferSize = dataNeeded;
                    return;
                }
                buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
                remoteHost = {
                    host: ip.fromLong(buff.readUInt32BE()),
                    port: buff.readUInt16BE()
                };
                // If given host is 0.0.0.0, assume remote proxy ip instead.
                if (remoteHost.host === '0.0.0.0') {
                    remoteHost.host = this._options.proxy.ipaddress;
                }
                // Hostname
            }
            else if (addressType === constants_1.Socks5HostType.Hostname) {
                const hostLength = header[4];
                const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHostname(hostLength); // header + host length + port
                // Check if data is available.
                if (this._receiveBuffer.length < dataNeeded) {
                    this._nextRequiredPacketBufferSize = dataNeeded;
                    return;
                }
                buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(5) // Slice at 5 to skip host length
                );
                remoteHost = {
                    host: buff.readString(hostLength),
                    port: buff.readUInt16BE()
                };
                // IPv6
            }
            else if (addressType === constants_1.Socks5HostType.IPv6) {
                // Check if data is available.
                const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv6;
                if (this._receiveBuffer.length < dataNeeded) {
                    this._nextRequiredPacketBufferSize = dataNeeded;
                    return;
                }
                buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
                remoteHost = {
                    host: ip.toString(buff.readBuffer(16)),
                    port: buff.readUInt16BE()
                };
            }
            this.state = constants_1.SocksClientState.Established;
            this.removeInternalSocketHandlers();
            this.emit('established', { socket: this._socket, remoteHost });
        }
    }
    get socksClientOptions() {
        return Object.assign({}, this._options);
    }
}
exports.SocksClient = SocksClient;
//# sourceMappingURL=socksclient.js.map


text:
<!DOCTYPE HTML>

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <title>SlickGrid example 1: Basic grid</title>
  <link rel="stylesheet" href="../slick.grid.css" type="text/css"/>
  <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css"/>
  <link rel="stylesheet" href="examples.css" type="text/css"/>