text:
require 'spec_helper'
require 'spf/query/query'

describe SPF::Query do
  subject { described_class }

  describe ".query" do
    let(:domain) { 'gmail.com' }

    it "should return the first SPF record" do
      expect(subject.query(domain)).to be == %{v=spf1 redirect=_spf.google.com}
    end

    context "when _spf.domain.com exists" do
      let(:domain) { 'google.com' }

      it "should return the first SPF record" do
        expect(subject.query(domain)).to be == %{v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all}
      end
    end

    context "when the domain.com has a TXT record" do
      let(:domain) { 'yahoo.com' }

      it "should return the TXT record containing the SPF record" do
        expect(subject.query(domain)).to be == %{v=spf1 redirect=_spf.mail.yahoo.com}
      end

      context "and when the record is split into multiple strings" do
        let(:domain) { '_spf.facebook.com' }

        it "should join the strings, without spaces" do
          expect(subject.query(domain)).to be == %{v=spf1 ip4:69.63.179.25 ip4:69.63.178.128/25 ip4:69.63.184.0/25 ip4:66.220.144.128/25 ip4:66.220.155.0/24 ip4:69.171.232.0/24 ip4:66.220.157.0/25 ip4:69.171.244.0/24 mx -all}
        end
      end
    end

    context "when the domain has a SPF type record" do
      let(:domain) { 'getlua.com' }

      it "should prefer the TXT type record over other SPF records" do
        expect_any_instance_of(Resolv::DNS).to_not receive(:getresource).with("getlua.com", Resolv::DNS::Resource::IN::SPF)
        expect_any_instance_of(Resolv::DNS).to receive(:getresources).with("getlua.com", Resolv::DNS::Resource::IN::TXT).at_least(:once).and_call_original
        expect_any_instance_of(Resolv::DNS).to receive(:getresources).with("_spf.getlua.com", Resolv::DNS::Resource::IN::TXT).at_least(:once).and_call_original

        expect(subject.query(domain)).to be == %{v=spf1 include:_spf.google.com include:mail.zendesk.com include:servers.mcsv.net include:aspmx.pardot.com -all}
      end
    end

    context "when given an invalid domain" do
      let(:domain) { 'foo.bar.com' }

      it "should return nil" do
        expect(subject.query(domain)).to be_nil
      end
    end
  end
end


text:
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.preferences.website;

import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.support.v7.app.AlertDialog;
import android.text.format.Formatter;
import android.widget.ListAdapter;
import android.widget.ListView;

import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ContentSettingsType;
import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader;
import org.chromium.chrome.browser.search_engines.TemplateUrlService;
import org.chromium.components.url_formatter.UrlFormatter;
import org.chromium.content_public.browser.WebContents;

import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Shows the permissions and other settings for a particular website.
 */
public class SingleWebsitePreferences extends PreferenceFragment
        implements DialogInterface.OnClickListener, OnPreferenceChangeListener,
                OnPreferenceClickListener {
    // SingleWebsitePreferences expects either EXTRA_SITE (a Website) or
    // EXTRA_ORIGIN (a WebsiteAddress) to be present (but not both). If
    // EXTRA_SITE is present, the fragment will display the permissions in that
    // Website object. If EXTRA_ORIGIN is present, the fragment will find all
    // permissions for that website address and display those. If EXTRA_LOCATION
    // is present, the fragment will add a Location toggle, even if the site
    // specifies no Location permission.
    public static final String EXTRA_SITE = "org.chromium.chrome.preferences.site";
    public static final String EXTRA_ORIGIN = "org.chromium.chrome.preferences.origin";
    public static final String EXTRA_LOCATION = "org.chromium.chrome.preferences.location";

    public static final String EXTRA_WEB_CONTENTS = "org.chromium.chrome.preferences.web_contents";
    public static final String EXTRA_USB_INFO = "org.chromium.chrome.preferences.usb_info";

    // Preference keys, see single_website_preferences.xml
    // Headings:
    public static final String PREF_SITE_TITLE = "site_title";
    public static final String PREF_USAGE = "site_usage";
    public static final String PREF_PERMISSIONS = "site_permissions";
    public static final String PREF_OS_PERMISSIONS_WARNING = "os_permissions_warning";
    public static final String PREF_OS_PERMISSIONS_WARNING_EXTRA = "os_permissions_warning_extra";
    public static final String PREF_OS_PERMISSIONS_WARNING_DIVIDER =
            "os_permissions_warning_divider";
    // Actions at the top (if adding new, see hasUsagePreferences below):
    public static final String PREF_CLEAR_DATA = "clear_data";
    // Buttons:
    public static final String PREF_RESET_SITE = "reset_site_button";
    // Website permissions (if adding new, see hasPermissionsPreferences and resetSite below):
    public static final String PREF_AUTOPLAY_PERMISSION = "autoplay_permission_list";
    public static final String PREF_BACKGROUND_SYNC_PERMISSION = "background_sync_permission_list";
    public static final String PREF_CAMERA_CAPTURE_PERMISSION = "camera_permission_list";
    public static final String PREF_COOKIES_PERMISSION = "cookies_permission_list";
    public static final String PREF_JAVASCRIPT_PERMISSION = "javascript_permission_list";
    public static final String PREF_KEYGEN_PERMISSION = "keygen_permission_list";
    public static final String PREF_LOCATION_ACCESS = "location_access_list";
    public static final String PREF_MIC_CAPTURE_PERMISSION = "microphone_permission_list";
    public static final String PREF_MIDI_SYSEX_PERMISSION = "midi_sysex_permission_list";
    public static final String PREF_NOTIFICATIONS_PERMISSION = "push_notifications_list";
    public static final String PREF_POPUP_PERMISSION = "popup_permission_list";
    public static final String PREF_PROTECTED_MEDIA_IDENTIFIER_PERMISSION =
            "protected_media_identifier_permission_list";

    // All permissions from the permissions preference category must be listed here.
    // TODO(mvanouwerkerk): Use this array in more places to reduce verbosity.
    private static final String[] PERMISSION_PREFERENCE_KEYS = {
            PREF_AUTOPLAY_PERMISSION,
            PREF_BACKGROUND_SYNC_PERMISSION,
            PREF_CAMERA_CAPTURE_PERMISSION,
            PREF_COOKIES_PERMISSION,
            PREF_JAVASCRIPT_PERMISSION,
            PREF_KEYGEN_PERMISSION,
            PREF_LOCATION_ACCESS,
            PREF_MIC_CAPTURE_PERMISSION,
            PREF_MIDI_SYSEX_PERMISSION,
            PREF_NOTIFICATIONS_PERMISSION,
            PREF_POPUP_PERMISSION,
            PREF_PROTECTED_MEDIA_IDENTIFIER_PERMISSION,
    };

    // The website this page is displaying details about.
    private Website mSite;

    // The address of the site we want to display. Used only if EXTRA_ADDRESS is provided.
    private WebsiteAddress mSiteAddress;

    // The number of USB device permissions displayed.
    private int mUsbPermissionCount;

    private class SingleWebsitePermissionsPopulator
            implements WebsitePermissionsFetcher.WebsitePermissionsCallback {
        private final WebContents mWebContents;

        public SingleWebsitePermissionsPopulator(WebContents webContents) {
            mWebContents = webContents;
        }

        @Override
        public void onWebsitePermissionsAvailable(Collection<Website> sites) {
            // This method may be called after the activity has been destroyed.
            // In that case, bail out.
            if (getActivity() == null) return;

            // TODO(mvanouwerkerk): Avoid modifying the outer class from this inner class.
            mSite = mergePermissionInfoForTopLevelOrigin(mSiteAddress, sites);

            // Display Keygen Content Setting if Keygen is blocked.
            if (mSite.getKeygenInfo() == null && mWebContents != null
                    && WebsitePreferenceBridge.getKeygenBlocked(mWebContents)) {
                String origin = mSiteAddress.getOrigin();
                mSite.setKeygenInfo(new KeygenInfo(origin, origin, false));
            }

            displaySitePermissions();
        }
    }

    /**
     * Creates a Bundle with the correct arguments for opening this fragment for
     * the website with the given url.
     *
     * @param url The URL to open the fragment with. This is a complete url including scheme,
     *            domain, port,  path, etc.
     * @return The bundle to attach to the preferences intent.
     */
    public static Bundle createFragmentArgsForSite(String url) {
        Bundle fragmentArgs = new Bundle();
        // TODO(mvanouwerkerk): Define a pure getOrigin method in UrlUtilities that is the
        // equivalent of the call below, because this is perfectly fine for non-display purposes.
        String origin =
                UrlFormatter.formatUrlForSecurityDisplay(URI.create(url), true /* showScheme */);
        fragmentArgs.putString(SingleWebsitePreferences.EXTRA_ORIGIN, origin);
        return fragmentArgs;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        getActivity().setTitle(R.string.prefs_site_settings);
        ListView listView = (ListView) getView().findViewById(android.R.id.list);
        listView.setDivider(null);

        Object extraSite = getArguments().getSerializable(EXTRA_SITE);
        Object extraOrigin = getArguments().getSerializable(EXTRA_ORIGIN);
        getArguments().setClassLoader(WebContents.class.getClassLoader());
        Object webContents = getArguments().get(EXTRA_WEB_CONTENTS);

        if (extraSite != null && extraOrigin == null) {
            mSite = (Website) extraSite;
            displaySitePermissions();
        } else if (extraOrigin != null && extraSite == null) {
            mSiteAddress = WebsiteAddress.create((String) extraOrigin);
            WebsitePermissionsFetcher fetcher;
            fetcher = new WebsitePermissionsFetcher(
                new SingleWebsitePermissionsPopulator((WebContents) webContents));
            fetcher.fetchAllPreferences();
        } else {
            assert false : "Exactly one of EXTRA_SITE or EXTRA_SITE_ADDRESS must be provided.";
        }

        super.onActivityCreated(savedInstanceState);
    }

    /**
     * Given an address and a list of sets of websites, returns a new site with the same origin
     * as |address| which has merged into it the permissions of the matching input sites. If a
     * permission is found more than once, the one found first is used and the latter are ignored.
     * This should not drop any relevant data as there should not be duplicates like that in the
     * first place.
     *
     * @param address The address to search for.
     * @param websites The websites to search in.
     * @return The merged website.
     */
    private static Website mergePermissionInfoForTopLevelOrigin(
            WebsiteAddress address, Collection<Website> websites) {
        String origin = address.getOrigin();
        String host = Uri.parse(origin).getHost();
        Website merged = new Website(address, null);
        // This loop looks expensive, but the amount of data is likely to be relatively small
        // because most sites have very few permissions.
        for (Website other : websites) {
            if (merged.getGeolocationInfo() == null && other.getGeolocationInfo() != null
                    && permissionInfoIsForTopLevelOrigin(other.getGeolocationInfo(), origin)) {
                merged.setGeolocationInfo(other.getGeolocationInfo());
            }
            if (merged.getKeygenInfo() == null && other.getKeygenInfo() != null
                    && permissionInfoIsForTopLevelOrigin(other.getKeygenInfo(), origin)) {
                merged.setKeygenInfo(other.getKeygenInfo());
            }
            if (merged.getMidiInfo() == null && other.getMidiInfo() != null
                    && permissionInfoIsForTopLevelOrigin(other.getMidiInfo(), origin)) {
                merged.setMidiInfo(other.getMidiInfo());
            }
            if (merged.getProtectedMediaIdentifierInfo() == null
                    && other.getProtectedMediaIdentifierInfo() != null
                    && permissionInfoIsForTopLevelOrigin(
                               other.getProtectedMediaIdentifierInfo(), origin)) {
                merged.setProtectedMediaIdentifierInfo(other.getProtectedMediaIdentifierInfo());
            }
            if (merged.getNotificationInfo() == null
                    && other.getNotificationInfo() != null
                    && permissionInfoIsForTopLevelOrigin(
                               other.getNotificationInfo(), origin)) {
                merged.setNotificationInfo(other.getNotificationInfo());
            }
            if (merged.getCameraInfo() == null && other.getCameraInfo() != null
                    && permissionInfoIsForTopLevelOrigin(
                               other.getCameraInfo(), origin)) {
                merged.setCameraInfo(other.getCameraInfo());
            }
            if (merged.getMicrophoneInfo() == null && other.getMicrophoneInfo() != null
                    && permissionInfoIsForTopLevelOrigin(other.getMicrophoneInfo(), origin)) {
                merged.setMicrophoneInfo(other.getMicrophoneInfo());
            }
            if (merged.getLocalStorageInfo() == null
                    && other.getLocalStorageInfo() != null
                    && origin.equals(other.getLocalStorageInfo().getOrigin())) {
                merged.setLocalStorageInfo(other.getLocalStorageInfo());
            }
            for (StorageInfo storageInfo : other.getStorageInfo()) {
                if (host.equals(storageInfo.getHost())) {
                    merged.addStorageInfo(storageInfo);
                }
            }
            for (UsbInfo usbInfo : other.getUsbInfo()) {
                if (origin.equals(usbInfo.getOrigin())
                        && (usbInfo.getEmbedder() == null || usbInfo.getEmbedder().equals("*"))) {
                    merged.addUsbInfo(usbInfo);
                }
            }

            // TODO(mvanouwerkerk): Make the various info types share a common interface that
            // supports reading the origin or host.
            // TODO(mvanouwerkerk): Merge in PopupExceptionInfo? It uses a pattern, and is never
            // set on Android.
            // TODO(mvanouwerkerk): Merge in JavaScriptExceptionInfo? It uses a pattern.
            // TODO(lshang): Merge in CookieException? It will use patterns.
        }
        return merged;
    }

    private static boolean permissionInfoIsForTopLevelOrigin(PermissionInfo info, String origin) {
        // TODO(mvanouwerkerk): Find a more generic place for this method.
        return origin.equals(info.getOrigin())
                && (origin.equals(info.getEmbedderSafe()) || "*".equals(info.getEmbedderSafe()));
    }

    /**
     * Updates the permissions displayed in the UI by fetching them from mSite.
     * Must only be called once mSite is set.
     */
    private void displaySitePermissions() {
        addPreferencesFromResource(R.xml.single_website_preferences);

        Set<String> permissionPreferenceKeys =
                new HashSet<>(Arrays.asList(PERMISSION_PREFERENCE_KEYS));
        int maxPermissionOrder = 0;
        ListAdapter preferences = getPreferenceScreen().getRootAdapter();
        for (int i = 0; i < preferences.getCount(); ++i) {
            Preference preference = (Preference) preferences.getItem(i);
            if (PREF_SITE_TITLE.equals(preference.getKey())) {
                preference.setTitle(mSite.getTitle());
            } else if (PREF_CLEAR_DATA.equals(preference.getKey())) {
                long usage = mSite.getTotalUsage();
                if (usage > 0) {
                    Context context = preference.getContext();
                    preference.setTitle(String.format(
                            context.getString(R.string.origin_settings_storage_usage_brief),
                            Formatter.formatShortFileSize(context, usage)));
                    ((ClearWebsiteStorage) preference).setConfirmationListener(this);
                } else {
                    getPreferenceScreen().removePreference(preference);
                }
            } else if (PREF_RESET_SITE.equals(preference.getKey())) {
                preference.setOnPreferenceClickListener(this);
            } else if (PREF_AUTOPLAY_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getAutoplayPermission());
            } else if (PREF_BACKGROUND_SYNC_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getBackgroundSyncPermission());
            } else if (PREF_CAMERA_CAPTURE_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getCameraPermission());
            } else if (PREF_COOKIES_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getCookiePermission());
            } else if (PREF_JAVASCRIPT_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getJavaScriptPermission());
            } else if (PREF_KEYGEN_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getKeygenPermission());
            } else if (PREF_LOCATION_ACCESS.equals(preference.getKey())) {
                setUpLocationPreference(preference);
            } else if (PREF_MIC_CAPTURE_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getMicrophonePermission());
            } else if (PREF_MIDI_SYSEX_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getMidiPermission());
            } else if (PREF_NOTIFICATIONS_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getNotificationPermission());
            } else if (PREF_POPUP_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getPopupPermission());
            } else if (PREF_PROTECTED_MEDIA_IDENTIFIER_PERMISSION.equals(preference.getKey())) {
                setUpListPreference(preference, mSite.getProtectedMediaIdentifierPermission());
            }

            if (permissionPreferenceKeys.contains(preference.getKey())) {
                maxPermissionOrder = Math.max(maxPermissionOrder, preference.getOrder());
            }
        }

        for (UsbInfo info : mSite.getUsbInfo()) {
            Preference preference = new Preference(getActivity());
            preference.getExtras().putSerializable(EXTRA_USB_INFO, info);
            preference.setIcon(R.drawable.settings_usb);
            preference.setOnPreferenceClickListener(this);
            preference.setOrder(maxPermissionOrder);
            preference.setTitle(info.getName());
            preference.setWidgetLayoutResource(R.layout.usb_permission);
            getPreferenceScreen().addPreference(preference);
            mUsbPermissionCount++;
        }

        // Remove the 'permission is off in Android' message if not needed.
        PreferenceScreen preferenceScreen = getPreferenceScreen();
        SiteSettingsCategory categoryWithWarning = getWarningCategory();
        if (categoryWithWarning == null) {
            getPreferenceScreen().removePreference(
                    preferenceScreen.findPreference(PREF_OS_PERMISSIONS_WARNING));
            getPreferenceScreen().removePreference(
                    preferenceScreen.findPreference(PREF_OS_PERMISSIONS_WARNING_EXTRA));
            getPreferenceScreen().removePreference(
                    preferenceScreen.findPreference(PREF_OS_PERMISSIONS_WARNING_DIVIDER));
        } else {
            Preference osWarning = preferenceScreen.findPreference(PREF_OS_PERMISSIONS_WARNING);
            Preference osWarningExtra =
                    preferenceScreen.findPreference(PREF_OS_PERMISSIONS_WARNING_EXTRA);
            categoryWithWarning.configurePermissionIsOffPreferences(
                    osWarning, osWarningExtra, getActivity(), false);
            if (osWarning.getTitle() == null) {
                getPreferenceScreen().removePreference(
                        preferenceScreen.findPreference(PREF_OS_PERMISSIONS_WARNING));
            } else if (osWarningExtra.getTitle() == null) {
                getPreferenceScreen().removePreference(
                        preferenceScreen.findPreference(PREF_OS_PERMISSIONS_WARNING_EXTRA));
            }
        }

        // Remove categories if no sub-items.
        if (!hasUsagePreferences()) {
            Preference heading = preferenceScreen.findPreference(PREF_USAGE);
            preferenceScreen.removePreference(heading);
        }
        if (!hasPermissionsPreferences()) {
            Preference heading = preferenceScreen.findPreference(PREF_PERMISSIONS);
            preferenceScreen.removePreference(heading);
        }
    }

    private SiteSettingsCategory getWarningCategory() {
        // If more than one per-app permission is disabled in Android, we can pick any category to
        // show the warning, because they will all show the same warning and all take the user to
        // the user to the same location. It is preferrable, however, that we give Geolocation some
        // priority because that category is the only one that potentially shows an additional
        // warning (when Location is turned off globally).
        if (showWarningFor(ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION)) {
            return SiteSettingsCategory.fromContentSettingsType(
                    ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION);
        }
        if (showWarningFor(ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) {
            return SiteSettingsCategory.fromContentSettingsType(
                    ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
        }
        if (showWarningFor(ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) {
            return SiteSettingsCategory.fromContentSettingsType(
                    ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
        }
        return null;
    }

    private boolean showWarningFor(int type) {
        ContentSetting setting = null;
        if (type == ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION) {
            setting = mSite.getGeolocationPermission();
        } else if (type == ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
            setting = mSite.getCameraPermission();
        } else if (type == ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) {
            setting = mSite.getMicrophonePermission();
        }

        if (setting == null) {
            return false;
        }

        SiteSettingsCategory category = SiteSettingsCategory.fromContentSettingsType(type);
        return category.showPermissionBlockedMessage(getActivity());
    }

    private boolean hasUsagePreferences() {
        // New actions under the Usage preference category must be listed here so that the category
        // heading can be removed when no actions are shown.
        return getPreferenceScreen().findPreference(PREF_CLEAR_DATA) != null;
    }

    private boolean hasPermissionsPreferences() {
        if (mUsbPermissionCount > 0) return true;
        PreferenceScreen screen = getPreferenceScreen();
        for (String key : PERMISSION_PREFERENCE_KEYS) {
            if (screen.findPreference(key) != null) return true;
        }
        return false;
    }

    /**
     * Initialize a ListPreference with a certain value.
     * @param preference The ListPreference to initialize.
     * @param value The value to initialize it to.
     */
    private void setUpListPreference(Preference preference, ContentSetting value) {
        if (value == null) {
            getPreferenceScreen().removePreference(preference);
            return;
        }

        ListPreference listPreference = (ListPreference) preference;

        int contentType = getContentSettingsTypeFromPreferenceKey(preference.getKey());
        CharSequence[] keys = new String[2];
        CharSequence[] descriptions = new String[2];
        keys[0] = ContentSetting.ALLOW.toString();
        keys[1] = ContentSetting.BLOCK.toString();
        descriptions[0] = getResources().getString(
                ContentSettingsResources.getSiteSummary(ContentSetting.ALLOW));
        descriptions[1] = getResources().getString(
                ContentSettingsResources.getSiteSummary(ContentSetting.BLOCK));
        listPreference.setEntryValues(keys);
        listPreference.setEntries(descriptions);
        int index = (value == ContentSetting.ALLOW ? 0 : 1);
        listPreference.setValueIndex(index);
        int explanationResourceId = ContentSettingsResources.getExplanation(contentType);
        if (explanationResourceId != 0) {
            listPreference.setTitle(explanationResourceId);
        }

        if (listPreference.isEnabled()) {
            SiteSettingsCategory category =
                    SiteSettingsCategory.fromContentSettingsType(contentType);
            if (category != null && !category.enabledInAndroid(getActivity())) {
                listPreference.setIcon(category.getDisabledInAndroidIcon(getActivity()));
                listPreference.setEnabled(false);
            } else {
                listPreference.setIcon(ContentSettingsResources.getIcon(contentType));
            }
        } else {
            listPreference.setIcon(
                    ContentSettingsResources.getDisabledIcon(contentType, getResources()));
        }

        preference.setSummary("%s");
        listPreference.setOnPreferenceChangeListener(this);
    }

    private void setUpLocationPreference(Preference preference) {
        ContentSetting permission = mSite.getGeolocationPermission();
        Context context = preference.getContext();
        Object locationAllowed = getArguments().getSerializable(EXTRA_LOCATION);
        if (permission == null && hasXGeoLocationPermission(context)) {
            String origin = mSite.getAddress().getOrigin();
            mSite.setGeolocationInfo(new GeolocationInfo(origin, origin, false));
            setUpListPreference(preference, ContentSetting.ALLOW);
            updateLocationPreferenceForXGeo(preference);
        } else if (permission == null && locationAllowed != null) {
            String origin = mSite.getAddress().getOrigin();
            mSite.setGeolocationInfo(new GeolocationInfo(origin, origin, false));
            setUpListPreference(preference, (boolean) locationAllowed
                    ? ContentSetting.ALLOW : ContentSetting.BLOCK);
        } else {
            setUpListPreference(preference, permission);
        }
    }

    /**
     * Returns true if the current host matches the default search engine host and location for the
     * default search engine is being granted via x-geo.
     * @param context The current context.
     */
    private boolean hasXGeoLocationPermission(Context context) {
        String searchUrl = TemplateUrlService.getInstance().getUrlForSearchQuery("foo");
        return mSite.getAddress().matches(searchUrl)
                && GeolocationHeader.isGeoHeaderEnabledForUrl(context, searchUrl, false);
    }

    /**
     * Updates the location preference to indicate that the site has access to location (via X-Geo)
     * for searches that happen from the omnibox.
     * @param preference The Location preference to modify.
     */
    private void updateLocationPreferenceForXGeo(Preference preference) {
        ListPreference listPreference = (ListPreference) preference;
        Resources res = getResources();
        listPreference.setEntries(new String[] {
                res.getString(R.string.website_settings_permissions_allow_dse),
                res.getString(ContentSettingsResources.getSiteSummary(ContentSetting.BLOCK)),
        });
        listPreference.setEntryValues(new String[] {
                ContentSetting.DEFAULT.toString(),
                ContentSetting.BLOCK.toString(),
        });
        listPreference.setValueIndex(0);
    }

    private int getContentSettingsTypeFromPreferenceKey(String preferenceKey) {
        switch (preferenceKey) {
            case PREF_AUTOPLAY_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_AUTOPLAY;
            case PREF_BACKGROUND_SYNC_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC;
            case PREF_CAMERA_CAPTURE_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA;
            case PREF_COOKIES_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_COOKIES;
            case PREF_JAVASCRIPT_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_JAVASCRIPT;
            case PREF_KEYGEN_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_KEYGEN;
            case PREF_LOCATION_ACCESS:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION;
            case PREF_MIC_CAPTURE_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC;
            case PREF_MIDI_SYSEX_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_MIDI_SYSEX;
            case PREF_NOTIFICATIONS_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_NOTIFICATIONS;
            case PREF_POPUP_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_POPUPS;
            case PREF_PROTECTED_MEDIA_IDENTIFIER_PERMISSION:
                return ContentSettingsType.CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER;
            default:
                return 0;
        }
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        clearStoredData();
    }

    private void clearStoredData() {
        mSite.clearAllStoredData(
                new Website.StoredDataClearedCallback() {
                    @Override
                    public void onStoredDataCleared() {
                        PreferenceScreen preferenceScreen = getPreferenceScreen();
                        preferenceScreen.removePreference(
                                preferenceScreen.findPreference(PREF_CLEAR_DATA));
                        if (!hasUsagePreferences()) {
                            preferenceScreen.removePreference(
                                    preferenceScreen.findPreference(PREF_USAGE));
                        }
                        popBackIfNoSettings();
                    }
                });
    }

    private void popBackIfNoSettings() {
        if (!hasPermissionsPreferences() && !hasUsagePreferences()) {
            if (getActivity() != null) {
                getActivity().finish();
            }
        }
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        ContentSetting permission = ContentSetting.fromString((String) newValue);
        if (PREF_AUTOPLAY_PERMISSION.equals(preference.getKey())) {
            mSite.setAutoplayPermission(permission);
        } else if (PREF_BACKGROUND_SYNC_PERMISSION.equals(preference.getKey())) {
            mSite.setBackgroundSyncPermission(permission);
        } else if (PREF_CAMERA_CAPTURE_PERMISSION.equals(preference.getKey())) {
            mSite.setCameraPermission(permission);
        } else if (PREF_COOKIES_PERMISSION.equals(preference.getKey())) {
            mSite.setCookiePermission(permission);
        } else if (PREF_JAVASCRIPT_PERMISSION.equals(preference.getKey())) {
            mSite.setJavaScriptPermission(permission);
        } else if (PREF_KEYGEN_PERMISSION.equals(preference.getKey())) {
            mSite.setKeygenPermission(permission);
        } else if (PREF_LOCATION_ACCESS.equals(preference.getKey())) {
            mSite.setGeolocationPermission(permission);
        } else if (PREF_MIC_CAPTURE_PERMISSION.equals(preference.getKey())) {
            mSite.setMicrophonePermission(permission);
        } else if (PREF_MIDI_SYSEX_PERMISSION.equals(preference.getKey())) {
            mSite.setMidiPermission(permission);
        } else if (PREF_NOTIFICATIONS_PERMISSION.equals(preference.getKey())) {
            mSite.setNotificationPermission(permission);
        } else if (PREF_POPUP_PERMISSION.equals(preference.getKey())) {
            mSite.setPopupPermission(permission);
        } else if (PREF_PROTECTED_MEDIA_IDENTIFIER_PERMISSION.equals(preference.getKey())) {
            mSite.setProtectedMediaIdentifierPermission(permission);
        }

        return true;
    }

    @Override
    public boolean onPreferenceClick(Preference preference) {
        Bundle extras = preference.peekExtras();
        if (extras != null) {
            UsbInfo usbInfo = (UsbInfo) extras.getSerializable(EXTRA_USB_INFO);
            if (usbInfo != null) {
                usbInfo.revoke();

                PreferenceScreen preferenceScreen = getPreferenceScreen();
                preferenceScreen.removePreference(preference);
                mUsbPermissionCount--;
                if (!hasPermissionsPreferences()) {
                    Preference heading = preferenceScreen.findPreference(PREF_PERMISSIONS);
                    preferenceScreen.removePreference(heading);
                }
                return true;
            }
        }

        // Handle the Clear & Reset preference click by showing a confirmation.
        new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme)
                .setTitle(R.string.website_reset)
                .setMessage(R.string.website_reset_confirmation)
                .setPositiveButton(R.string.website_reset, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        resetSite();
                    }
                })
                .setNegativeButton(R.string.cancel, null)
                .show();
        return true;
    }

    /**
     * Resets the current site, clearing all permissions and storage used (inc. cookies).
     */
    @VisibleForTesting
    protected void resetSite() {
        if (getActivity() == null) return;
        // Clear the screen.
        // TODO(mvanouwerkerk): Refactor this class so that it does not depend on the screen state
        // for its logic. This class should maintain its own data model, and only update the screen
        // after a change is made.
        PreferenceScreen screen = getPreferenceScreen();
        for (String key : PERMISSION_PREFERENCE_KEYS) {
            Preference preference = screen.findPreference(key);
            if (preference != null) screen.removePreference(preference);
        }

        // Clear the permissions.
        mSite.setAutoplayPermission(ContentSetting.DEFAULT);
        mSite.setBackgroundSyncPermission(ContentSetting.DEFAULT);
        mSite.setCameraPermission(ContentSetting.DEFAULT);
        mSite.setCookiePermission(ContentSetting.DEFAULT);
        WebsitePreferenceBridge.nativeClearCookieData(mSite.getAddress().getTitle());
        mSite.setGeolocationPermission(ContentSetting.DEFAULT);
        mSite.setJavaScriptPermission(ContentSetting.DEFAULT);
        mSite.setKeygenPermission(ContentSetting.DEFAULT);
        mSite.setMicrophonePermission(ContentSetting.DEFAULT);
        mSite.setMidiPermission(ContentSetting.DEFAULT);
        mSite.setNotificationPermission(ContentSetting.DEFAULT);
        mSite.setPopupPermission(ContentSetting.DEFAULT);
        mSite.setProtectedMediaIdentifierPermission(ContentSetting.DEFAULT);
        for (UsbInfo info : mSite.getUsbInfo()) info.revoke();

        // Clear the storage and finish the activity if necessary.
        if (mSite.getTotalUsage() > 0) {
            clearStoredData();
        } else {
            // Clearing stored data implies popping back to parent menu if there
            // is nothing left to show. Therefore, we only need to explicitly
            // close the activity if there's no stored data to begin with.
            getActivity().finish();
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
import * as React from 'react';
import * as fp from 'lodash/fp';

import { TextInput } from 'app/components/inputs';
import { TooltipTrigger } from 'app/components/popups';
import colors, { colorWithWhiteness } from 'app/styles/colors';
import { reactStyles } from 'app/utils';

const styles = reactStyles({
  dropdownMenu: {
    display: 'block',
    maxHeight: '12rem',
    minHeight: '30px',
    visibility: 'visible',
    overflowY: 'scroll',
    width: '35%',
    marginTop: '.25rem',
    zIndex: 100,
    border: `1px solid ${colorWithWhiteness(colors.dark, 0.7)}`,
    borderRadius: '5px',
    backgroundColor: colors.white,
  },
  open: {
    position: 'absolute',
    backgroundColor: colors.white,
    border: '1px solid',
  },
  box: {
    borderRadius: '5px',
    paddingTop: '0.2rem',
    paddingLeft: '0.2rem',
    color: colors.primary,
  },
  boxHover: {
    background: 'rgb(234, 243, 250)',
    color: colors.primary,
    paddingTop: '0.2rem',
    paddingLeft: '0.2rem',
  },
  boxHoverElement: {
    color: colors.primary,
    margin: 0,
    padding: 0,
    fontFamily: 'Montserrat',
    fontSize: '14px',
    lineHeight: '32px',
  },
});

// Fifo accepts a function 'fn' that returns a promise, and returns a
// new function that returns a promise. Promises returned by the
// resulting function return their result of the last-instantiated
// promise. For example, if a0, a1 are the start and end times of a
// computation represented by promise A, and b0, b1 are the start and end
// times of a computation represented by promise B, and a0 < b0 < b1 <
// a1, then the value returned by promise A at time a1 will be the result
// of promise B, *not* promise A, because B was instantiated after A.
function fifo(fn) {
  let nextCallID = 1;
  let lastCompletedCallID = 0;
  let lastCompletedResult = null;
  return (...args) => {
    const thisCallID = nextCallID++;
    return new Promise((accept, reject) => {
      fn.apply(null, args)
        .then((newResult) => {
          if (thisCallID > lastCompletedCallID) {
            lastCompletedCallID = thisCallID;
            lastCompletedResult = newResult;
          }
          accept(lastCompletedResult);
        })
        .catch((e) => {
          reject(e);
        });
    });
  };
}

interface SearchInputState {
  matches: Array<string>;
  hover: Array<boolean>;
  state: number;
}

export interface SearchInputProps {
  enabled: boolean;
  placeholder: string;
  value: string;
  onSearch: (keyword: string) => Promise<Array<string>>;
  tooltip: string;
  onChange: (newInput: string) => void;
}

export class SearchInput extends React.Component<
  SearchInputProps,
  SearchInputState
> {
  static defaultProps = {
    enabled: true,
    placeholder: '',
    value: '',
    onSearch: () => {
      return new Promise<Array<string>>((accept) => {
        accept([]);
      });
    },
    tooltip: '',
    onChange: () => {},
  };

  // Forward declarations
  _searchTermChangedEvent: Function;
  _onSearch: Function;
  _START: number;
  _ACTIVE: number;
  _SUGGEST: number;
  _HOVER: number;

  constructor(props) {
    super(props);
    this.state = {
      matches: [],
      hover: [],
      state: this._START,
    };
    this._onSearch = fifo(props.onSearch);
    this._searchTermChangedEvent = fp.debounce(300, this._search);

    // State machine states
    this._START = 0; // Input box lacks focus, drop-down invisible
    this._ACTIVE = 1; // Input box focused, drop-down invisible
    this._SUGGEST = 2; // Input box focused, search results visible
    this._HOVER = 3; // Input box focused, search results visible, item activated
  }

  _toggleHover(j) {
    return this.state.hover.map((elt, i) => {
      return i === j ? !elt : elt;
    });
  }

  _search(keyword: string): void {
    this.setState({ matches: [] });
    keyword = keyword.trim();
    if (!keyword) {
      return;
    }
    this._onSearch(keyword)
      .then((matches) => {
        matches = matches || [];
        this.setState({
          matches: matches,
          state: matches.length > 0 ? this._SUGGEST : this._ACTIVE,
          hover: matches.map(() => false),
        });
      })
      .catch((e) => {
        console.error(e);
      });
  }

  _onBlur() {
    const state = this.state.state;
    if (
      state === this._ACTIVE ||
      state === this._SUGGEST ||
      state === this._HOVER
    ) {
      this.setState({ state: this._START });
    }
  }

  _onChange(match) {
    this.setState({ state: this._ACTIVE });
    this._searchTermChangedEvent(match);
    this.props.onChange(match);
  }

  _onFocus() {
    this.setState({ state: this._ACTIVE });
  }

  _onMouseOver(j) {
    this.setState({
      state: this._HOVER,
      hover: this._toggleHover(j),
    });
  }

  _onMouseOut(j) {
    this.setState({
      state: this._SUGGEST,
      hover: this._toggleHover(j),
    });
  }

  _onMouseDown(match) {
    this.props.onChange(match);
  }

  _suggest() {
    const s = this.state.state;
    const rval =
      this.props.enabled && (s === this._SUGGEST || s === this._HOVER);
    return rval;
  }

  render() {
    const borderColor = colorWithWhiteness(colors.dark, 0.7);
    const inputStyle = {
      width: '90%',
      border: `1px solid ${borderColor}`,
      borderRadius: '5px',
    };
    return (

        <TooltipTrigger
          content={this.props.tooltip}
          disabled={this.props.enabled}
          data-test-id='search-input'
        >
          <TextInput
            value={this.props.value}
            style={inputStyle}
            onFocus={this._onFocus.bind(this)}
            onBlur={this._onBlur.bind(this)}
            onChange={(e) => this._onChange(e)}
            placeholder={this.props.placeholder}
            disabled={!this.props.enabled}
          />
        </TooltipTrigger>
        {this._suggest() && (

            {this.state.matches.map((match, j) => {
              return (
                <div
                  data-test-id={`search-input-drop-down-element-${j}`}
                  key={j}
                  style={this.state.hover[j] ? styles.boxHover : styles.box}
                  onMouseOver={this._onMouseOver.bind(this, j)}
                  onMouseOut={this._onMouseOut.bind(this, j)}
                  onMouseDown={this._onMouseDown.bind(this, match)}
                >

{match}

              );
            })}

        )}

    );
  }
}


text:
TCL_PREFIX=C:/Program Files/Tcl
TCL_VERSION=85
HTTPD_PREFIX=C:/Program Files/Apache Software Foundation/Apache2
INSTALL_PREFIX=C:/Program Files/Apache Software Foundation/Websh

## no modifications should be necessary below this line
#

# debug objects?
!IF "$(DEBUG)"==""
DEBUG=0
!ELSE
DEBUG=1
!ENDIF

# local directories
TOP_DIR = ..
SRC_DIR = ../generic

# sources for script.h
SCRIPT_SOURCES = \
	../generic/context.tcl \
	../generic/script.ws3 \
	../generic/cookie.ws3 \
	../generic/sessctx.ws3

# generic objects
web_OBJECTS = \
	args.obj \
	cfg.obj \
	checksum.obj \
	command.obj \
	conv.obj \
	crypt.obj \
	nca_d.obj \
	dispatch.obj \
	filecounter.obj \
	filelock.obj \
	formdata.obj \
	hashutl.obj \
	htmlify.obj \
	log.obj \
	logtocmd.obj \
	logtochannel.obj \
	logtofile.obj \
	logutl.obj \
	messages.obj \
	messagesCmd.obj \
	paramlist.obj \
	querystring.obj \
	request.obj \
	uricode.obj \
	script.obj \
	url.obj \
	web.obj \
	webout.obj \
	weboutint.obj \
	webutl.obj \
	webutlcmd.obj \
	varchannel.obj \
	modwebsh_cgi.obj \
	request_cgi.obj \
	response_cgi.obj

# Apache objects (for mod_websh.so)
web_OBJECTS_ap = \
	apchannel.obj \
	interpool.obj \
	logtoap.obj \
	mod_websh.obj \
	modwebsh_ap.obj \
	request_ap.obj \
	response_ap.obj

# install directories
bindir = $(INSTALL_PREFIX)/bin
moddir = $(INSTALL_PREFIX)/modules
docdir = $(INSTALL_PREFIX)/htdocs
libdir = $(INSTALL_PREFIX)/lib
cfgdir = $(INSTALL_PREFIX)/conf

# compiler, linker, and other binaries
CC = cl
CCLD = $(CC)
INSTALL = xcopy /y

PACKAGE = web
VERSION = 3.6.0b5

CFLAGS_DEFAULT = /D"WIN32" /D"VERSION=\"$(VERSION)\"" /D"_MBCS" /W3 /EHsc
CFLAGS_DEBUG = /Od /Yd /Zi /D"_DEBUG"
CFLAGS_OPTIMIZE = /O2 /Ob1

CLEANFILES = *.obj *.ilk *.pdb *.tlb *.tli *.tlh *.tmp *.rsp *.exe *.dll *.lib *.exp *.so

OBJEXT = obj

EXEC_CFLAGS = /D"_CONSOLE"
!IF "$(DEBUG)" == "1"
SHLIB_CFLAGS = /LDd /MDd /Gy
!ELSE
SHLIB_CFLAGS = /LD /MD /Gy
!ENDIF

# TCL stuff
TCL_INCLUDES = "$(TCL_PREFIX)/include"
TCL_DEFS = /DTHREAD_SAFE=1
TCL_LIBS = kernel32.lib user32.lib advapi32.lib ws2_32.lib odbc32.lib
TCL_STUB_LIB_SPEC = "$(TCL_PREFIX)/lib/tclstub$(TCL_VERSION).lib"
TCL_LIB_SPEC = "$(TCL_PREFIX)/lib/tcl$(TCL_VERSION).lib"
TCLSH_PROG = "$(TCL_PREFIX)\bin\tclsh$(TCL_VERSION)"

# Apache stuff
HTTPD_INCLUDES = "$(HTTPD_PREFIX)/include"
!IF EXIST("$(HTTPD_PREFIX)/include/apr_strings.h")
# Apache 2
!IF EXIST("$(HTTPD_PREFIX)/lib/libapr.lib")
# Apache 2.0
HTTPD_LIBS = "$(HTTPD_PREFIX)/lib/libhttpd.lib" \
	"$(HTTPD_PREFIX)/lib/libapr.lib" \
	"$(HTTPD_PREFIX)/lib/libaprutil.lib"
!ELSE
# Apache 2.2
HTTPD_LIBS = "$(HTTPD_PREFIX)/lib/libhttpd.lib" \
	"$(HTTPD_PREFIX)/lib/libapr-1.lib" \
	"$(HTTPD_PREFIX)/lib/libaprutil-1.lib"
!ENDIF
!ELSE
# Apache 1.3
HTTPD_LIBS = "$(HTTPD_PREFIX)/lib/ap.lib" \
	"$(HTTPD_PREFIX)/lib/ApacheOS.lib" \
	"$(HTTPD_PREFIX)/libexec/ApacheCore.lib"
!ENDIF

INCLUDES = -I$(TCL_INCLUDES) -I$(HTTPD_INCLUDES)

EXTRA_CFLAGS = $(TCL_DEFS)

!IF "$(DEBUG)" == "0"
CFLAGS = $(CFLAGS_DEFAULT) $(CFLAGS_OPTIMIZE) $(EXTRA_CFLAGS) $(INCLUDES)
LD_CFLAGS =  $(CFLAGS_DEFAULT) $(CFLAGS_OPTIMIZE)
DEFAULT_MSVCRT=msvcrt.lib
!ELSE
CFLAGS = $(CFLAGS_DEFAULT) $(CFLAGS_DEBUG) $(EXTRA_CFLAGS) $(INCLUDES)
LD_CFLAGS = $(CFLAGS_DEFAULT)
DEFAULT_MSVCRT=msvcrtd.lib
!ENDIF

!IF "$(DEBUG)" == "1"
!MESSAGE ==================================================
!MESSAGE Creating objects with debug information (DEBUG=1)
!MESSAGE ==================================================
!ENDIF

# find apache binary (needed for apachetest)
!IF EXIST("$(HTTPD_PREFIX)/bin/Apache.exe")
HTTPD_BIN = "$(HTTPD_PREFIX)/bin/Apache.exe"
!ELSE
!IF EXIST("$(HTTPD_PREFIX)/bin/httpd.exe")
HTTPD_BIN = "$(HTTPD_PREFIX)/bin/httpd.exe"
!ELSE
!IF EXIST("$(HTTPD_PREFIX)/Apache.exe")
HTTPD_BIN = "$(HTTPD_PREFIX)/Apache.exe"
!ELSE
!MESSAGE Warning: Apache binary not found in "$(HTTPD_PREFIX)/bin"
!ENDIF
!ENDIF
!ENDIF

# =============================================================================
# main targets
# =============================================================================

default:
	@echo.
	@echo -----------------------------------------------------------------
	@echo Target must be one of websh.exe, mod_websh.so, all, clean,
	@echo test, or install
	@echo Use DEBUG=1 to for debug objects (e.g. nmake websh.exe DEBUG=1)
	@echo -----------------------------------------------------------------
	@echo.

all: websh.exe mod_websh.so

script.h: ..\generic\tcldecmt.tcl $(SCRIPT_SOURCES)
	$(TCLSH_PROG) ..\generic\tcldecmt.tcl $(SCRIPT_SOURCES) > $@

script.obj: script.h ../generic/script.c
	$(CC) -I. $(CFLAGS) -c ../generic/script.c /Fo$@

interpool.obj: ../generic/interpool.c
	$(CC) $(CFLAGS) -UUSE_TCL_STUBS -c ../generic/interpool.c /Fo$@

{$(SRC_DIR)}.c{}.obj::
	$(CC) $(CFLAGS) -Fd.\ -c $<

websh.exe: websh$(VERSION).exe websh$(VERSION).dll

mod_websh.so: mod_websh$(VERSION).so websh$(VERSION).dll

websh$(VERSION).exe: tclAppInit.$(OBJEXT) websh$(VERSION).dll
	$(CCLD) $(LD_CFLAGS) $(EXEC_CFLAGS) \
	tclAppInit.$(OBJEXT) websh$(VERSION).lib \
	$(TCL_LIB_SPEC) $(TCL_STUB_LIB_SPEC) $(TCL_LIBS) -o websh$(VERSION).exe \
	/link /nodefaultlib:$(DEFAULT_MSVCRT)

mod_websh$(VERSION).so: $(web_OBJECTS_ap) websh$(VERSION).dll
	$(CCLD) $(LD_CFLAGS) $(SHLIB_CFLAGS) -o mod_websh$(VERSION).so \
	$(web_OBJECTS_ap) websh$(VERSION).lib $(TCL_LIB_SPEC) \
	$(TCL_STUB_LIB_SPEC) $(HTTPD_LIBS) $(TCL_LIBS) \
	/link /dll /nodefaultlib:msvcrt.lib /subsystem:windows

websh$(VERSION).dll: $(web_OBJECTS)
        $(CCLD) $(LD_CFLAGS) $(SHLIB_CFLAGS) -o websh$(VERSION).dll \
	$(web_OBJECTS) $(TCL_LIB_SPEC) $(TCL_STUB_LIB_SPEC) \
	$(TCL_LIBS) /link /dll \
	/nodefaultlib:$(DEFAULT_MSVCRT) /subsystem:windows

test: websh.exe
	set TCL_LIBRARY="$(TCL_PREFIX)/lib"
	set TCLLIBPATH=$(TCL_PACKAGE_PATH)
	set WEB_LIBRARY=$(TOP_DIR)/win/websh$(VERSION).dll
	cd $(TOP_DIR)/tests
	$(TOP_DIR)\win\websh$(VERSION).exe webtest.ws3

apachetest: mod_websh.so websh.exe
	cd $(TOP_DIR)/apachetests
	$(TCLSH_PROG) runtests.tcl $(HTTPD_BIN)

clean:
	-del /Q $(CLEANFILES)
	-del /Q script.h
	-rmdir /S /Q ..\apachetests\logs
	-del /Q ..\apachetests\conf\server.conf
	-del /Q ..\apachetests\conf\websh.conf

distclean: clean

# =============================================================================
# Install Websh
# As there are no symbolic links under Windows, files are installed twice:
# once with version number and once without.
# =============================================================================

install: installdirs installtargets installdocs installsample

installtargets:
	@echo.
	@echo -----------------------------------------------------------------
	@echo Note that only targets that have been built are installed
	@echo -----------------------------------------------------------------
	@echo.
	if exist mod_websh$(VERSION).so \
		$(INSTALL) mod_websh$(VERSION).so "$(moddir)"
	if exist mod_websh$(VERSION).lib \
		$(INSTALL) mod_websh$(VERSION).lib "$(libdir)"
	if exist mod_websh$(VERSION).exp \
		$(INSTALL) mod_websh$(VERSION).exp "$(libdir)"
	if exist mod_websh$(VERSION).so \
		copy /Y mod_websh$(VERSION).so "$(moddir)/mod_websh.so"
	if exist websh$(VERSION).exe \
		$(INSTALL) websh$(VERSION).exe "$(bindir)"
	if exist websh$(VERSION).exe \
		copy /Y websh$(VERSION).exe "$(bindir)/websh.exe"
	if exist websh$(VERSION).dll \
		$(INSTALL) websh$(VERSION).dll "$(bindir)"
	if exist websh$(VERSION).lib \
		$(INSTALL) websh$(VERSION).lib "$(libdir)"
	if exist websh$(VERSION).exp \
		$(INSTALL) websh$(VERSION).exp "$(libdir)"
	if exist websh$(VERSION).dll \
		copy /Y websh$(VERSION).dll "$(bindir)/websh.dll"
	copy /Y "$(TOP_DIR)\..\src\win\pkgIndex.tcl" "$(bindir)"

installdocs:
#	$(INSTALL) "$(TOP_DIR)\..\doc\html\*.html" "$(docdir)"

installsample:
	$(INSTALL) "$(TOP_DIR)\..\doc\mod_websh\conf\*.*" "$(cfgdir)"
	$(INSTALL) "$(TOP_DIR)\..\doc\mod_websh\htdocs\*.*" "$(docdir)"
	copy /Y "$(TOP_DIR)\..\doc\mod_websh\README" "$(INSTALL_PREFIX)\README.txt"

installdirs:
	-mkdir "$(bindir)"
	-mkdir "$(libdir)"
	-mkdir "$(moddir)"
	-mkdir "$(docdir)"
	-mkdir "$(cfgdir)"


text:
package org.drools.guvnor.client.explorer.navigation.admin.widget;

import com.google.gwt.user.client.ui.*;
import org.drools.guvnor.client.common.GenericCallback;
import org.drools.guvnor.client.common.PrettyFormLayout;
import org.drools.guvnor.client.messages.ConstantsCore;
import org.drools.guvnor.client.resources.GuvnorImages;
import org.drools.guvnor.client.resources.ImagesCore;
import org.drools.guvnor.client.rpc.CategoryService;
import org.drools.guvnor.client.rpc.CategoryServiceAsync;
import org.drools.guvnor.client.widgets.categorynav.CategoryEditor;
import org.drools.guvnor.client.widgets.categorynav.CategoryExplorerWidget;
import org.drools.guvnor.client.widgets.categorynav.CategorySelectHandler;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import org.uberfire.client.annotations.WorkbenchPartTitle;
import org.uberfire.client.annotations.WorkbenchPartView;
import org.uberfire.client.annotations.WorkbenchScreen;

import javax.enterprise.context.Dependent;

/**
 * This controls category administration.
 */
@Dependent
@WorkbenchScreen(identifier = "categoryManager")
public class CategoryManager extends Composite {

    public VerticalPanel           layout    = new VerticalPanel();
    //public String selectedPath;
    private CategoryExplorerWidget explorer;

    public CategoryManager() {

        PrettyFormLayout form = new PrettyFormLayout();
        form.addHeader( GuvnorImages.INSTANCE.EditCategories(),
                        new HTML( ConstantsCore.INSTANCE.EditCategories() ) );
        form.startSection( ConstantsCore.INSTANCE.CategoriesPurposeTip() );

        explorer = new CategoryExplorerWidget( new CategorySelectHandler() {
            public void selected(String sel) {
                //don't need this here as we don't do anything on select in this spot
            }
        } );
        SimplePanel editable = new SimplePanel();
        editable.add( explorer );

        form.addAttribute( ConstantsCore.INSTANCE.CurrentCategories(),
                           editable );

        HorizontalPanel actions = new HorizontalPanel();

        form.addAttribute( "",
                           actions );

        Button newCat = new Button( ConstantsCore.INSTANCE.NewCategory() );
        newCat.setTitle( ConstantsCore.INSTANCE.CreateANewCategory() );
        newCat.addClickHandler( new ClickHandler() {
            public void onClick(ClickEvent w) {
                CategoryEditor newCat = new CategoryEditor( explorer.getSelectedPath(),
                                                            new Command() {
                                                                public void execute() {
                                                                    explorer.refresh();
                                                                }
                                                            } );

                newCat.show();
            }
        } );

        actions.add( newCat );

        Button rename = new Button( ConstantsCore.INSTANCE.RenameSelected() );
        rename.addClickHandler( new ClickHandler() {
            public void onClick(ClickEvent w) {
                if ( !explorer.isSelected() ) {
                    Window.alert( ConstantsCore.INSTANCE.PleaseSelectACategoryToRename() );
                    return;
                }
                renameSelected();
            }
        } );

        actions.add( rename );

        Button delete = new Button( ConstantsCore.INSTANCE.DeleteSelected() );
        delete.addClickHandler( new ClickHandler() {
            public void onClick(ClickEvent w) {
                if ( !explorer.isSelected() ) {
                    Window.alert( ConstantsCore.INSTANCE.PleaseSelectACategoryToDelete() );
                    return;
                }
                deleteSelected();
            }
        } );
        delete.setTitle( ConstantsCore.INSTANCE.DeleteSelectedCat() );

        actions.add( delete );

        form.endSection();

        initWidget( form );

    }

    private void renameSelected() {

        String name = Window.prompt( ConstantsCore.INSTANCE.CategoryNewNamePleaseEnter(),
                                     "" );
        if ( name != null ) {
            CategoryServiceAsync categoryService = GWT.create(CategoryService.class);
            categoryService.renameCategory( explorer.getSelectedPath(),
                                                                  name,
                                                                  new GenericCallback<java.lang.Void>() {
                                                                      public void onSuccess(Void v) {
                                                                          Window.alert( ConstantsCore.INSTANCE.CategoryRenamed() );
                                                                          explorer.refresh();
                                                                      }
                                                                  } );
        }
    }

    private void deleteSelected() {
        if ( Window.confirm( ConstantsCore.INSTANCE.AreYouSureYouWantToDeleteCategory() + explorer.getSelectedPath() ) ) {
            CategoryServiceAsync categoryService = GWT.create(CategoryService.class);
            categoryService.removeCategory( explorer.getSelectedPath(),
                                                                  new GenericCallback<java.lang.Void>() {

                                                                      public void onSuccess(Void v) {
                                                                          explorer.refresh();
                                                                      }

                                                                  } );
        }
    }

    @WorkbenchPartView
    public Widget asWidget() {
        return this;
    }

    @WorkbenchPartTitle
    public String getTitle() {
        return ConstantsCore.INSTANCE.CategoryManager();
    }
}


text:
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.Its.Domain
{
    public static class SnapshotRepositoryExtensions
    {
        /// <summary>
        /// Saves a snapshot of the aggregate.
        /// </summary>
        public static async Task SaveSnapshot<TAggregate>(
            this ISnapshotRepository repository,
            TAggregate aggregate)
            where TAggregate : class, IEventSourced
        {
            var snapshotCreator = Configuration.Current.Container.Resolve<ICreateSnapshot<TAggregate>>();

            var snapshot = snapshotCreator.CreateSnapshot(aggregate);

            aggregate.InitializeSnapshot(snapshot);

            await repository.SaveSnapshot(snapshot);
        }
    }
}


text:
package net.openhft.chronicle.engine.client.internal;

import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.engine.client.ClientWiredStatelessTcpConnectionHub;
import net.openhft.chronicle.engine.client.internal.ClientWiredChronicleQueueStateless.EventId;
import net.openhft.chronicle.network.event.EventGroup;
import net.openhft.chronicle.queue.ChronicleQueue;
import net.openhft.chronicle.queue.ChronicleQueueBuilder;
import net.openhft.chronicle.queue.ExcerptAppender;
import net.openhft.chronicle.queue.ExcerptTailer;
import net.openhft.chronicle.wire.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.StreamCorruptedException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * Created by Rob Austin
 */
public class QueueWireHandler implements WireHandler, Consumer<WireHandlers> {

    public static final int SIZE_OF_SIZE = ClientWiredStatelessTcpConnectionHub.SIZE_OF_SIZE;
    private static final Logger LOG = LoggerFactory.getLogger(QueueWireHandler.class);
    final StringBuilder cspText = new StringBuilder();
    final StringBuilder eventName = new StringBuilder();
    // assume there is a handler for each connection.
    long tid = -1;
    long cid = -1;
    ChronicleQueue queue = null;
    private WireHandlers publishLater;
    private Wire inWire;
    private Wire outWire;
    private Map<Long, ChronicleQueue> cidToQueue = new ConcurrentHashMap<>();
    private ConcurrentHashMap<String, Integer> cspToCid = new ConcurrentHashMap<>();
    private ConcurrentHashMap<String, ChronicleQueue> fileNameToChronicle = new ConcurrentHashMap<>();
    private AtomicInteger cidCounter = new AtomicInteger();
    private Map<ChronicleQueue, ExcerptAppender> queueToAppender = new ConcurrentHashMap<>();
    private Map<ChronicleQueue, ExcerptTailer> queueToTailer = new ConcurrentHashMap<>();

    public QueueWireHandler() {
    }

    @Override
    public void accept(WireHandlers wireHandlers) {
        this.publishLater = wireHandlers;
    }

    @Override
    public void process(Wire in, Wire out) throws StreamCorruptedException {
        try {
            this.inWire = in;
            this.outWire = out;
            onEvent();
        } catch (Exception e) {
            LOG.error("", e);
        }
    }

    @SuppressWarnings("UnusedReturnValue")
    void onEvent() throws IOException {
        //Be careful not to use Wires.acquireStringBuilder() as we
        //need to store the value

        inWire.readDocument(
                w -> {
                    w.read(CoreFields.csp).text(cspText)
                            .read(CoreFields.tid).int64(x -> tid = x)
                            .read(CoreFields.cid).int64(x -> cid = x);
                    queue = getQueue(cspText);
                }, dataWireIn -> {
                    ValueIn vin = inWire.readEventName(eventName);

        try {
            // writes out the tid
            outWire.writeDocument(true, wire -> outWire.write(CoreFields.tid).int64(tid));

            if (EventId.lastWrittenIndex.contentEquals(eventName)) {
                writeData(wireOut -> wireOut.write(CoreFields.reply).int64(queue.lastWrittenIndex()));

            } else if (EventId.createAppender.contentEquals(eventName)) {
                //only need one appender per queue
                queueToAppender.computeIfAbsent(queue,
                        s -> {
                            try {
                                return queue.createAppender();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            return null;
                        });

                outWire.writeDocument(false, wireOut -> {
                    QueueAppenderResponse qar = new QueueAppenderResponse();
                    qar.setCid(cid);
                    qar.setCsp(cspText);
                    wireOut.write(CoreFields.reply).typedMarshallable(qar);
                });

            } else if (EventId.submit.contentEquals(eventName)) {
                ExcerptAppender appender = queueToAppender.get(queue);
                appender.writeDocument(wo -> wo.bytes().write(vin.bytes()));

                outWire.writeDocument(false, wire -> wire.write(EventId.index).int64(appender.lastWrittenIndex()));

            } else if (EventId.createTailer.contentEquals(eventName)) {
                //only need one appender per queue
                queueToTailer.computeIfAbsent(queue,
                        s -> {
                            try {
                                return queue.createTailer();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            return null;
                        });

                outWire.writeDocument(false, wireOut -> {
                    QueueTailerResponse qar = new QueueTailerResponse();
                    qar.setCid(cid);
                    qar.setCsp(cspText);
                    wireOut.write(CoreFields.reply).typedMarshallable(qar);
                });
            }else if (EventId.hasNext.contentEquals(eventName)) {
                ExcerptTailer tailer = queueToTailer.get(queue);
                vin.marshallable((ReadMarshallable) rm -> {
                    long index = rm.read(() -> "index").int64();

                    sendBackMessage(tailer, index);
                });
            }

        } finally {

            if (EventGroup.IS_DEBUG) {
                long len = outWire.bytes().position() - SIZE_OF_SIZE;
                if (len == 0) {
                    System.out.println("--------------------------------------------\n" +
                            "server writes:\n\n<EMPTY>");

                } else {

                    System.out.println("--------------------------------------------\n" +
                            "server writes:\n\n" +
                            Wires.fromSizePrefixedBlobs(outWire.bytes(), SIZE_OF_SIZE, len));
                }
            }
        }
                });
    }

    private void sendBackMessage(ExcerptTailer tailer, long index) {
        tailer.index(index);
        tailer.readDocument(wireIn ->
                writeIndexedDocument(index, wireIn.bytes()));
    }

    private void writeIndexedDocument(long index, Bytes<?> bytes) {
        outWire.writeDocument(false, ow ->
                ow.write(EventId.index).int64(index)
                        .write(CoreFields.reply).bytes(bytes));
    }

    private ChronicleQueue getQueue(StringBuilder cspText) {
        ChronicleQueue queue;
        if (cid == 0) {
            //cid hasn't been passed in need to map it from csp
            cid = cspToCid.computeIfAbsent(cspText.toString(),
                    s -> cidCounter.incrementAndGet());
            String[] parts = cspText.toString().split("/");

            String filename = "/tmp/" + parts[1] + "/" + parts[2] + ".q";

            queue = fileNameToChronicle.computeIfAbsent
                    (filename, s -> {
                        try {
                            return new ChronicleQueueBuilder(filename).build();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return null;
                    });
            cidToQueue.put(cid, queue);

        } else {
            //if the cid has been created then there must be a corresponding queue
            queue = cidToQueue.get(cid);
            assert queue != null;
        }
        return queue;
    }

    private void writeData(Consumer<WireOut> c) {
        try {
            outWire.bytes().mark();
            outWire.writeDocument(false, c);
        } catch (Exception e) {
            outWire.bytes().reset();
            final WireOut o = outWire.write(CoreFields.reply)
                    .type(e.getClass().getSimpleName());

            if (e.getMessage() != null)
                o.writeValue().text(e.getMessage());

            LOG.error("", e);
        }
    }
}


text:
<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Form\Type\ContactFormType;

class SupportController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        //dump($request);
        //form object instance
        $form = $this->createForm(ContactFormType::class,null,['action'=>$this->generateUrl('handle_form_submission')]);

        return $this->render('support/index.html.twig',['our_form'=>$form->createView()]);
    }

    /**
     * @param Request $request
     * @Route("/form-submission", name="handle_form_submission")
     * @Method("POST")
     */
    public function handleFormSubmissionAction(Request $request)
    {
        $form = $this->createForm(ContactFormType::class);

        $form->handleRequest($request);

        if(!$form->isSubmitted() || !$form->isValid()){
            return $this->redirectToRoute('homepage');
        }

        $data = $form->getData();

        $message = \Swift_Message::newInstance()
                    ->setSubject('Contact Submission')
                    ->setFrom($data['from'])
                    ->setTo('jasonpolydor@gmail.com')
                    ->setBody($data['message'],'text/plain');

        $this->get('mailer')->send($message);
        $this->addFlash('success', 'Your message has been sent!');
        return $this->redirectToRoute('homepage');
    }
}


text:
Sleep - Async
-------------

async javascript functions made easy.

To run this example run these commands in your shell:

```bash
cd
git clone https://github.com/rusthon/Rusthon.git
cd Rusthon/
./rusthon.py ./examples/javascript_sleep.md
```

html
----

@index.html
```html
<html>
<head>
<@myscript>
</head>
<body onload="test()">
<pre id="CONTAINER">
</pre>
</body>
</html>
```

Example
--------------------------

`sleep(seconds)` pauses a function for a given number of seconds,
it can only be used in the function body, and not under any conditional blocks or loops.

@myscript
```rusthon
#backend:javascript
from runtime import *

def show(txt):
	document.getElementById('CONTAINER').appendChild(
		document.createTextNode(txt + '\n')
	)

def invalid_sleep():
	## sleep is not allowed under any control or loop blocks
	## uncomment below to see a transpiler error
	#if True:
	#	show('sleep2')
	#	sleep(1)
	#else:
	#	show('never seen')
	#for i in range(10):
	#	sleep(1)
	#while True:
	#	sleep(1)
	#	break
	pass

@debugger
def test():

	show('sleep1')

	sleep(1)

	show('sleep2')
	sleep(1)

	show('sleep3')
	sleep(1)

	show('sleep test OK')

```


text:
declare namespace Jymfony.Component.DependencyInjection.Compiler {
    /**
     * Compiler pass to register tagged services that require a service locator.
     */
    export class RegisterServiceSubscribersPass extends AbstractRecursivePass {
        /**
         * @inheritdoc
         */
        protected _processValue(value: any, isRoot?: boolean): any;
    }
}


text:
package com.esri.geoevent.test.performance.db.elasticsearch;

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;

import com.esri.geoevent.test.performance.db.DBClient;
import com.esri.geoevent.test.performance.db.DBResult;

public class ElasticSearchClient implements DBClient {

    // member vars

    private String indexName;
    private String indexType;
    private String fieldName = "_timestamp";
    private int numOfNodes = 1;

    // setup the cluster
    private Client client;

    @SuppressWarnings("resource")
    public ElasticSearchClient(String hostName, String clusterName, String indexName, String indexType, int numOfNodes) {
        this.indexName = indexName;
        this.indexType = indexType;
        this.numOfNodes = numOfNodes;

        // TODO: Fixed the hard coding of the port number
        Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", clusterName).build();
        this.client = new TransportClient(settings).addTransportAddress(new InetSocketTransportAddress(hostName, 9300));
    }

    @Override
    public void close() throws IOException {
        client.close();
    }

    @Override
    public void createSchema() {
        if (numOfNodes > 1) {
            for (int i = 1; i <= numOfNodes; i++) {
                addSchema(i);
            }
        } else {
            addSchema(0);
        }
    }

    private void addSchema(int iter) {
        String indexIter = "";
        if (iter > 0) {
            indexIter += iter;
        }

        String mappingJSON = "{\"" + indexType + "\":{\"_timestamp\":{\"enabled\":true,\"store\":true,\"index\":\"not_analyzed\"},\"_all\":{\"enabled\":false},\"properties\":{\"trackId\":{\"type\":\"string\"},\"timestamp\":{\"type\":\"date\"},\"speed\":{\"type\":\"float\",\"index\":\"no\"}}}}";

        CreateIndexRequestBuilder builder = client.admin().indices().prepareCreate(indexName + indexIter);
        builder.addMapping(indexType, mappingJSON);

	//builder.setSettings("index.number_of_shards", 1);
        //builder.setSettings("index.number_of_replicas", 0);
        //builder.setSettings("refresh_interval", "120s");
        builder.setSettings("index.store.type", "memory");

        CreateIndexResponse createResponse = builder.execute().actionGet();
        if (!createResponse.isAcknowledged()) {
            System.err.println("Index was not created!");
        }
    }

    @Override
    public void truncate() {
        IndicesExistsResponse indicesExistsResponse = client.admin().indices().prepareExists(indexName + "*").execute().actionGet();
        if (indicesExistsResponse.isExists()) {
            DeleteIndexResponse response = client.admin().indices().prepareDelete(indexName + "*").execute().actionGet();
            if (!response.isAcknowledged()) {
                System.err.println("Index wasn't deleted");
            }
        }
    }

    @Override
    public DBResult queryForLastWriteTimes() {
        SearchResponse response
                = client.prepareSearch(indexName + "*")
                .setTypes(indexType)
                .setQuery(QueryBuilders.matchAllQuery())
                .addFields(fieldName)
                .setFrom(0)
                .setSize(Integer.MAX_VALUE)
                .execute().actionGet();

        List<SearchHit> hits = Arrays.asList(response.getHits().getHits());

        // sort all of the rows accordingly
        hits.sort(new RowComparator());

        // gather the information we need
        int totalCount = hits.size();

        long startTime = Long.MAX_VALUE;
        long endTime = Long.MIN_VALUE;
        if (hits.size() > 0) {
            startTime = (long) (hits.get(0).field(fieldName).getValue());
            endTime = (long) (hits.get(hits.size() - 1).field(fieldName).getValue());
        }

        return new DBResult(startTime, endTime, totalCount);
    }

    /**
     * Inner class used to sort the incoming Cassandra rows by last updated
     * (long)
     */
    class RowComparator implements Comparator<SearchHit> {

        @Override
        public int compare(SearchHit row1, SearchHit row2) {
            if (row1 == null || row2 == null) {
                return 0;
            }

            return Long.compare(row1.field(fieldName).getValue(), row2.field(fieldName).getValue());
        }
    }
}


text:
@interface OptionController : UIViewController

@property (nonatomic) int sicknessIndex;
@property (nonatomic) BOOL severeSickness;

@property (weak, nonatomic) IBOutlet UILabel *labelOutlet;
@property (weak, nonatomic) IBOutlet UIButton *button1Outlet;
@property (weak, nonatomic) IBOutlet UIButton *button2Outlet;

@end


text:
id: 587d7fa6367417b2b2512bbf
title: Visualizzare i dati con una mappa coropletica
challengeType: 3
forumTopicId: 301465
dashedName: visualize-data-with-a-choropleth-map
---

# --description--

**Obiettivo:** Costruisci un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: <https://codepen.io/freeCodeCamp/full/EZKqza>.

Soddisfa le seguenti [user story](https://en.wikipedia.org/wiki/User_story) e fai in modo che tutti i test siano superati. Dalle il tuo stile personale.

Puoi usare HTML, JavaScript, CSS e la libreria di visualizzazione basata su svg D3. Gli elementi del DOM (non-virtuale) richiesti sono selezionati al momento di ogni test. Se usi un framework frontend (come Vue per esempio) i risultati dei test potrebbero essere inaccurati per il contenuto dinamico. Speriamo di supportarli prima o poi, ma questi framework non sono supportati al momento per i progetti D3.

**User Story #1:** La mia mappa coropletica dovrebbe avere un titolo con corrispondente `id="title"`.

**User Story #2:** La mia mappa coropletica dovrebbe avere un elemento descrittivo con un corrispondente `id="description"`.

**User Story #3:** La mia mappa coropletica dovrebbe avere le contee con una classe `class="county"` corrispondente.

**User Story #4:** Dovrebbero essere usati almeno 4 colori di riempimento diversi per le contee.

**User Story #5:** Le mie contee dovrebbero avere le proprietà `data-fips` e `data-education` contenenti i loro valori corrispondenti `fips` e `education`.

**User Story #6:** La mia mappa coropletica dovrebbe avere una contea per ogni data point fornito.

**User Story #7:** Le contee dovrebbero avere valori `data-fips` e `data-education` che corrispondono ai dati del campione.

**User Story #8:** La mia mappa coropletica dovrebbe avere una legenda con corrispondente `id="legend"`.

**User Story #9:** Dovrebbero essere usati almeno 4 colori di riempimento diversi per la legenda.

**User Story #10:** Posso passare con il mouse su un'area e vedere un suggerimento con un corrispondente `id="tooltip"` che mostra maggiori informazioni sull'area.

**User Story #11:** Il mio suggerimento dovrebbe avere una proprietà `data-education` che corrisponde alla `data-education` dell'area attiva.

Ecco i set di dati necessari per completare questo progetto:

-   **Dati sull'educazione negli Stati Uniti:**`https://cdn.freecodecamp.org/testable-projects-fcc/data/choropleth_map/for_user_education.json`
-   **Dati sull'educazione nelle contee degli Stati Uniti:**`https://cdn.freecodecamp.org/testable-projects-fcc/data/choropleth_map/counties.json`

Puoi costruire il tuo progetto usando questo modello CodePen e facendo click su `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`

Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test superati.

# --solutions--

```js
// solution required
```


text:
package com.google.android.apps.mytracks;

import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.maps.mytracks.R;

import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.ResourceCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * A section based resource cursor adapter. Currently only supports one
 * additional section header, "Shared with me".
 *
 * @author Jimmy Shih
 */
public abstract class SectionResourceCursorAdapter extends ResourceCursorAdapter {

  private enum ItemType {
    TRACK, HEADER
  }

  private final LayoutInflater layoutInflater;
  private int sharedWithMeIndex = -1;

  public SectionResourceCursorAdapter(Context context, int layout, Cursor cursor, int flags) {
    super(context, layout, cursor, flags);
    this.layoutInflater = LayoutInflater.from(context);
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    if (getItemViewType(position) == ItemType.TRACK.ordinal()) {
      return super.getView(getCursorPosition(position), convertView, parent);
    } else {
      TextView textView;
      if (convertView == null) {
        textView = (TextView) layoutInflater.inflate(R.layout.track_list_header, parent, false);
      } else {
        textView = (TextView) convertView;
      }
      return textView;
    }
  }

  @Override
  public int getViewTypeCount() {
    return ItemType.values().length;
  }

  @Override
  public int getCount() {
    int count = super.getCount();
    return count != 0 && sharedWithMeIndex != -1 ? count + 1 : count;
  }

  @Override
  public boolean isEnabled(int position) {
    return getItemViewType(position) == ItemType.TRACK.ordinal();
  }

  @Override
  public Object getItem(int position) {
    if (getItemViewType(position) == ItemType.TRACK.ordinal()) {
      return super.getItem(getCursorPosition(position));
    }
    return null;
  }

  @Override
  public long getItemId(int position) {
    if (getItemViewType(position) == ItemType.TRACK.ordinal()) {
      return super.getItemId(getCursorPosition(position));
    }
    return -1L;
  }

  @Override
  public int getItemViewType(int position) {
    if (sharedWithMeIndex != -1 && sharedWithMeIndex == position) {
      return ItemType.HEADER.ordinal();
    }
    return ItemType.TRACK.ordinal();
  }

  @Override
  public Cursor swapCursor(Cursor newCursor) {
    Cursor oldCursor = super.swapCursor(newCursor);
    sharedWithMeIndex = getSharedWithMeIndex();
    return oldCursor;
  }

  /**
   * Gets the Shared with me header index.
   */
  private int getSharedWithMeIndex() {
    int i = 0;
    Cursor cursor = getCursor();
    if (cursor != null && cursor.moveToFirst()) {
      int index = cursor.getColumnIndex(TracksColumns.SHAREDWITHME);
      do {
        int sharedWithMe = cursor.getInt(index);
        if (sharedWithMe == 1) {
          // Returns the index where sharedWithMe == 1
          return i;
        }
        i++;
      } while (cursor.moveToNext());
    }
    return -1;
  }

  /**
   * Gets the underlying cursor position.
   *
   * @param position the requested position
   */
  private int getCursorPosition(int position) {
    if (sharedWithMeIndex != -1 && position > sharedWithMeIndex) {
      return position - 1;
    }
    return position;
  }
}


text:
module Theblog
  class HomeController < Theblog::ApplicationController
    skip_before_action :authenticate_user!

    def index
      @node = Page.find_by(slug: 'home')
      @node ||= Page.first

      @posts = Post.all
    end
  end
end


text:
package integration_test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"testing"

	"github.com/magiconair/properties/assert"
	"github.com/stretchr/testify/require"
	goauth "golang.org/x/oauth2"

	"github.com/ory/fosite"
	"github.com/ory/fosite/compose"
	"github.com/ory/fosite/handler/oauth2" // "github.com/stretchr/testify/assert"
)

func TestAuthorizeCodeFlowWithPublicClientAndPKCE(t *testing.T) {
	for _, strategy := range []oauth2.AccessTokenStrategy{
		hmacStrategy,
	} {
		runAuthorizeCodeGrantWithPublicClientAndPKCETest(t, strategy)
	}
}

func runAuthorizeCodeGrantWithPublicClientAndPKCETest(t *testing.T, strategy interface{}) {
	c := new(compose.Config)
	c.EnforcePKCE = true
	c.EnablePKCEPlainChallengeMethod = true
	f := compose.Compose(c, fositeStore, strategy, nil, compose.OAuth2AuthorizeExplicitFactory, compose.OAuth2PKCEFactory, compose.OAuth2TokenIntrospectionFactory)
	ts := mockServer(t, f, &fosite.DefaultSession{})
	defer ts.Close()

	oauthClient := newOAuth2Client(ts)
	oauthClient.ClientSecret = ""
	oauthClient.ClientID = "public-client"
	fositeStore.Clients["public-client"].(*fosite.DefaultClient).RedirectURIs[0] = ts.URL + "/callback"

	var authCodeUrl string
	var verifier string
	for k, c := range []struct {
		description     string
		setup           func()
		authStatusCode  int
		tokenStatusCode int
	}{
		{
			description: "should fail because no challenge was given",
			setup: func() {
				authCodeUrl = oauthClient.AuthCodeURL("12345678901234567890")
			},
			authStatusCode: http.StatusNotAcceptable,
		},
		{
			description: "should pass",
			setup: func() {
				verifier = "somechallengesomechallengesomechallengesomechallengesomechallengesomechallenge"
				authCodeUrl = oauthClient.AuthCodeURL("12345678901234567890") + "&code_challenge=somechallengesomechallengesomechallengesomechallengesomechallengesomechallenge"
			},
			authStatusCode: http.StatusOK,
		},
		{
			description: "should fail because the verifier is mismatching",
			setup: func() {
				verifier = "failchallengefailchallengefailchallengefailchallengefailchallengefailchallengefailchallengefailchallenge"
				authCodeUrl = oauthClient.AuthCodeURL("12345678901234567890") + "&code_challenge=somechallengesomechallengesomechallengesomechallengesomechallengesomechallengesomechallengesomechallenge"
			},
			authStatusCode:  http.StatusOK,
			tokenStatusCode: http.StatusBadRequest,
		},
	} {
		t.Run(fmt.Sprintf("case=%d/description=%s", k, c.description), func(t *testing.T) {
			c.setup()

			t.Logf("Got url: %s", authCodeUrl)

			resp, err := http.Get(authCodeUrl)
			require.NoError(t, err)
			require.Equal(t, resp.StatusCode, c.authStatusCode)

			if resp.StatusCode == http.StatusOK {
				// This should fail because no verifier was given
				// _, err := oauthClient.Exchange(goauth.NoContext, resp.Request.URL.Query().Get("code"))
				// require.Error(t, err)
				// require.Empty(t, token.AccessToken)
				t.Logf("Got redirect url: %s", resp.Request.URL)

				resp, err := http.PostForm(ts.URL+"/token", url.Values{
					"code":          {resp.Request.URL.Query().Get("code")},
					"grant_type":    {"authorization_code"},
					"client_id":     {"public-client"},
					"redirect_uri":  {ts.URL + "/callback"},
					"code_verifier": {verifier},
				})
				require.NoError(t, err)
				defer resp.Body.Close()

				body, err := ioutil.ReadAll(resp.Body)
				require.NoError(t, err)

				if c.tokenStatusCode != 0 {
					require.Equal(t, c.tokenStatusCode, resp.StatusCode)
					token := goauth.Token{}
					require.NoError(t, json.Unmarshal(body, &token))
					require.Empty(t, token.AccessToken)
					return
				}

				assert.Equal(t, resp.StatusCode, http.StatusOK)
				token := goauth.Token{}
				require.NoError(t, json.Unmarshal(body, &token))

				require.NotEmpty(t, token.AccessToken, "Got body: %s", string(body))

				httpClient := oauthClient.Client(goauth.NoContext, &token)
				resp, err = httpClient.Get(ts.URL + "/info")
				require.NoError(t, err)
				assert.Equal(t, http.StatusOK, resp.StatusCode)
			}
		})
	}
}


text:
Twitter clone based on Symfony2 and Redis
====

#Raison D'être

Long time ago to show redis capabilities a twitter clone was built using PHP. PHP was used because it was easy enough for everybody to understand. To get a glimpse at the code you can go to http://redis.io/topics/twitter-clone. That tutorial had sole intention of making developers better understand what is redis, how redis works and how to use it.
When you try to read the code of the app unfortunately it fails to deliver on any of those points.

I decided to take idea of that twitter clone app and build it as good as I can using OOP approach. To build it I didn't use pure PHP like its predecessor did but I incorporated Symfony2 framework within it.

Hopefully when you try to read the code now you will get better sense of how to use certain redis features and what all can redis do for you.


text:
package org.jcote.domino.checkable.tag;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.jcote.domino.checkable.Checkable;
import org.jcote.domino.checkable.NodeCallback;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * @author jordancote
 *
 */
public class TagMatch extends Checkable {
	HashMap<String, HashMap<String,String>> matchTags;  // tag name -> (attr name -> attr value)

	/**
	 *
	 */
	public TagMatch() {
		super();
		matchTags = new HashMap<>();
	}

	public TagMatch(NodeCallback callback) {
		super(callback);
		matchTags = new HashMap<>();
	}

	public TagMatch(String tagName, String attrName, String attrValue, NodeCallback callback) {
		this(callback);
		addCriteria(tagName, attrName, attrValue);
	}

	public TagMatch(String tagName, String attrName, String attrValue) {
		this();
		addCriteria(tagName, attrName, attrValue);
	}

	/**
	 * @param tagName
	 * @param attrName
	 * @param attrValue
	 * @param callback
	 */
	public void addCriteria(String tagName, String attrName, String attrValue) {
		tagName = tagName.toUpperCase();
		if (matchTags.containsKey(tagName)) {
			// tag already exists, add criteria to matchTags entry
			matchTags.get(tagName).put(attrName, attrValue);
		} else {
			// tag does not exist, create new matchTags entry
			HashMap<String, String> attrMap = new HashMap<>();
			attrMap.put(attrName, attrValue);
			matchTags.put(tagName, attrMap);
		}
	}

	/**checks criteria on single tag
	 * @param node
	 */
	public boolean checkImpl(Node node) {
		String nodeName = node.getNodeName();
    	if (!matchTags.containsKey(nodeName)) {
    		return false;
    	}
    	if (node.getAttributes() == null) {
    		return false;
    	}
		// tag found, scan for all specified match attributes
		return checkAttrs(node);
	}

	/**
	 * Checks that all attributes are contained on the given node
	 * @param node
	 * @return
	 */
	public boolean checkAttrs(Node node) {
		NamedNodeMap attrs = node.getAttributes();
		if (attrs.getLength() == 0) {
			return false;
		}
		HashMap<String,String> matchAttrMap = matchTags.get(node.getNodeName());
		for (Entry<String, String> matchAttrEntry : matchAttrMap.entrySet()) {
			Node attrNode = attrs.getNamedItem(matchAttrEntry.getKey());
			if (!matchAttrEntry.getValue().equalsIgnoreCase(attrNode.getNodeValue())) {
				return false;
			}
		}
		return true;
	}

}


text: See [releases](https://github.com/shaungrady/angular-http-etag/releases).


text:
namespace 材化虚拟实验室
{
    partial class TemperatureForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
           /* if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);*/
            this.Hide();
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.splitContainer1 = new System.Windows.Forms.SplitContainer();
            this.splitContainer2 = new System.Windows.Forms.SplitContainer();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
            this.splitContainer1.Panel1.SuspendLayout();
            this.splitContainer1.Panel2.SuspendLayout();
            this.splitContainer1.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
            this.splitContainer2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            //
            // timer1
            //
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            //
            // splitContainer1
            //
            this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.splitContainer1.Location = new System.Drawing.Point(0, 0);
            this.splitContainer1.Name = "splitContainer1";
            this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
            //
            // splitContainer1.Panel1
            //
            this.splitContainer1.Panel1.Controls.Add(this.splitContainer2);
            //
            // splitContainer1.Panel2
            //
            this.splitContainer1.Panel2.Controls.Add(this.pictureBox1);
            this.splitContainer1.Size = new System.Drawing.Size(1022, 494);
            this.splitContainer1.SplitterDistance = 250;
            this.splitContainer1.TabIndex = 0;
            //
            // splitContainer2
            //
            this.splitContainer2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
            this.splitContainer2.Location = new System.Drawing.Point(0, 0);
            this.splitContainer2.Name = "splitContainer2";
            this.splitContainer2.Size = new System.Drawing.Size(1022, 250);
            this.splitContainer2.SplitterDistance = 497;
            this.splitContainer2.TabIndex = 0;
            //
            // pictureBox1
            //
            this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.pictureBox1.Location = new System.Drawing.Point(0, 0);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(1022, 240);
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            //
            // TemperatureForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1022, 494);
            this.Controls.Add(this.splitContainer1);
            this.Name = "TemperatureForm";
            this.Text = "温度场";
            this.Load += new System.EventHandler(this.TemperatureForm_Load);
            this.splitContainer1.Panel1.ResumeLayout(false);
            this.splitContainer1.Panel2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
            this.splitContainer1.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
            this.splitContainer2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        public System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.SplitContainer splitContainer1;
        public System.Windows.Forms.SplitContainer splitContainer2;
        private System.Windows.Forms.PictureBox pictureBox1;
    }
}


text:
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;

class Test {

  public static void foo() {
    String result = null;
    try {
      result = createString();
    }
    catch (Exception e) {
      Assert.fail();
    }
    finally {
      if (result == null) {
        System.out.println("Analysis failed!");
      }
    }
  }

  private static @NotNull String createString() {
    throw new NullPointerException();
  }
}


text:
<?php

ini_set('error_reporting', (string) \E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');


text:
package com.eagle.programmar.COBOL.Statements;

import com.eagle.programmar.COBOL.COBOL_AbstractStatement;
import com.eagle.programmar.COBOL.COBOL_Expression;
import com.eagle.programmar.COBOL.Statements.COBOL_UnstringStatement.COBOL_UnstringOrClause.COBOL_UnstringOrWhat;
import com.eagle.programmar.COBOL.Symbols.COBOL_Identifier_Reference;
import com.eagle.programmar.COBOL.Terminals.COBOL_Keyword;
import com.eagle.programmar.COBOL.Terminals.COBOL_Literal;
import com.eagle.tokens.TokenChooser;
import com.eagle.tokens.TokenList;
import com.eagle.tokens.TokenSequence;
import com.eagle.tokens.punctuation.PunctuationComma;

public class COBOL_UnstringStatement extends COBOL_AbstractStatement
{
	public @DOC("rlpsunst.htm") COBOL_Keyword UNSTRING = new COBOL_Keyword("UNSTRING");
	public COBOL_Expression expr;
	public COBOL_Keyword DELIMITED = new COBOL_Keyword("DELIMITED");
	public COBOL_Keyword BY = new COBOL_Keyword("BY");
	public COBOL_UnstringOrWhat delim;
	public @OPT COBOL_UnstringOrClause orClause;
	public COBOL_Keyword INTO = new COBOL_Keyword("INTO");
	public TokenList<COBOL_UnstringPiece> pieces;
	public @OPT COBOL_UnstringWith with;
	public @OPT COBOL_Keyword ENDUNSTRING = new COBOL_Keyword("END-UNSTRING");

	public static class COBOL_UnstringOrClause extends TokenSequence
	{
		public COBOL_Keyword OR = new COBOL_Keyword("OR");
		public COBOL_UnstringOrWhat unstringWhat;

		public static class COBOL_UnstringOrWhat extends TokenChooser
		{
			public @CHOICE COBOL_Literal delim;

			public @CHOICE static class COBOL_UnstringOrSpaces extends TokenSequence
			{
				public @OPT COBOL_Keyword ALL = new COBOL_Keyword("ALL");
				public COBOL_Keyword SPACES = new COBOL_Keyword("SPACES");
			}
		}
	}

	public static class COBOL_UnstringPiece extends TokenSequence
	{
		public @OPT PunctuationComma comma;
		public COBOL_Identifier_Reference intoVar;
		public @OPT COBOL_UnstringCount count;

		public static class COBOL_UnstringCount extends TokenSequence
		{
			public COBOL_Keyword COUNT = new COBOL_Keyword("COUNT");
			public COBOL_Keyword IN = new COBOL_Keyword("IN");
			public COBOL_Identifier_Reference countVar;
		}
	}

	public static class COBOL_UnstringWith extends TokenSequence
	{
		public COBOL_Keyword WITH = new COBOL_Keyword("WITH");
		public COBOL_Keyword POINTER = new COBOL_Keyword("POINTER");
		public COBOL_Identifier_Reference withPointer;
	}
}


text:
require 'spec_helper'

describe 'diffmerge' do

  it do
    should contain_package('DiffMerge').with({
      :source   => 'http://download-us.sourcegear.com/DiffMerge/4.2.0/DiffMerge.4.2.0.697.intel.stable.dmg',
      :provider => 'appdmg'
    })
  end
end