text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>AlarmAttendant</title>
<meta name="date" content="2015-07-15">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

models

Class AlarmAttendant

java.lang.Object

play.db.ebean.Model

models.AlarmAttendant

All Implemented Interfaces:

com.avaje.ebean.bean.EntityBean, java.io.Serializable

@Entity
public class AlarmAttendant
extends play.db.ebean.Model

See Also:

Serialized Form

Nested Class Summary

Nested classes/interfaces inherited from class play.db.ebean.Model

play.db.ebean.Model.Finder<I,T>

Field Summary

Fields

Modifier and Type
Field and Description

static int
ADMINISTRATOR

static int
API_BASIC

static int
API_FULL

static int
API_MEDIUM

static int
ATTENDANT

static int
FIELDOPERATOR

static play.db.ebean.Model.Finder<java.lang.Long,AlarmAttendant>
find

java.lang.String
gcmRegId

java.lang.Long
id

java.lang.String
password

int
role

java.lang.String
username

Fields inherited from class play.db.ebean.Model

_ebean_identity, _ebean_intercept

Constructor Summary

Constructors

Constructor and Description

AlarmAttendant()

Method Summary

All Methods Static Methods Instance Methods Concrete Methods

Modifier and Type
Method and Description

static java.util.List<AlarmAttendant>
all()

static void
create(AlarmAttendant attendant)

static void
delete(java.lang.Long id)

static AlarmAttendant
get(java.lang.Long id)

static AlarmAttendant
getAndInjectIntoCache(java.lang.Long id)

Retrieves a user object by its ID and injects it into the Cache

static AlarmAttendant
getAttendantFromUsername(java.lang.String attendantUserName)

static java.util.List<AlarmAttendant>
getMobileCareTakers()

Retrieve a list of all Mobile Care Takers (Field operators).

static boolean
isAdministrator(AlarmAttendant attendant)

static boolean
isAttendant(AlarmAttendant attendant)

static boolean
isFieldOperator(AlarmAttendant attendant)

static com.fasterxml.jackson.databind.node.ObjectNode
toJson(AlarmAttendant a)

Helper method that returns an AlarmAttendant as JSON

java.lang.String
validate()

Perform some simple data validity checks on the model fields

Methods inherited from class play.db.ebean.Model

_ebean_createCopy, _ebean_get__idGetSet, _ebean_getField, _ebean_getFieldIntercept, _ebean_getFieldNames, _ebean_getIntercept, _ebean_getMarker, _ebean_getni__idGetSet, _ebean_intercept, _ebean_isEmbeddedNewOrDirty, _ebean_newInstance, _ebean_set__idGetSet, _ebean_setEmbeddedLoaded, _ebean_setField, _ebean_setFieldIntercept, _ebean_setni__idGetSet, addPropertyChangeListener, addPropertyChangeListener, delete, delete, deleteManyToManyAssociations, equals, hashCode, refresh, refresh, removePropertyChangeListener, removePropertyChangeListener, save, save, saveManyToManyAssociations, saveManyToManyAssociations, update, update, update, update

Methods inherited from class java.lang.Object

clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait

Field Detail

ADMINISTRATOR

public static final int ADMINISTRATOR

See Also:

Constant Field Values

ATTENDANT

public static final int ATTENDANT

See Also:

Constant Field Values

FIELDOPERATOR

public static final int FIELDOPERATOR

See Also:

Constant Field Values

API_FULL

public static final int API_FULL

See Also:

Constant Field Values

API_MEDIUM

public static final int API_MEDIUM

See Also:

Constant Field Values

API_BASIC

public static final int API_BASIC

See Also:

Constant Field Values

id

public java.lang.Long id

username

public java.lang.String username

password

public java.lang.String password

role

public int role

gcmRegId

public java.lang.String gcmRegId

find

public static play.db.ebean.Model.Finder<java.lang.Long,AlarmAttendant> find

Constructor Detail

AlarmAttendant

public AlarmAttendant()

Method Detail

all

public static java.util.List<AlarmAttendant> all()

get

public static AlarmAttendant get(java.lang.Long id)

create

public static void create(AlarmAttendant attendant)

validate

public java.lang.String validate()

Perform some simple data validity checks on the model fields

Returns:

A string containing an error, if occurred, null if no errors.

getAndInjectIntoCache

public static AlarmAttendant getAndInjectIntoCache(java.lang.Long id)

Retrieves a user object by its ID and injects it into the Cache

Parameters:

id - The user ID of the user to be retrieved

Returns:

The AlarmAttendant corresponding to the provided id

getMobileCareTakers

public static java.util.List<AlarmAttendant> getMobileCareTakers()

Retrieve a list of all Mobile Care Takers (Field operators). If no AlarmAttendants with that role
 exists, an empty list is returned.

Returns:

A List of AlarmAttendants with role == 3.

delete

public static void delete(java.lang.Long id)

getAttendantFromUsername

public static AlarmAttendant getAttendantFromUsername(java.lang.String attendantUserName)

isAdministrator

public static boolean isAdministrator(AlarmAttendant attendant)

isAttendant

public static boolean isAttendant(AlarmAttendant attendant)

isFieldOperator

public static boolean isFieldOperator(AlarmAttendant attendant)

toJson

public static com.fasterxml.jackson.databind.node.ObjectNode toJson(AlarmAttendant a)

Helper method that returns an AlarmAttendant as JSON

Parameters:

a - The AlarmAttendant to serialize

Returns:

A JSON ObjectNode representing the AlarmAttendant

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

redpajama_set_name: RedPajamaGithub


text: Node launcher open source


text:
from autobahn.twisted.wamp import Application

app = Application()

def onEvent(msg):
    print("got event: {}".format(msg))

@app.register(u'com.example.triggersubscribe')
def triggerSubscribe():
    print("triggersubscribe() called")
    yield app.session.subscribe(onEvent, u'com.example.topic1')

@app.signal('onjoined')
def onjoined():
    print("realm joined!")

if __name__ == "__main__":
    app.run(u"ws://127.0.0.1:8080/ws", u"realm1", standalone=True)


text:
package gov.nih.nci.ncicb.xmiinout.domain;

/**
 * Wrapper class for a Class Final modifier (attribute).
 */
public interface UMLFinalModifier {

  /**
   *
   * @return boolean value, for example 'true'
   */
  public boolean isFinal();

}


text:
// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.skyframe;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction.Factory;
import com.google.devtools.build.lib.bugreport.BugReporter;
import com.google.devtools.build.lib.packages.PackageFactory;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionName;

/**
* A factory that creates instances of SkyframeExecutor.
*/
public interface SkyframeExecutorFactory {

  /**
   * Creates an instance of SkyframeExecutor
   *
   * @param pkgFactory the package factory
   * @param fileSystem the Blaze file system
   * @param directories Blaze directories
   * @param workspaceStatusActionFactory a factory for creating WorkspaceStatusAction objects
   * @param bugReporter BugReporter: always BugReporter.defaultInstance() outside of Java tests
   * @return an instance of the SkyframeExecutor
   * @throws AbruptExitException if the executor cannot be created
   */
  SkyframeExecutor create(
      PackageFactory pkgFactory,
      FileSystem fileSystem,
      BlazeDirectories directories,
      ActionKeyContext actionKeyContext,
      Factory workspaceStatusActionFactory,
      Iterable<? extends DiffAwareness.Factory> diffAwarenessFactories,
      ImmutableMap<SkyFunctionName, SkyFunction> extraSkyFunctions,
      Iterable<SkyValueDirtinessChecker> customDirtinessCheckers,
      ManagedDirectoriesKnowledge managedDirectoriesKnowledge,
      BugReporter bugReporter)
      throws AbruptExitException;
}


text:
package org.litepal.util.cipher;

import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Utility to manage encryption and decryption for different algorithms.
 *
 * @author Tony Green
 * @since 1.6
 */
public class CipherUtil {

    private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    public static String aesKey = "LitePalKey";

    /**
     * Encrypt the plain text with AES algorithm.
     * @param plainText
     *          The plain text.
     * @return The Encrypt content.
     */
    public static String aesEncrypt(String plainText) {
        if (TextUtils.isEmpty(plainText)) {
            return plainText;
        }
        try {
            return AESCrypt.encrypt(aesKey, plainText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Decrypt the encrypted text with AES algorithm.
     * @param encryptedText
     *          The encrypted text.
     * @return The plain content.
     */
    public static String aesDecrypt(String encryptedText) {
        if (TextUtils.isEmpty(encryptedText)) {
            return encryptedText;
        }
        try {
            return AESCrypt.decrypt(aesKey, encryptedText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Encrypt the plain text with MD5 algorithm.
     * @param plainText
     *          The plain text.
     * @return The Encrypt content.
     */
    public static String md5Encrypt(String plainText) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(plainText.getBytes(Charset.defaultCharset()));
            return new String(toHex(digest.digest()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    private static char[] toHex(byte[] data) {
        char[] toDigits = DIGITS_UPPER;
        int l = data.length;
        char[] out = new char[l << 1];
        // two characters form the hex value.
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
        return out;
    }

}


text:
<?php

use yii\helpers\Html;
use kartik\widgets\ActiveForm;
use kartik\builder\Form;

/* @var $this yii\web\View */
/* @var $model common\models\p\LimitacionesCapitales */
/* @var $form yii\widgets\ActiveForm */
?>

   <?php $form = ActiveForm::begin(); ?>

    <?php echo Form::widget([
    'model'=>$model,
    'form'=>$form,
    'columns'=>4,
    'attributes'=>$model->getFormAttribs()
      ]);?>

        <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

    <?php ActiveForm::end(); ?>


text:
using namespace OpenP2P;

int main() {
	UDP::Socket socket(46667);

	Crypt::AutoSeededRandomPool rand;
	Crypt::ECDSA::PrivateKey privateKey(rand, Crypt::ECDSA::brainpoolP256r1);

	RootNetwork::PrivateIdentity privateIdentity(privateKey);

	RootNetwork::PacketSocket packetSocket(socket);

	RootNetwork::AuthenticatedSocket authenticatedSocket(privateIdentity, packetSocket);

	RootNetwork::Service service(authenticatedSocket);

	const RootNetwork::NodeId nodeId = service.identifyEndpoint(UDP::Endpoint(IP::V4Address::Localhost(), 46668));

	(void) nodeId;

	const auto endpoint = service.pingNode(UDP::Endpoint(IP::V4Address::Localhost(), 46668), RootNetwork::NodeId());

	printf("My endpoint is '%s'.\n", endpoint.udpEndpoint.toString().c_str());

	const auto networks = service.queryNetworks(UDP::Endpoint(IP::V4Address::Localhost(), 46668), RootNetwork::NodeId());

	printf("Node supports %llu networks.\n", (unsigned long long) networks.size());

	for (size_t i = 0; i < networks.size(); i++) {
		printf("    Network %llu: %s.\n", (unsigned long long) i, networks.at(i).hexString().c_str());
		if (networks.at(i) == RootNetwork::NetworkId::Generate("test")) {
			printf("         -> Supports 'test' network.\n");
		}
	}

	return 0;
}


text:
echo "sets the git hooks directory to this directory"
echo "Requires git >= 2.9"
echo "your git version:"
git --version
echo "let's try:"
git config core.hooksPath "$(pwd)"
echo "done"


text:
const RepresentationList = require('./representationList');

class MusicList extends RepresentationList {
  constructor(client, parent) {
    super(client, parent);
    this.type = 'musicList';
    this.itemType = 'music';
  }
}

module.exports = MusicList;


text:
.class public Landroid/drm/DrmConvertedStatus;
.super Ljava/lang/Object;
.source "DrmConvertedStatus.java"

# static fields
.field public static final STATUS_ERROR:I = 0x3

.field public static final STATUS_INPUTDATA_ERROR:I = 0x2

.field public static final STATUS_OK:I = 0x1

# instance fields
.field public final convertedData:[B

.field public final offset:I

.field public final statusCode:I

# direct methods
.method public constructor <init>(I[BI)V
    .locals 0
    .parameter "_statusCode"
    .parameter "_convertedData"
    .parameter "_offset"

    .prologue
    .line 47
    invoke-direct/range {p0 .. p0}, Ljava/lang/Object;-><init>()V

    .line 48
    iput p1, p0, Landroid/drm/DrmConvertedStatus;->statusCode:I

    .line 49
    iput-object p2, p0, Landroid/drm/DrmConvertedStatus;->convertedData:[B

    .line 50
    iput p3, p0, Landroid/drm/DrmConvertedStatus;->offset:I

    .line 51
    return-void
.end method


text:
jasmine.getFixtures().fixturesPath = '../../src/FeedTestSite';

describe('Test Templates', function() {

  beforeEach(function() {
    loadFixtures('ops-feed-lib.html');
  });

  afterEach(function() {

  });

  describe('Given the templates page', function() {

    it('should have a feed template', function() {

      var feed = $('template.ops-feed-per');

      expect(feed).toBeInDOM();

    });

    it('should have a feed timeline template', function() {

     var feed = $('template.ops-feed-timeline');

      expect(feed).toBeInDOM();
    });

  });

   describe('Given the feed template', function() {

    it('should have a feed header', function() {

      var feed = $('template.ops-feed-per h3');

      expect(feed).toBeInDOM();

    });

  });

   describe('Given the feed timeline template', function() {

    it('should have a feed header', function() {

      var feed = $('template.ops-feed-timeline h3');

      expect(feed).toBeInDOM();

    });

  });

});


text:
//
// vi:cin:et:sw=4 ts=4
//
//  config.cc - part of drafter
//
//  Created by Jiri Kratochvil on 2015-02-13
//  Copyright (c) 2015 Apiary Inc. All rights reserved.
//

#include "config.h"
#include "cmdline.h"

#include "Version.h"

namespace config {
    static const std::string Program        = "drafter";

    static const std::string Output         = "output";
    static const std::string Format         = "format";
    static const std::string Render         = "render";
    static const std::string Sourcemap      = "sourcemap";
    static const std::string Validate       = "validate";
    static const std::string Version        = "version";
    static const std::string UseLineNumbers = "use-line-num";
};

void PrepareCommanLineParser(cmdline::parser& parser)
{
    parser.set_program_name(config::Program);

    parser.add<std::string>(config::Output,    'o', "save output AST into file", false);
    parser.add<std::string>(config::Format,    'f', "output AST format", false, "yaml", cmdline::oneof<std::string>("yaml", "json"));
    parser.add<std::string>(config::Sourcemap, 's', "export sourcemap AST into file", false);
    parser.add("help",                         'h', "display this help message");
    parser.add(config::Version ,               'v', "print Drafter version");
    parser.add(config::Validate,               'l', "validate input only, do not print AST");
    parser.add(config::UseLineNumbers ,        'u', "use line and row number instead of character index when printing annotation");

    std::stringstream ss;

    ss << "<input file>\n\n";
    ss << "API Blueprint Parser\n";
    ss << "If called without <input file>, 'drafter' will listen on stdin.\n";

    parser.footer(ss.str());
}

void ValidateParsedCommandLine(const cmdline::parser& parser)
{
    if (parser.rest().size() > 1) {
        std::cerr << "one input file expected, got " << parser.rest().size() << std::endl;
        exit(EXIT_FAILURE);
    }

    if (parser.exist(config::Version)) {
        std::cout << DRAFTER_VERSION_STRING << std::endl;
        exit(EXIT_SUCCESS);
    }

}

void ParseCommadLineOptions(int argc, const char *argv[], /* out */Config& conf)
{
    cmdline::parser parser;
    PrepareCommanLineParser(parser);

    parser.parse_check(argc, argv);

    ValidateParsedCommandLine(parser);

    if (!parser.rest().empty()) {
        conf.input = parser.rest().front();
    }

    conf.lineNumbers = parser.exist(config::UseLineNumbers);
    conf.validate    = parser.exist(config::Validate);
    conf.format      = parser.get<std::string>(config::Format);
    conf.output      = parser.get<std::string>(config::Output);
    conf.sourceMap   = parser.get<std::string>(config::Sourcemap);
}


text:
export default (expenses) => {
  return expenses
      .map((expense) => expense.amount)
      .reduce((sum, value) => sum + value, 0); // initial accumulator value is 0
};


text:
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="PublishConfigData" serverName="UYBGames" uploadOnCheckin="05b84146-72a1-4678-9ffa-3d9f1642ef70" autoUploadExternalChanges="true">
    <serverData>
      <paths name="UYBGames">
        <serverdata>
          <mappings>
            <mapping deploy="/frameworks/UYBGames" local="$PROJECT_DIR$" web="/" />
            <mapping deploy="/apache2/htdocs/css_library" local="$PROJECT_DIR$/web/css_library" web="/csslib" />
            <mapping deploy="/apache2/htdocs/js_library" local="$PROJECT_DIR$/web/js_library" web="/jslib" />
            <mapping deploy="/apache2/htdocs/img/UYBG_img" local="$PROJECT_DIR$/web/img/UYBG_img" web="/UYBGimglib" />
          </mappings>
        </serverdata>
      </paths>
    </serverData>
    <option name="myUploadOnCheckinName" value="UYBGames" />
  </component>
</project>


text:
/* $XFree86: xc/programs/xmessage/xmessage.h,v 1.2 2003/09/13 21:33:11 dawes Exp $ */
/*
 * Copyright (C) 2003 The XFree86 Project, Inc.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of the XFree86 Project
 * shall not be used in advertising or otherwise to promote the sale,
 * use or other dealings in this Software without prior written
 * authorization from the XFree86 Project.
 */
#ifndef _XMESSAGE_H
#define _XMESSAGE_H

extern const char *ProgramName;
extern int default_exitstatus;

extern Widget make_queryform(Widget, char *, int, char *, Boolean, char *,
    Dimension, Dimension);

#endif


text:
package prefuse.demos;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.text.NumberFormat;
import java.util.Iterator;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.GroupAction;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataColorAction;
import prefuse.action.assignment.DataShapeAction;
import prefuse.action.filter.VisibilityFilter;
import prefuse.action.layout.AxisLabelLayout;
import prefuse.action.layout.AxisLayout;
import prefuse.controls.Control;
import prefuse.controls.ControlAdapter;
import prefuse.controls.ToolTipControl;
import prefuse.data.Table;
import prefuse.data.expression.AndPredicate;
import prefuse.data.expression.Predicate;
import prefuse.data.expression.parser.ExpressionParser;
import prefuse.data.io.DelimitedTextTableReader;
import prefuse.data.query.ListQueryBinding;
import prefuse.data.query.RangeQueryBinding;
import prefuse.data.query.SearchQueryBinding;
import prefuse.render.AxisRenderer;
import prefuse.render.Renderer;
import prefuse.render.RendererFactory;
import prefuse.render.ShapeRenderer;
import prefuse.render.AbstractShapeRenderer;
import prefuse.util.ColorLib;
import prefuse.util.FontLib;
import prefuse.util.UpdateListener;
import prefuse.util.ui.JFastLabel;
import prefuse.util.ui.JRangeSlider;
import prefuse.util.ui.JSearchPanel;
import prefuse.util.ui.UILib;
import prefuse.visual.VisualItem;
import prefuse.visual.VisualTable;
import prefuse.visual.expression.VisiblePredicate;
import prefuse.visual.sort.ItemSorter;

/**
 * @author jeffrey heer
 */
public class Congress extends JPanel {

    public static void main(String[] args) {
        UILib.setPlatformLookAndFeel();

        JFrame f = demo();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    public static JFrame demo() {
        // load the data
        Table t = null;
        try {
            t = new DelimitedTextTableReader().readTable("/fec.txt");
        } catch ( Exception e ) {
            e.printStackTrace();
            System.exit(1);
        }

        JFrame frame = new JFrame((char)0x00a2+" o n g r e s s");
        frame.setContentPane(new Congress(t));
        frame.pack();
        return frame;
    }

    // ------------------------------------------------------------------------

    private static final String TOTAL_RECEIPTS = "Total Receipts";
    private static final String RECEIPTS = "Total Receipts";

    private String m_title = (char)0x00a2+"ongress";
    private String m_totalStr;
    private double m_totalMoney = 1000000000;
    private int m_totalPeople = 10000;
    private JFastLabel m_total = new JFastLabel(m_totalPeople+" Candidates: "+m_totalMoney);
    private JFastLabel m_details;

    private Visualization m_vis;
    private Display m_display;
    private Rectangle2D m_dataB = new Rectangle2D.Double();
    private Rectangle2D m_xlabB = new Rectangle2D.Double();
    private Rectangle2D m_ylabB = new Rectangle2D.Double();

    public Congress(Table t) {
        super(new BorderLayout());

        // --------------------------------------------------------------------
        // STEP 1: setup the visualized data

        final Visualization vis = new Visualization();
        m_vis = vis;

        final String group = "by_state";

        // filter to show only candidates receiving more than $100,000
        Predicate p = (Predicate)
            ExpressionParser.parse("["+TOTAL_RECEIPTS+"] >= 100000");
        VisualTable vt = vis.addTable(group, t, p);

        // add a new column containing a label string showing
        // candidate name, party, state, year, and total receipts
        vt.addColumn("label", "CONCAT(CAP(Candidate), ' (', "
                + "CAP([Party Designation]), '-', [State Code], "
                + "') ', Year, ': $', FORMAT([Total Receipts],2))");

        // add calculation for senators
        vt.addColumn("Senate", "District <= 0");

        vis.setRendererFactory(new RendererFactory() {
            AbstractShapeRenderer sr = new ShapeRenderer();
            Renderer arY = new AxisRenderer(Constants.RIGHT, Constants.TOP);
            Renderer arX = new AxisRenderer(Constants.CENTER, Constants.FAR_BOTTOM);

            public Renderer getRenderer(VisualItem item) {
                return item.isInGroup("ylab") ? arY :
                       item.isInGroup("xlab") ? arX : sr;
            }
        });

        // --------------------------------------------------------------------
        // STEP 2: create actions to process the visual data

        // set up dynamic queries, search set
        RangeQueryBinding  receiptsQ = new RangeQueryBinding(vt, RECEIPTS);
        ListQueryBinding   yearsQ    = new ListQueryBinding(vt, "Year");
        SearchQueryBinding searchQ   = new SearchQueryBinding(vt, "Candidate");

        // construct the filtering predicate
        AndPredicate filter = new AndPredicate(searchQ.getPredicate());
        filter.add(yearsQ.getPredicate());
        filter.add(receiptsQ.getPredicate());

        // set up the actions
        AxisLayout xaxis = new AxisLayout(group, "State Code",
                Constants.X_AXIS, VisiblePredicate.TRUE);
        AxisLayout yaxis = new AxisLayout(group, RECEIPTS,
                Constants.Y_AXIS, VisiblePredicate.TRUE);
        //yaxis.setScale(Constants.LOG_SCALE);
        yaxis.setRangeModel(receiptsQ.getModel());
        receiptsQ.getNumberModel().setValueRange(0,65000000,0,65000000);

        xaxis.setLayoutBounds(m_dataB);
        yaxis.setLayoutBounds(m_dataB);

        AxisLabelLayout ylabels = new AxisLabelLayout("ylab", yaxis, m_ylabB);
        NumberFormat nf = NumberFormat.getCurrencyInstance();
        nf.setMaximumFractionDigits(0);
        ylabels.setNumberFormat(nf);

        AxisLabelLayout xlabels = new AxisLabelLayout("xlab", xaxis, m_xlabB, 15);
        vis.putAction("xlabels", xlabels);

        // dems = blue, reps = red, other = gray
        int[] palette = new int[] {
            ColorLib.rgb(150,150,255), ColorLib.rgb(255,150,150),
            ColorLib.rgb(180,180,180)
        };
        DataColorAction color = new DataColorAction(group, "Party",
                Constants.ORDINAL, VisualItem.STROKECOLOR, palette);

        int[] shapes = new int[]
            { Constants.SHAPE_RECTANGLE, Constants.SHAPE_DIAMOND };
        DataShapeAction shape = new DataShapeAction(group, "Senate", shapes);

        Counter cntr = new Counter(group);

        ActionList draw = new ActionList();
        draw.add(cntr);
        draw.add(color);
        draw.add(shape);
        draw.add(xaxis);
        draw.add(yaxis);
        draw.add(ylabels);
        draw.add(new ColorAction(group, VisualItem.FILLCOLOR, 0));
        draw.add(new RepaintAction());
        vis.putAction("draw", draw);

        ActionList update = new ActionList();
        update.add(new VisibilityFilter(group, filter));
        update.add(cntr);
        update.add(xaxis);
        update.add(yaxis);
        update.add(ylabels);
        update.add(new RepaintAction());
        vis.putAction("update", update);

        UpdateListener lstnr = new UpdateListener() {
            public void update(Object src) {
                vis.run("update");
            }
        };
        filter.addExpressionListener(lstnr);

        // --------------------------------------------------------------------
        // STEP 4: set up a display and ui components to show the visualization

        m_display = new Display(vis);
        m_display.setItemSorter(new ItemSorter() {
            public int score(VisualItem item) {
                int score = super.score(item);
                if ( item.isInGroup(group) )
                    score += item.getInt(TOTAL_RECEIPTS);
                return score;
            }
        });
        m_display.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
        m_display.setSize(700,450);
        m_display.setHighQuality(true);
        m_display.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                displayLayout();
            }
        });
        displayLayout();

        m_details = new JFastLabel(m_title);
        m_details.setPreferredSize(new Dimension(75,20));
        m_details.setVerticalAlignment(SwingConstants.BOTTOM);

        m_total.setPreferredSize(new Dimension(500,20));
        m_total.setHorizontalAlignment(SwingConstants.RIGHT);
        m_total.setVerticalAlignment(SwingConstants.BOTTOM);

        ToolTipControl ttc = new ToolTipControl("label");
        Control hoverc = new ControlAdapter() {
            public void itemEntered(VisualItem item, MouseEvent evt) {
                if ( item.isInGroup(group) ) {
                  m_total.setText(item.getString("label"));
                  item.setFillColor(item.getStrokeColor());
                  item.setStrokeColor(ColorLib.rgb(0,0,0));
                  item.getVisualization().repaint();
                }
            }
            public void itemExited(VisualItem item, MouseEvent evt) {
                if ( item.isInGroup(group) ) {
                  m_total.setText(m_totalStr);
                  item.setFillColor(item.getEndFillColor());
                  item.setStrokeColor(item.getEndStrokeColor());
                  item.getVisualization().repaint();
                }
            }
        };
        m_display.addControlListener(ttc);
        m_display.addControlListener(hoverc);

        // --------------------------------------------------------------------
        // STEP 5: launching the visualization

        this.addComponentListener(lstnr);

        // details
        Box infoBox = new Box(BoxLayout.X_AXIS);
        infoBox.add(Box.createHorizontalStrut(5));
        infoBox.add(m_details);
        infoBox.add(Box.createHorizontalGlue());
        infoBox.add(Box.createHorizontalStrut(5));
        infoBox.add(m_total);
        infoBox.add(Box.createHorizontalStrut(5));

        // set up search box
        JSearchPanel searcher = searchQ.createSearchPanel();
        searcher.setLabelText("Candidate: ");
        searcher.setBorder(BorderFactory.createEmptyBorder(5,5,5,0));

        // create dynamic queries
        Box radioBox = new Box(BoxLayout.X_AXIS);
        radioBox.add(Box.createHorizontalStrut(5));
        radioBox.add(searcher);
        radioBox.add(Box.createHorizontalGlue());
        radioBox.add(Box.createHorizontalStrut(5));
        radioBox.add(yearsQ.createRadioGroup());
        radioBox.add(Box.createHorizontalStrut(16));

        JRangeSlider slider = receiptsQ.createVerticalRangeSlider();
        slider.setThumbColor(null);
        slider.setMinExtent(150000);
        slider.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                m_display.setHighQuality(false);
            }
            public void mouseReleased(MouseEvent e) {
                m_display.setHighQuality(true);
                m_display.repaint();
            }
        });

        vis.run("draw");
        vis.run("xlabels");

        add(infoBox, BorderLayout.NORTH);
        add(m_display, BorderLayout.CENTER);
        add(slider, BorderLayout.EAST);
        add(radioBox, BorderLayout.SOUTH);
        UILib.setColor(this, ColorLib.getColor(255,255,255), Color.GRAY);
        slider.setForeground(Color.LIGHT_GRAY);
        UILib.setFont(radioBox, FontLib.getFont("Tahoma", 15));
        m_details.setFont(FontLib.getFont("Tahoma", 18));
        m_total.setFont(FontLib.getFont("Tahoma", 16));
    }

    public void displayLayout() {
        Insets i = m_display.getInsets();
        int w = m_display.getWidth();
        int h = m_display.getHeight();
        int iw = i.left+i.right;
        int ih = i.top+i.bottom;
        int aw = 85;
        int ah = 15;

        m_dataB.setRect(i.left, i.top, w-iw-aw, h-ih-ah);
        m_xlabB.setRect(i.left, h-ah-i.bottom, w-iw-aw, ah-10);
        m_ylabB.setRect(i.left, i.top, w-iw, h-ih-ah);

        m_vis.run("update");
        m_vis.run("xlabels");
    }

    private class Counter extends GroupAction {
        public Counter(String group) {
            super(group);
        }
        public void run(double frac) {
            double total = 0;
            int count = 0;
            VisualItem item = null;
            Iterator items = m_vis.visibleItems(m_group);
            while ( items.hasNext() ) {
                item = (VisualItem)items.next();
                total += item.getDouble("Total Receipts");
                ++count;
            }
            m_totalMoney = total;
            m_totalPeople = count;

            if ( count == 1 ) {
                m_totalStr = item.getString("label");
            } else {
                m_totalStr = count + " Candidates receiving " +
                    NumberFormat.getCurrencyInstance().format(total);
            }
            m_total.setText(m_totalStr);
        }
    }

} // end of class ScatterPlot


text:
<?php

////
// Get the installed version number
  function osc_get_version() {
    static $v;

    if (!isset($v)) {
      $v = trim(implode('', file('../includes/version.php')));
    }

    return $v;
  }

////
// Sets timeout for the current script.
// Cant be used in safe mode.
  function osc_set_time_limit($limit) {
    if (!get_cfg_var('safe_mode')) {
      set_time_limit($limit);
    }
  }

  function osc_realpath($directory) {
    return str_replace('\\', '/', realpath($directory));
  }

////
// This function encrypts a phpass password from a plaintext
// password.
  function osc_encrypt_password($plain) {
    if (!class_exists('PasswordHash')) {
      include('../includes/classes/passwordhash.php');
    }

    $hasher = new PasswordHash(10, true);

    return $hasher->HashPassword($plain);
  }

////
// Wrapper function for is_writable() for Windows compatibility
  function osc_is_writable($file) {
    if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {
      if (file_exists($file)) {
        $file = realpath($file);
        if (is_dir($file)) {
          $result = @tempnam($file, 'osc');
          if (is_string($result) && file_exists($result)) {
            unlink($result);
            return (strpos($result, $file) === 0) ? true : false;
          }
        } else {
          $handle = @fopen($file, 'r+');
          if (is_resource($handle)) {
            fclose($handle);
            return true;
          }
        }
      } else{
        $dir = dirname($file);
        if (file_exists($dir) && is_dir($dir) && osc_is_writable($dir)) {
          return true;
        }
      }
      return false;
    } else {
      return is_writable($file);
    }
  }

////
// Parse the data used in the html tags to ensure the tags will not break
  function osc_parse_input_field_data($data, $parse) {
    return strtr(trim($data), $parse);
  }

  function osc_output_string($string, $translate = false, $protected = false) {
    if ($protected == true) {
      return htmlspecialchars($string);
    } else {
      if ($translate == false) {
        return osc_parse_input_field_data($string, array('"' => '"'));
      } else {
        return osc_parse_input_field_data($string, $translate);
      }
    }
  }
?>


text:
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.Core.Common.Models;
using Orchard.Core.Containers.Models;
using Orchard.Core.Containers.Services;
using Orchard.Core.Containers.ViewModels;
using Orchard.Localization;
using Orchard.UI.Notify;
using System.Web.Routing;
using Orchard.Settings;
using Orchard.Core.Feeds;
using Orchard.UI.Navigation;

namespace Orchard.Core.Containers.Drivers {
    public class ContainerPartDriver : ContentPartDriver<ContainerPart> {
        private readonly IContentDefinitionManager _contentDefinitionManager;
        private readonly IOrchardServices _orchardServices;
        private readonly IContentManager _contentManager;
        private readonly ISiteService _siteService;
        private readonly IFeedManager _feedManager;
        private readonly IContainerService _containerService;

        public ContainerPartDriver(
            IContentDefinitionManager contentDefinitionManager,
            IOrchardServices orchardServices,
            ISiteService siteService,
            IFeedManager feedManager, IContainerService containerService) {
            _contentDefinitionManager = contentDefinitionManager;
            _orchardServices = orchardServices;
            _contentManager = orchardServices.ContentManager;
            _siteService = siteService;
            _feedManager = feedManager;
            _containerService = containerService;

            T = NullLocalizer.Instance;
        }

        public Localizer T { get; set; }

        protected override DriverResult Display(ContainerPart part, string displayType, dynamic shapeHelper) {
            if (!part.ItemsShown)
                return null;

        return ContentShape("Parts_Container_Contained", () => {
                var container = part.ContentItem;
                var query = _contentManager
                .Query(VersionOptions.Published)
                .Join<CommonPartRecord>().Where(x => x.Container.Id == container.Id)
                .Join<ContainablePartRecord>().OrderByDescending(x => x.Position);

                var metadata = container.ContentManager.GetItemMetadata(container);
                if (metadata!=null)
                _feedManager.Register(metadata.DisplayText, "rss", new RouteValueDictionary { { "containerid", container.Id } });

                var pager = new Pager(_siteService.GetSiteSettings(), part.PagerParameters);
                pager.PageSize = part.PagerParameters.PageSize != null && part.Paginated
                                ? pager.PageSize
                                : part.PageSize;

                var pagerShape = shapeHelper.Pager(pager).TotalItemCount(query.Count());
                var startIndex = part.Paginated ? pager.GetStartIndex() : 0;
                var pageOfItems = query.Slice(startIndex, pager.PageSize).ToList();

                var listShape = shapeHelper.List();
                listShape.AddRange(pageOfItems.Select(item => _contentManager.BuildDisplay(item, "Summary")));
                listShape.Classes.Add("content-items");
                listShape.Classes.Add("list-items");

                return shapeHelper.Parts_Container_Contained(
                    List: listShape,
                    Pager: part.Paginated ? pagerShape : null
                );
            });
        }

        protected override DriverResult Editor(ContainerPart part, dynamic shapeHelper) {
            if (!_contentDefinitionManager.ListTypeDefinitions().Any(typeDefinition => typeDefinition.Parts.Any(partDefinition => partDefinition.PartDefinition.Name == "ContainablePart"))) {
                _orchardServices.Notifier.Warning(T("There are no content types in the system with a Containable part attached. Consider adding a Containable part to some content type, existing or new, in order to relate items to this (Container enabled) item."));
            }
            return Editor(part, (IUpdateModel)null, shapeHelper);
        }

        protected override DriverResult Editor(ContainerPart part, IUpdateModel updater, dynamic shapeHelper) {
            return ContentShape("Parts_Container_Edit", () => {
                var containables = !part.ContainerSettings.RestrictItemContentTypes ? _containerService.GetContainableTypes().ToList() : new List<ContentTypeDefinition>(0);
                var model = new ContainerViewModel {
                    AdminMenuPosition = part.AdminMenuPosition,
                    AdminMenuText = part.AdminMenuText,
                    AdminMenuImageSet = part.AdminMenuImageSet,
                    ItemsShown = part.ItemsShown,
                    PageSize = part.PageSize,
                    Paginated = part.Paginated,
                    SelectedItemContentTypes = part.ItemContentTypes.Select(x => x.Name).ToList(),
                    ShowOnAdminMenu = part.ShowOnAdminMenu,
                    AvailableItemContentTypes = containables,
                    RestrictItemContentTypes = part.ContainerSettings.RestrictItemContentTypes,
                    EnablePositioning = part.Record.EnablePositioning,
                    OverrideEnablePositioning = part.ContainerSettings.EnablePositioning == null
                };

                if (updater != null) {
                    if (updater.TryUpdateModel(model, "Container", null, new[] { "OverrideEnablePositioning" })) {
                        part.AdminMenuPosition = model.AdminMenuPosition;
                        part.AdminMenuText = model.AdminMenuText;
                        part.AdminMenuImageSet = model.AdminMenuImageSet;
                        part.ItemsShown = model.ItemsShown;
                        part.PageSize = model.PageSize;
                        part.Paginated = model.Paginated;
                        part.ShowOnAdminMenu = model.ShowOnAdminMenu;

                        if (!part.ContainerSettings.RestrictItemContentTypes) {
                            part.ItemContentTypes = _contentDefinitionManager.ListTypeDefinitions().Where(x => model.SelectedItemContentTypes.Contains(x.Name));
                        }

                        if (model.OverrideEnablePositioning) {
                            part.Record.EnablePositioning = model.EnablePositioning;
                        }
                    }
                }

                return shapeHelper.EditorTemplate(TemplateName: "Container", Model: model, Prefix: "Container");
            });
        }

        protected override void Importing(ContainerPart part, ImportContentContext context) {
            var itemContentType = context.Attribute(part.PartDefinition.Name, "ItemContentTypes");
            if (itemContentType != null) {
                if (_contentDefinitionManager.GetTypeDefinition(itemContentType) != null) {
                    part.Record.ItemContentTypes = itemContentType;
                }
            }

            context.ImportAttribute(part.PartDefinition.Name, "ItemsShown", s => part.ItemsShown = XmlConvert.ToBoolean(s));
            context.ImportAttribute(part.PartDefinition.Name, "Paginated", s => part.Paginated = XmlConvert.ToBoolean(s));
            context.ImportAttribute(part.PartDefinition.Name, "PageSize", s => part.PageSize = XmlConvert.ToInt32(s));
            context.ImportAttribute(part.PartDefinition.Name, "ShowOnAdminMenu", s => part.ShowOnAdminMenu = XmlConvert.ToBoolean(s));
            context.ImportAttribute(part.PartDefinition.Name, "AdminMenuText", s => part.AdminMenuText = s);
            context.ImportAttribute(part.PartDefinition.Name, "AdminMenuPosition", s => part.AdminMenuPosition = s);
            context.ImportAttribute(part.PartDefinition.Name, "AdminMenuImageSet", s => part.AdminMenuImageSet = s);
            context.ImportAttribute(part.PartDefinition.Name, "ItemCount", s => part.ItemCount = XmlConvert.ToInt32(s));
        }

        protected override void Exporting(ContainerPart part, ExportContentContext context) {
            context.Element(part.PartDefinition.Name).SetAttributeValue("ItemContentTypes", part.Record.ItemContentTypes);
            context.Element(part.PartDefinition.Name).SetAttributeValue("ItemsShown", part.ItemsShown);
            context.Element(part.PartDefinition.Name).SetAttributeValue("Paginated", part.Paginated);
            context.Element(part.PartDefinition.Name).SetAttributeValue("PageSize", part.PageSize);
            context.Element(part.PartDefinition.Name).SetAttributeValue("ShowOnAdminMenu", part.ShowOnAdminMenu);
            context.Element(part.PartDefinition.Name).SetAttributeValue("AdminMenuText", part.AdminMenuText);
            context.Element(part.PartDefinition.Name).SetAttributeValue("AdminMenuPosition", part.AdminMenuPosition);
            context.Element(part.PartDefinition.Name).SetAttributeValue("AdminMenuImageSet", part.AdminMenuImageSet);
            context.Element(part.PartDefinition.Name).SetAttributeValue("ItemCount", part.ItemCount);
        }
    }
}


text:
/*!
 * jquery-viewable
 * filip@salsitasoft.com
 * Released under the MIT license
 */

;(function($) {

  // Defaults
  var element = null;
  var settings = null;
  var $window = $(window);
  var defaultOptions = {
    checkOpacity: true,
    opacityMin: 0,
    checkParents: true,
    checkViewport: true,
    viewportTolerance: 0
  };

  // Is element hidden by CSS values?
  var isVisible = function(el, opacity, opacityMin) {
    // Expect opaque element if we're not checking it
    var opaque = true;
    var displayed = el.css('display') !== 'none' ? true : false;
    var visible = el.css('visibility') !== 'hidden' ? true : false;
    if (opacity) {
      opaque = el.css('opacity') > opacityMin ? true : false;
    };
    return (displayed && visible && opaque);
  };

  // Is element in visible viewport?
  var isInViewport = function(el, tolerance) {
    var rect = el[0].getBoundingClientRect();
    // Using jQuery width()/height() since it factors in overlayed scrollbars
    return !(rect.bottom < 0 + tolerance ||
             rect.right < 0 + tolerance ||
             rect.left > $window.width() - tolerance ||
             rect.top > $window.height() - tolerance);
  };

  // Create jQuery plugin
  $.fn.viewable = function(options) {

    // Get user settings
    settings = $.extend({}, defaultOptions, options);

    // Reference only first element found by query
    element = (this.length > 1) ? this.first() : this;

    // Element CSS value check
    if (!isVisible(element, settings.checkOpacity, settings.opacityMin)) {
      // console.info('Element is not visible');
      return false;
    };

    // Parents CSS value check
    if (settings.checkParents) {
      var state = true;
      element.parents(':not(body, html)').each(function() {
        if (!isVisible($(this), settings.checkOpacity, settings.opacityMin)) {
          state = false;
          return false;
        };
      });
      // console.info('Parent element is not visible');
      if (!state) return false;
    };

    // Viewport check
    if (settings.checkViewport && !isInViewport(element, settings.viewportTolerance)) {
      // console.info('Element is visible, but not in viewport (tolerance: ' + settings.viewportTolerance + 'px)');
      return false;
    };

    // TODO: Below fold check
    // TODO: z-index check
    // TODO: debug

    // Element is viewable
    return true;
  };
})(jQuery, window, document);


text:
FROM sspreitzer/confd:latest
RUN dnf install -y supervisor haproxy && \
    dnf clean all
ENV ETCD_NODE=http://etcd:4001
ADD haproxy.ini /etc/supervisord.d/
VOLUME ["/etc/confd", "/var/log/supervisor", "/etc/haproxy", "/var/lib/haproxy", "/var/log/haproxy.log"]
EXPOSE 80 443
CMD ["/usr/bin/supervisord"]


text:
export default {
  background: "#F2f2f2",
  fontFamily: `mrhouse, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif`,
  headerBgColor: "#F55869",
  headerFontColor: "#fecea8",
  botBubbleColor: "#FFFFFF",
  botFontColor: "#000",
  userBubbleColor: "#fecea8",
  userFontColor: "#000"
};

//botBubbleColor: "#e6e6e6",
//fontFamily: "Helvetica Neue",
//  fontFamily: `Courgette, cursive, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
//"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
//SimSun, sans-serif`,


text:
namespace Halide { namespace Runtime { namespace Internal { namespace Cuda {

// Define the function pointers for the CUDA API.
#define CUDA_FN(ret, fn, args) WEAK ret (CUDAAPI *fn)args;
#define CUDA_FN_3020(ret, fn, fn_3020, args) WEAK ret (CUDAAPI *fn)args;
#define CUDA_FN_4000(ret, fn, fn_4000, args) WEAK ret (CUDAAPI *fn)args;
#include "cuda_functions.h"

// The default implementation of halide_cuda_get_symbol attempts to load
// the CUDA shared library/DLL, and then get the symbol from it.
WEAK void *lib_cuda = NULL;

extern "C" WEAK void *halide_cuda_get_symbol(void *user_context, const char *name) {
    // Only try to load the library if we can't already get the symbol
    // from the library. Even if the library is NULL, the symbols may
    // already be available in the process.
    void *symbol = halide_get_library_symbol(lib_cuda, name);
    if (symbol) {
        return symbol;
    }

    const char *lib_names[] = {
#ifdef WINDOWS
        "nvcuda.dll",
#else
        "libcuda.so",
        "libcuda.dylib",
        "/Library/Frameworks/CUDA.framework/CUDA",
#endif
    };
    for (int i = 0; i < sizeof(lib_names) / sizeof(lib_names[0]); i++) {
        lib_cuda = halide_load_library(lib_names[i]);
        if (lib_cuda) {
            debug(user_context) << "    Loaded CUDA runtime library: " << lib_names[i] << "\n";
            break;
        }
    }

    return halide_get_library_symbol(lib_cuda, name);
}

template <typename T>
INLINE T get_cuda_symbol(void *user_context, const char *name) {
    T s = (T)halide_cuda_get_symbol(user_context, name);
    if (!s) {
        error(user_context) << "CUDA API not found: " << name << "\n";
    }
    return s;
}

// Load a CUDA shared object/dll and get the CUDA API function pointers from it.
WEAK void load_libcuda(void *user_context) {
    debug(user_context) << "    load_libcuda (user_context: " << user_context << ")\n";
    halide_assert(user_context, cuInit == NULL);

    #define CUDA_FN(ret, fn, args) fn = get_cuda_symbol<ret (CUDAAPI *)args>(user_context, #fn);
    #define CUDA_FN_3020(ret, fn, fn_3020, args) fn = get_cuda_symbol<ret (CUDAAPI *)args>(user_context, #fn_3020);
    #define CUDA_FN_4000(ret, fn, fn_4000, args) fn = get_cuda_symbol<ret (CUDAAPI *)args>(user_context, #fn_4000);
    #include "cuda_functions.h"
}

extern WEAK halide_device_interface cuda_device_interface;

WEAK const char *get_error_name(CUresult error);
WEAK CUresult create_cuda_context(void *user_context, CUcontext *ctx);

// A cuda context defined in this module with weak linkage
CUcontext WEAK context = 0;
volatile int WEAK thread_lock = 0;

}}}} // namespace Halide::Runtime::Internal::Cuda

using namespace Halide::Runtime::Internal;
using namespace Halide::Runtime::Internal::Cuda;

extern "C" {

// The default implementation of halide_cuda_acquire_context uses the global
// pointers above, and serializes access with a spin lock.
// Overriding implementations of acquire/release must implement the following
// behavior:
// - halide_acquire_cl_context should always store a valid context/command
//   queue in ctx/q, or return an error code.
// - A call to halide_acquire_cl_context is followed by a matching call to
//   halide_release_cl_context. halide_acquire_cl_context should block while a
//   previous call (if any) has not yet been released via halide_release_cl_context.
WEAK int halide_cuda_acquire_context(void *user_context, CUcontext *ctx, bool create = true) {
    // TODO: Should we use a more "assertive" assert? these asserts do
    // not block execution on failure.
    halide_assert(user_context, ctx != NULL);

    halide_assert(user_context, &thread_lock != NULL);
    while (__sync_lock_test_and_set(&thread_lock, 1)) { }

    // If the context has not been initialized, initialize it now.
    halide_assert(user_context, &context != NULL);
    if (context == NULL && create) {
        CUresult error = create_cuda_context(user_context, &context);
        if (error != CUDA_SUCCESS) {
            __sync_lock_release(&thread_lock);
            return error;
        }
    }

    *ctx = context;
    return 0;
}

WEAK int halide_cuda_release_context(void *user_context) {
    __sync_lock_release(&thread_lock);
    return 0;
}

} // extern "C"

namespace Halide { namespace Runtime { namespace Internal { namespace Cuda {

// Helper object to acquire and release the cuda context.
class Context {
    void *user_context;

public:
    CUcontext context;
    int error;

    // Constructor sets 'error' if any occurs.
    Context(void *user_context) : user_context(user_context),
                                  context(NULL),
                                  error(CUDA_SUCCESS) {
        if (cuInit == NULL) {
            load_libcuda(user_context);
        }

#ifdef DEBUG_RUNTIME
        halide_start_clock(user_context);
#endif
        error = halide_cuda_acquire_context(user_context, &context);
        halide_assert(user_context, context != NULL);
        if (error != 0) {
            return;
        }

        error = cuCtxPushCurrent(context);
    }

    ~Context() {
        CUcontext old;
        cuCtxPopCurrent(&old);

        halide_cuda_release_context(user_context);
    }
};

// Structure to hold the state of a module attached to the context.
// Also used as a linked-list to keep track of all the different
// modules that are attached to a context in order to release them all
// when then context is released.
struct module_state {
    CUmodule module;
    module_state *next;
};
WEAK module_state *state_list = NULL;

WEAK CUresult create_cuda_context(void *user_context, CUcontext *ctx) {
    // Initialize CUDA
    CUresult err = cuInit(0);
    if (err != CUDA_SUCCESS) {
        error(user_context) << "CUDA: cuInit failed: "
                            << get_error_name(err);
        return err;
    }

    // Make sure we have a device
    int deviceCount = 0;
    err = cuDeviceGetCount(&deviceCount);
    if (err != CUDA_SUCCESS) {
        error(user_context) << "CUDA: cuGetDeviceCount failed: "
                            << get_error_name(err);
        return err;
    }
    if (deviceCount <= 0) {
        halide_error(user_context, "CUDA: No devices available");
        return CUDA_ERROR_NO_DEVICE;
    }

    int device = halide_get_gpu_device(user_context);
    if (device == -1) {
        device = deviceCount - 1;
    }

    // Get device
    CUdevice dev;
    CUresult status = cuDeviceGet(&dev, device);
    if (status != CUDA_SUCCESS) {
        halide_error(user_context, "CUDA: Failed to get device\n");
        return status;
    }

    debug(user_context) <<  "    Got device " << dev << "\n";

    // Dump device attributes
    #ifdef DEBUG_RUNTIME
    {
        char name[256];
        name[0] = 0;
        err = cuDeviceGetName(name, 256, dev);
        debug(user_context) << "      " << name << "\n";

        if (err != CUDA_SUCCESS) {
            error(user_context) << "CUDA: cuDeviceGetName failed: "
                                << get_error_name(err);
            return err;
        }

        size_t memory = 0;
        err = cuDeviceTotalMem(&memory, dev);
        debug(user_context) << "      total memory: " << (int)(memory >> 20) << " MB\n";

        if (err != CUDA_SUCCESS) {
            error(user_context) << "CUDA: cuDeviceTotalMem failed: "
                                << get_error_name(err);
            return err;
        }

        // Declare variables for other state we want to query.
        int max_threads_per_block = 0, warp_size = 0, num_cores = 0;
        int max_block_size[] = {0, 0, 0};
        int max_grid_size[] = {0, 0, 0};
        int max_shared_mem = 0, max_constant_mem = 0;
        int cc_major = 0, cc_minor = 0;

        struct {int *dst; CUdevice_attribute attr;} attrs[] = {
            {&max_threads_per_block, CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK},
            {&warp_size,             CU_DEVICE_ATTRIBUTE_WARP_SIZE},
            {&num_cores,             CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT},
            {&max_block_size[0],     CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X},
            {&max_block_size[1],     CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y},
            {&max_block_size[2],     CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z},
            {&max_grid_size[0],      CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X},
            {&max_grid_size[1],      CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y},
            {&max_grid_size[2],      CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z},
            {&max_shared_mem,        CU_DEVICE_ATTRIBUTE_SHARED_MEMORY_PER_BLOCK},
            {&max_constant_mem,      CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY},
            {&cc_major,              CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR},
            {&cc_minor,              CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR},
            {NULL,                   CU_DEVICE_ATTRIBUTE_MAX}};

        // Do all the queries.
        for (int i = 0; attrs[i].dst; i++) {
            err = cuDeviceGetAttribute(attrs[i].dst, attrs[i].attr, dev);
            if (err != CUDA_SUCCESS) {
                error(user_context)
                    << "CUDA: cuDeviceGetAttribute failed ("
                    << get_error_name(err)
                    << ") for attribute " << (int)attrs[i].attr;
                return err;
            }
        }

        // threads per core is a function of the compute capability
        int threads_per_core = (cc_major == 1 ? 8 :
                                cc_major == 2 ? (cc_minor == 0 ? 32 : 48) :
                                cc_major == 3 ? 192 :
                                cc_major == 5 ? 128 : 0);

        debug(user_context)
            << "      max threads per block: " << max_threads_per_block << "\n"
            << "      warp size: " << warp_size << "\n"
            << "      max block size: " << max_block_size[0]
            << " " << max_block_size[1] << " " << max_block_size[2] << "\n"
            << "      max grid size: " << max_grid_size[0]
            << " " << max_grid_size[1] << " " << max_grid_size[2] << "\n"
            << "      max shared memory per block: " << max_shared_mem << "\n"
            << "      max constant memory per block: " << max_constant_mem << "\n"
            << "      compute capability " << cc_major << "." << cc_minor << "\n"
            << "      cuda cores: " << num_cores << " x " << threads_per_core << " = " << threads_per_core << "\n";
    }
    #endif

    // Create context
    debug(user_context) <<  "    cuCtxCreate " << dev << " -> ";
    err = cuCtxCreate(ctx, 0, dev);
    if (err != CUDA_SUCCESS) {
        debug(user_context) << get_error_name(err) << "\n";
        error(user_context) << "CUDA: cuCtxCreate failed: "
                            << get_error_name(err);
        return err;
    } else {
        unsigned int version = 0;
        cuCtxGetApiVersion(*ctx, &version);
        debug(user_context) << *ctx << "(" << version << ")\n";
    }

    return CUDA_SUCCESS;
}

WEAK bool validate_device_pointer(void *user_context, buffer_t* buf, size_t size=0) {
// The technique using cuPointerGetAttribute and CU_POINTER_ATTRIBUTE_CONTEXT
// requires unified virtual addressing is enabled and that is not the case
// for 32-bit processes on Mac OS X. So for now, as a total hack, just return true
// in 32-bit. This could of course be wrong the other way for cards that only
// support 32-bit addressing in 64-bit processes, but I expect those cards do not
// support unified addressing at all.
// TODO: figure out a way to validate pointers in all cases if strictly necessary.
#ifdef BITS_32
    return true;
#else
    if (buf->dev == 0)
        return true;

    CUdeviceptr dev_ptr = (CUdeviceptr)halide_get_device_handle(buf->dev);

    CUcontext ctx;
    CUresult result = cuPointerGetAttribute(&ctx, CU_POINTER_ATTRIBUTE_CONTEXT, dev_ptr);
    if (result) {
        error(user_context) << "Bad device pointer " << (void *)dev_ptr
                            << ": cuPointerGetAttribute returned "
                            << get_error_name(result);
        return false;
    }
    return true;
#endif
}

}}}} // namespace Halide::Runtime::Internal

extern "C" {
WEAK int halide_cuda_initialize_kernels(void *user_context, void **state_ptr, const char* ptx_src, int size) {
    debug(user_context) << "CUDA: halide_cuda_initialize_kernels (user_context: " << user_context
                        << ", state_ptr: " << state_ptr
                        << ", ptx_src: " << (void *)ptx_src
                        << ", size: " << size << "\n";

    Context ctx(user_context);
    if (ctx.error != 0) {
        return ctx.error;
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_before = halide_current_time_ns(user_context);
    #endif

    // Create the state object if necessary. This only happens once, regardless
    // of how many times halide_initialize_kernels/halide_release is called.
    // halide_release traverses this list and releases the module objects, but
    // it does not modify the list nodes created/inserted here.
    module_state **state = (module_state**)state_ptr;
    if (!(*state)) {
        *state = (module_state*)malloc(sizeof(module_state));
        (*state)->module = NULL;
        (*state)->next = state_list;
        state_list = *state;
    }

    // Create the module itself if necessary.
    if (!(*state)->module) {
        debug(user_context) <<  "    cuModuleLoadData " << (void *)ptx_src << ", " << size << " -> ";
        CUresult err = cuModuleLoadData(&(*state)->module, ptx_src);
        if (err != CUDA_SUCCESS) {
            debug(user_context) << get_error_name(err) << "\n";
            error(user_context) << "CUDA: cuModuleLoadData failed: "
                                << get_error_name(err);
            return err;
        } else {
            debug(user_context) << (void *)((*state)->module) << "\n";
        }
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_after = halide_current_time_ns(user_context);
    debug(user_context) << "    Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
    #endif

    return 0;
}

WEAK int halide_cuda_device_free(void *user_context, buffer_t* buf) {
    // halide_device_free, at present, can be exposed to clients and they
    // should be allowed to call halide_device_free on any buffer_t
    // including ones that have never been used with a GPU.
    if (buf->dev == 0) {
        return 0;
    }

    CUdeviceptr dev_ptr = (CUdeviceptr)halide_get_device_handle(buf->dev);

    debug(user_context)
        <<  "CUDA: halide_cuda_device_free (user_context: " << user_context
        << ", buf: " << buf << ")\n";

    Context ctx(user_context);
    if (ctx.error != CUDA_SUCCESS)
        return ctx.error;

    #ifdef DEBUG_RUNTIME
    uint64_t t_before = halide_current_time_ns(user_context);
    #endif

    halide_assert(user_context, validate_device_pointer(user_context, buf));

    debug(user_context) <<  "    cuMemFree " << (void *)(dev_ptr) << "\n";
    CUresult err = cuMemFree(dev_ptr);
    // If cuMemFree fails, it isn't likely to succeed later, so just drop
    // the reference.
    halide_delete_device_wrapper(buf->dev);
    buf->dev = 0;
    if (err != CUDA_SUCCESS) {
        error(user_context) << "CUDA: cuMemFree failed: "
                            << get_error_name(err);
        return err;
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_after = halide_current_time_ns(user_context);
    debug(user_context) << "    Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
    #endif

    return 0;
}

WEAK int halide_cuda_device_release(void *user_context) {
    debug(user_context)
        << "CUDA: halide_cuda_device_release (user_context: " <<  user_context << ")\n";

    int err;
    CUcontext ctx;
    err = halide_cuda_acquire_context(user_context, &ctx, false);
    if (err != CUDA_SUCCESS) {
        return err;
    }

    if (ctx) {
        // It's possible that this is being called from the destructor of
        // a static variable, in which case the driver may already be
        // shutting down.
        err = cuCtxSynchronize();
        halide_assert(user_context, err == CUDA_SUCCESS || err == CUDA_ERROR_DEINITIALIZED);

        // Unload the modules attached to this context. Note that the list
        // nodes themselves are not freed, only the module objects are
        // released. Subsequent calls to halide_init_kernels might re-create
        // the program object using the same list node to store the module
        // object.
        module_state *state = state_list;
        while (state) {
            if (state->module) {
                debug(user_context) << "    cuModuleUnload " << state->module << "\n";
                err = cuModuleUnload(state->module);
                halide_assert(user_context, err == CUDA_SUCCESS || err == CUDA_ERROR_DEINITIALIZED);
                state->module = 0;
            }
            state = state->next;
        }

        // Only destroy the context if we own it
        if (ctx == context) {
            debug(user_context) << "    cuCtxDestroy " << context << "\n";
            err = cuCtxDestroy(context);
            halide_assert(user_context, err == CUDA_SUCCESS || err == CUDA_ERROR_DEINITIALIZED);
            context = NULL;
        }
    }

    halide_cuda_release_context(user_context);

    return 0;
}

WEAK int halide_cuda_device_malloc(void *user_context, buffer_t *buf) {
    debug(user_context)
        << "CUDA: halide_cuda_device_malloc (user_context: " << user_context
        << ", buf: " << buf << ")\n";

    Context ctx(user_context);
    if (ctx.error != CUDA_SUCCESS) {
        return ctx.error;
    }

    size_t size = buf_size(user_context, buf);
    if (buf->dev) {
        // This buffer already has a device allocation
        halide_assert(user_context, validate_device_pointer(user_context, buf, size));
        return 0;
    }

    halide_assert(user_context, buf->stride[0] >= 0 && buf->stride[1] >= 0 &&
                                buf->stride[2] >= 0 && buf->stride[3] >= 0);

    debug(user_context) << "    allocating buffer of " << (uint64_t)size << " bytes, "
                        << "extents: "
                        << buf->extent[0] << "x"
                        << buf->extent[1] << "x"
                        << buf->extent[2] << "x"
                        << buf->extent[3] << " "
                        << "strides: "
                        << buf->stride[0] << "x"
                        << buf->stride[1] << "x"
                        << buf->stride[2] << "x"
                        << buf->stride[3] << " "
                        << "(" << buf->elem_size << " bytes per element)\n";

    #ifdef DEBUG_RUNTIME
    uint64_t t_before = halide_current_time_ns(user_context);
    #endif

    CUdeviceptr p;
    debug(user_context) << "    cuMemAlloc " << (uint64_t)size << " -> ";
    CUresult err = cuMemAlloc(&p, size);
    if (err != CUDA_SUCCESS) {
        debug(user_context) << get_error_name(err) << "\n";
        error(user_context) << "CUDA: cuMemAlloc failed: "
                            << get_error_name(err);
        return err;
    } else {
        debug(user_context) << (void *)p << "\n";
    }
    halide_assert(user_context, p);
    buf->dev = halide_new_device_wrapper((uint64_t)p, &cuda_device_interface);
    if (buf->dev == 0) {
        error(user_context) << "CUDA: out of memory allocating device wrapper.\n";
        cuMemFree(p);
        return -1;
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_after = halide_current_time_ns(user_context);
    debug(user_context) << "    Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
    #endif

    return 0;
}

WEAK int halide_cuda_copy_to_device(void *user_context, buffer_t* buf) {
    debug(user_context)
        <<  "CUDA: halide_cuda_copy_to_device (user_context: " << user_context
        << ", buf: " << buf << ")\n";

    Context ctx(user_context);
    if (ctx.error != CUDA_SUCCESS) {
        return ctx.error;
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_before = halide_current_time_ns(user_context);
    #endif

    halide_assert(user_context, buf->host && buf->dev);
    halide_assert(user_context, validate_device_pointer(user_context, buf));

    device_copy c = make_host_to_device_copy(buf);

    for (int w = 0; w < c.extent[3]; w++) {
        for (int z = 0; z < c.extent[2]; z++) {
            for (int y = 0; y < c.extent[1]; y++) {
                for (int x = 0; x < c.extent[0]; x++) {
                    uint64_t off = (x * c.stride_bytes[0] +
                                    y * c.stride_bytes[1] +
                                    z * c.stride_bytes[2] +
                                    w * c.stride_bytes[3]);
                    void *src = (void *)(c.src + off);
                    CUdeviceptr dst = (CUdeviceptr)(c.dst + off);
                    uint64_t size = c.chunk_size;
                    debug(user_context) << "    cuMemcpyHtoD "
                                        << "(" << x << ", " << y << ", " << z << ", " << w << "), "
                                        << src << " -> " << (void *)dst << ", " << size << " bytes\n";
                    CUresult err = cuMemcpyHtoD(dst, src, size);
                    if (err != CUDA_SUCCESS) {
                        error(user_context) << "CUDA: cuMemcpyHtoD failed: "
                                            << get_error_name(err);
                        return err;
                    }
                }
            }
        }
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_after = halide_current_time_ns(user_context);
    debug(user_context) << "    Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
    #endif

    return 0;
}

WEAK int halide_cuda_copy_to_host(void *user_context, buffer_t* buf) {
    debug(user_context)
        << "CUDA: halide_cuda_copy_to_host (user_context: " << user_context
        << ", buf: " << buf << ")\n";

    Context ctx(user_context);
    if (ctx.error != CUDA_SUCCESS) {
        return ctx.error;
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_before = halide_current_time_ns(user_context);
    #endif

    halide_assert(user_context, buf->dev && buf->dev);
    halide_assert(user_context, validate_device_pointer(user_context, buf));

    device_copy c = make_device_to_host_copy(buf);

    for (int w = 0; w < c.extent[3]; w++) {
        for (int z = 0; z < c.extent[2]; z++) {
            for (int y = 0; y < c.extent[1]; y++) {
                for (int x = 0; x < c.extent[0]; x++) {
                    uint64_t off = (x * c.stride_bytes[0] +
                                    y * c.stride_bytes[1] +
                                    z * c.stride_bytes[2] +
                                    w * c.stride_bytes[3]);
                    CUdeviceptr src = (CUdeviceptr)(c.src + off);
                    void *dst = (void *)(c.dst + off);
                    uint64_t size = c.chunk_size;

                    debug(user_context) << "    cuMemcpyDtoH "
                                        << "(" << x << ", " << y << ", " << z << ", " << w << "), "
                                        << (void *)src << " -> " << dst << ", " << size << " bytes\n";

                    CUresult err = cuMemcpyDtoH(dst, src, size);
                    if (err != CUDA_SUCCESS) {
                        error(user_context) << "CUDA: cuMemcpyDtoH failed: "
                                            << get_error_name(err);
                        return err;
                    }
                }
            }
        }
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_after = halide_current_time_ns(user_context);
    debug(user_context) << "    Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
    #endif

    return 0;
}

// Used to generate correct timings when tracing
WEAK int halide_cuda_device_sync(void *user_context, struct buffer_t *) {
    debug(user_context)
        << "CUDA: halide_cuda_device_sync (user_context: " << user_context << ")\n";

    Context ctx(user_context);
    if (ctx.error != CUDA_SUCCESS) {
        return ctx.error;
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_before = halide_current_time_ns(user_context);
    #endif

    CUresult err = cuCtxSynchronize();
    if (err != CUDA_SUCCESS) {
        error(user_context) << "CUDA: cuCtxSynchronize failed: "
                            << get_error_name(err);
        return err;
    }

    #ifdef DEBUG_RUNTIME
    uint64_t t_after = halide_current_time_ns(user_context);
    debug(user_context) << "    Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
    #endif

    return 0;
}

WEAK int halide_cuda_run(void *user_context,
                         void *state_ptr,
                         const char* entry_name,
                         int blocksX, int blocksY, int blocksZ,
                         int threadsX, int threadsY, int threadsZ,
                         int shared_mem_bytes,
                         size_t arg_sizes[],
                         void* args[],
                         int8_t arg_is_buffer[],
                         int num_attributes,
                         float* vertex_buffer,
                         int num_coords_dim0,
                         int num_coords_dim1) {

    debug(user_context) << "CUDA: halide_cuda_run ("
                        << "user_context: " << user_context << ", "
                        << "entry: " << entry_name << ", "
                        << "blocks: " << blocksX << "x" << blocksY << "x" << blocksZ << ", "
                        << "threads: " << threadsX << "x" << threadsY << "x" << threadsZ << ", "
                        << "shmem: " << shared_mem_bytes << "\n";

    CUresult err;
    Context ctx(user_context);
    if (ctx.error != CUDA_SUCCESS) {
        return ctx.error;
    }

    debug(user_context) << "Got context.\n";

    #ifdef DEBUG_RUNTIME
    uint64_t t_before = halide_current_time_ns(user_context);
    #endif

    halide_assert(user_context, state_ptr);
    CUmodule mod = ((module_state*)state_ptr)->module;
    debug(user_context) << "Got module " << mod << "\n";
    halide_assert(user_context, mod);
    CUfunction f;
    err = cuModuleGetFunction(&f, mod, entry_name);
    debug(user_context) << "Got function " << f << "\n";
    if (err != CUDA_SUCCESS) {
        error(user_context) << "CUDA: cuModuleGetFunction failed: "
                            << get_error_name(err);
        return err;
    }

    size_t num_args = 0;
    while (arg_sizes[num_args] != 0) {
        debug(user_context) << "    halide_cuda_run " << (int)num_args
                            << " " << (int)arg_sizes[num_args]
                            << " [" << (*((void **)args[num_args])) << " ...] "
                            << arg_is_buffer[num_args] << "\n";
        num_args++;
    }

    // We need storage for both the arg and the pointer to it if if
    // has to be translated.
    void** translated_args = (void **)malloc((num_args + 1) * sizeof(void *));
    uint64_t *dev_handles = (uint64_t *)malloc(num_args * sizeof(uint64_t));
    for (size_t i = 0; i <= num_args; i++) { // Get NULL at end.
        if (arg_is_buffer[i]) {
            halide_assert(user_context, arg_sizes[i] == sizeof(uint64_t));
            dev_handles[i] = halide_get_device_handle(*(uint64_t *)args[i]);
            translated_args[i] = &(dev_handles[i]);
            debug(user_context) << "    halide_cuda_run translated arg" << (int)i
                                << " [" << (*((void **)translated_args[i])) << " ...]\n";
        } else {
            translated_args[i] = args[i];
        }
    }

    err = cuLaunchKernel(f,
                         blocksX,  blocksY,  blocksZ,
                         threadsX, threadsY, threadsZ,
                         shared_mem_bytes,
                         NULL, // stream
                         translated_args,
                         NULL);
    free(dev_handles);
    free(translated_args);
    if (err != CUDA_SUCCESS) {
        error(user_context) << "CUDA: cuLaunchKernel failed: "
                            << get_error_name(err);
        return err;
    }

    #ifdef DEBUG_RUNTIME
    err = cuCtxSynchronize();
    if (err != CUDA_SUCCESS) {
        error(user_context) << "CUDA: cuCtxSynchronize failed: "
                            << get_error_name(err);
        return err;
    }
    uint64_t t_after = halide_current_time_ns(user_context);
    debug(user_context) << "    Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
    #endif
    return 0;
}

WEAK int halide_cuda_wrap_device_ptr(void *user_context, struct buffer_t *buf, uintptr_t device_ptr) {
    halide_assert(user_context, buf->dev == 0);
    if (buf->dev != 0) {
        return -2;
    }
    buf->dev = halide_new_device_wrapper(device_ptr, &cuda_device_interface);
    if (buf->dev == 0) {
        return -1;
    }
#if DEBUG_RUNTIME
    if (!validate_device_pointer(user_context, buf)) {
        halide_delete_device_wrapper(buf->dev);
        buf->dev = 0;
        return -3;
    }
#endif
    return 0;
}

WEAK uintptr_t halide_cuda_detach_device_ptr(void *user_context, struct buffer_t *buf) {
    if (buf->dev == NULL) {
        return 0;
    }
    halide_assert(user_context, halide_get_device_interface(buf->dev) == &cuda_device_interface);
    uint64_t dev_ptr = halide_get_device_handle(buf->dev);
    halide_delete_device_wrapper(buf->dev);
    buf->dev = 0;
    return (uintptr_t)dev_ptr;
}

WEAK uintptr_t halide_cuda_get_device_ptr(void *user_context, struct buffer_t *buf) {
    if (buf->dev == NULL) {
        return 0;
    }
    halide_assert(user_context, halide_get_device_interface(buf->dev) == &cuda_device_interface);
    uint64_t dev_ptr = halide_get_device_handle(buf->dev);
    return (uintptr_t)dev_ptr;
}

WEAK const halide_device_interface *halide_cuda_device_interface() {
    return &cuda_device_interface;
}

namespace {
__attribute__((destructor))
WEAK void halide_cuda_cleanup() {
    halide_cuda_device_release(NULL);
}
}

} // extern "C" linkage

namespace Halide { namespace Runtime { namespace Internal { namespace Cuda {

WEAK const char *get_error_name(CUresult error) {
    switch(error) {
    case CUDA_SUCCESS: return "CUDA_SUCCESS";
    case CUDA_ERROR_INVALID_VALUE: return "CUDA_ERROR_INVALID_VALUE";
    case CUDA_ERROR_OUT_OF_MEMORY: return "CUDA_ERROR_OUT_OF_MEMORY";
    case CUDA_ERROR_NOT_INITIALIZED: return "CUDA_ERROR_NOT_INITIALIZED";
    case CUDA_ERROR_NO_DEVICE: return "CUDA_ERROR_NO_DEVICE";
    case CUDA_ERROR_INVALID_DEVICE: return "CUDA_ERROR_INVALID_DEVICE";
    case CUDA_ERROR_INVALID_IMAGE: return "CUDA_ERROR_INVALID_IMAGE";
    case CUDA_ERROR_INVALID_CONTEXT: return "CUDA_ERROR_INVALID_CONTEXT";
    case CUDA_ERROR_CONTEXT_ALREADY_CURRENT: return "CUDA_ERROR_CONTEXT_ALREADY_CURRENT";
    case CUDA_ERROR_MAP_FAILED: return "CUDA_ERROR_MAP_FAILED";
    case CUDA_ERROR_UNMAP_FAILED: return "CUDA_ERROR_UNMAP_FAILED";
    case CUDA_ERROR_ARRAY_IS_MAPPED: return "CUDA_ERROR_ARRAY_IS_MAPPED";
    case CUDA_ERROR_ALREADY_MAPPED: return "CUDA_ERROR_ALREADY_MAPPED";
    case CUDA_ERROR_NO_BINARY_FOR_GPU: return "CUDA_ERROR_NO_BINARY_FOR_GPU";
    case CUDA_ERROR_ALREADY_ACQUIRED: return "CUDA_ERROR_ALREADY_ACQUIRED";
    case CUDA_ERROR_NOT_MAPPED: return "CUDA_ERROR_NOT_MAPPED";
    case CUDA_ERROR_INVALID_SOURCE: return "CUDA_ERROR_INVALID_SOURCE";
    case CUDA_ERROR_FILE_NOT_FOUND: return "CUDA_ERROR_FILE_NOT_FOUND";
    case CUDA_ERROR_INVALID_HANDLE: return "CUDA_ERROR_INVALID_HANDLE";
    case CUDA_ERROR_NOT_FOUND: return "CUDA_ERROR_NOT_FOUND";
    case CUDA_ERROR_NOT_READY: return "CUDA_ERROR_NOT_READY";
    case CUDA_ERROR_LAUNCH_FAILED: return "CUDA_ERROR_LAUNCH_FAILED";
    case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES: return "CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES";
    case CUDA_ERROR_LAUNCH_TIMEOUT: return "CUDA_ERROR_LAUNCH_TIMEOUT";
    case CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING: return "CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING";
    case CUDA_ERROR_UNKNOWN: return "CUDA_ERROR_UNKNOWN";
    default: return "<Unknown error>";
    }
}

WEAK halide_device_interface cuda_device_interface = {
    halide_use_jit_module,
    halide_release_jit_module,
    halide_cuda_device_malloc,
    halide_cuda_device_free,
    halide_cuda_device_sync,
    halide_cuda_device_release,
    halide_cuda_copy_to_host,
    halide_cuda_copy_to_device,
};

}}}} // namespace Halide::Runtime::Internal::Cuda


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <title>Jak zacząć przygodę z elektroniką</title>
    <meta name="description" content="A place where I share my thoughts about programming." />

    <meta name="HandheldFriendly" content="True" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="shortcut icon" href="/assets/images/favicon.ico" >

    <link rel="stylesheet" type="text/css" href="/assets/css/screen.css" />
    <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400" />
    <link rel="stylesheet" type="text/css" href="/assets/css/syntax.css" />

    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.3.0/styles/default.min.css">

        <link rel="canonical" href="http://blog.marcinchwedczuk.pl//jak-zaczac-przygode-z-elektronika" />
    <meta name="referrer" content="origin" />
    <link rel="next" href="/page2/" />

    <meta property="og:site_name" content="Programming is Magic" />
    <meta property="og:type" content="website" />
    <meta property="og:title" content="Jak zacząć przygodę z elektroniką" />
    <meta property="og:description" content="A place where I share my thoughts about programming." />
    <meta property="og:url" content="http://blog.marcinchwedczuk.pl//jak-zaczac-przygode-z-elektronika" />
    <meta property="og:image" content="/assets/images/mc_cover2.jpg" />

    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content="Jak zacząć przygodę z elektroniką" />
    <meta name="twitter:description" content="A place where I share my thoughts about programming." />
    <meta name="twitter:url" content="http://blog.marcinchwedczuk.pl//jak-zaczac-przygode-z-elektronika" />
    <meta name="twitter:image:src" content="/assets/images/mc_cover2.jpg" />

    <meta name="generator" content="Jekyll 3.0.0" />
    <link rel="alternate" type="application/rss+xml" title="Programming is Magic" href="/feed.xml" />

Menu

        Close

Home

                    java (29)

                    dotnet (11)

                    algorithms (7)

                    architecture (7)

                    scala (7)

                    javascript (5)

                    polish (5)

                    csharp (4)

                    elektronika (4)

                    hibernate (3)

                    linux (3)

                    unit-testing (3)

                    hardware-review (2)

                    cheatsheet (1)

                    ctf (1)

                    devcon (1)

                    eclipse (1)

                    electronics (1)

                    functional-programming (1)

                    git (1)

                    hacking (1)

                    hardware (1)

                    kotlin (1)

                    low-level (1)

                    other (1)

                    postman (1)

                    powershell (1)

                    regex (1)

                    security (1)

                    sql (1)

                    ssh (1)

                    tips (1)

                    vim (1)

                    windows (1)

    Subscribe

            Menu

Jak zacząć przygodę z elektroniką

                    Marcin Chwedczuk

            <time class="post-date" datetime="2019-12-30">30 Dec 2019</time>

                on

                       Polish,

                       Elektronika

Parę miesięcy temu postanowiłem powrócić do mojego
hobby z czasów dzieciństwa: elektroniki.
Powrót, po ponad dziesięciu latach przerwy, okazał
się być trudniejszy niż przypuszczałem,
a droga do pierwszego działającego układu
pełna frustracji i porażek.

Pomimo tego radość z wykonania najprostszego generatora,
który naprzemiennie migał diodami LED dostarczyła
mi tak dużo radości i frajdy, że przez kilka następnych
wieczorów oddałem się w całości budowie kolejnych układów.

Niestety elektronika jako hobby, nie jest
już w Polsce tak popularna jak
miało to miejsce w końcówce lat dziewięćdziesiątych.
A szkoda, bo na zachodzie mamy obecnie do czynienia
z prawdziwym boomem na elektronikę.
Dobrze ilustrują to platformy takie jak
Arduino czy
Raspberry PI.
Nie wspominając już o modzie na retro-computing
(a więc na budowę prostych, często 8-bitowych komputerów wprost
z układów scalonych) uosabianej przez takie postaci
jak Ben Eater
i projekty jak The MOnSter 6502 i
Gigatron

Niestety nauka nowej umiejętności czy jest nią jazda samochodem,
czy język obcy czy też elektronika, nie jest prosta.
Na początkujących czyha wiele pułapek, które zniechęcają ich
do dalszej nauki. Dlatego, aby ułatwić początkującym wejście w
świat elektronik, postawiłem podzielić się moimi doświadczeniami
(czytaj wpadkami)
i opisać problemy na jakie się natknąłem.
To jest pierwszy wpis z tej serii, w którym opisuję
pułapki które czekają nas przy zakupie pierwszych płytek
stykowych, przewodów i elementów elektronicznych. Zapraszam!

Płytka stykowa

Według mnie najlepszym sposobem montażu układów, na początku
przygody z elektroniką są płytki stykowe.
Na rysunku poniżej przedstawiam przykład dwóch takich płytek:

Płytka oznaczona numerem 1, to przykład płytki droższej
która mimo to posiada kilka poważnych mankamentów.
Po pierwsze brakuje oznaczenia polaryzacji szyn zasilania,
co rodzi pole do przykrych w konsekwencjach pomyłek
(np. nieprawidłowe doprowadzenie zasilania do układu scalonego).
Po drugie szyny zasilania są "przecięte" w połowie płytki
(patrz strzałki). Tego typu "przecięcie" przydaje
się gdy budujemy układy w których występują dwa poziomy
zasilania np. 3.3V i 5V. Większość początkujących
elektroników korzysta jednak z pojedynczego napięcia zasilania.
W praktyce okazywało się to tak denerwujące że musiałem dodać specjalne
oznaczenia markerem, żeby już więcej się nie zastanawiać dlaczego
połowa układu nie ma napięcia zasilania.

Płytka oznaczona numerem 2 to tania płytka (7 PLN za sztukę),
produkcji chińskiej. Mimo to producent
nie oszczędzał na pomocnych oznaczeniach.
Każda z czterech linii zasilania
ma swój kolor, każde gniazdo jest adresowane
za pomocą kombinacji litery (a-j) i liczby (1-65).
Może, na pierwszy rzut oka nie wydaje się to
przydatne, ale w internecie można znaleźć mnóstwo
projektów pomyślanych specjalnie do wykonania
na płytkach stykowych, które zawierają instrukcje
typu: "umieść rezystor 1k w gniazdach 5f i 5c".

Niestety niska cena płytki nr. 2 znalazła negatywne
odbicie w jakości styków. Korzystanie z tej płytki
rodziło sporo kłopotów: często miałem problemy żeby
włożyć końcówkę przewodu lub nóżkę elementu do danego
gniazda. Czasami pomagało wetknięcie szpilki, czasami
włożenie przewodów najpierw do sąsiadujących gniazd
a dopiero potem przeniesienie ich do tego właściwego.
Czasami pomagało "wiercenie" w gnieździe nóżką diody LED.
Innymi słowy, spora część radości wynikającej z budowania układu
ustępowała miejsca frustracji związanej z niskiej jakości płytką.

Przed zakupem płytek polecam przeczytać
recenzje, zarówno na polski forach jak i na zagranicznych (oraz
na Amazonie). Osobiście, nie znalazłem jak do tej pory
płytki stykowej godnej polecenia, jeżeli taką znacie to
proszę dodajcie komentarz z linkiem.

Wróćmy jeszcze na chwilę do zdjęcia płytek.
Część oznaczona numerem cztery to pojedyncza szyna zasilania,
odseparowana od płytki stykowej typu dwa.
Jak się okazuje od każdej płytki możemy oderwać jedną lub
obie szyny zasilania. Przy wykonywaniu tej operacji
przydaje się nożyk do kartonu, który pozwoli nam
rozciąć izolacyjny materiał znajdujący się na spodzie płytki.

Każda płytka stykowa posiada wypustki, które pozwalają
zbudować "megapłytkę" z dwóch lub większej liczby
pojedynczych płytek (z obecnymi lub oderwanymi szynami zasilania).
Niestety płytki wyprodukowane przez różne firmy rzadko
są ze sobą kompatybilne.
Poniżej zamiejszczam zdjęcie takiej "megapłytki":

Oprócz pełonowymiarowych płytek, na ryku dostępne są też
mniejsze modele:

Osobiście nie polecam ich początkującym, gdyż są
po prostu za małe.

Wydawało by się że orientacja płytki nie ma żadnego znaczenia.
Warto jednak przy budowie układów podążać za sprawdzoną regułą,
która mówi że prądy powinny płynąć z góry na dół, a sygnały
od lewej do prawej. W praktyce oznacza to że górna wewnętrzna
szyna zasilająca powinna być podłączona do plusa zasilania,
a dolna wewnętrzna do minusa. Przestrzeganie tej
zasady znacznie ułatwi nam doprowadzanie zasilania do układów scalonych.

A skoro już jesteśmy przy układach scalonych, większość
z nich nie posiada prostopadłych nóżek. Zamiast tego
nóżki rozchodzą się nieco na boki, co uniemożliwia umieszczenie
takiego układu w płytce stykowej. Rozwiązaniem tego
problemu jest przygięcie nóżek scalaka przed włożeniem go
do płytki:

Zanim opuścimy temat płytek warto jeszcze dodać, że
na opakowaniu płytki znajduje się jeden z najważniejszych
jej parametrów, mianowicie zakres grubości drutów/końcówek/wyprowadzeń
z jakimi płytka współpracuje. Ten parametr okaże się istotny
gdy będziemy planować zakup przewodów kompatybilnych
z płytką (czytaj nie każdy przewód pasuje do danej płytki).

Przewody / połączenia / zworki

Oprócz płytki stykowej, przy budowie układów będziemy
też potrzebowali całej masy przewodów.
Osobiście polecam zakup zestawu przewodów
takich jak Adafruit Hook-up Wire,
wraz ze szczypcami do ściągania izolacji takimi
jak Adafruit Wire Stripper:

Przy zakupie warto zwracać uwagę czy na pewno kupujemy
jednożyłowy, cynowany przewód miedziany, a nie na przykład
wielożyłowy (czysta miedź pokrywa się
nieprzewodzącą warstwą tlenków, cynowany drut zapewni
nam znacznie lepszą jakość połączeń).

Przedstawiony powyżej zestaw przewodów ma grubość
drutu AWG 22 (miara amerykańska), co przelicza się
na polskie 0.6438 milimetra średnicy.
Płytki stykowe z pierwszej sekcji, pracują poprawnie z przewodami
o grubościach 0.3-0.8 milimetra, a więc są kompatybilne z tym
zestawem przewodów.

Ze względu na rosnące ceny miedzi zakup zestawów takich
jak te przedstawione powyżej, może wiązać się ze sporym wydatkiem.
Należy jednak pamiętać że
jeden zestaw przewodów powinien zaspokoić nasze potrzeby na mniej więcej rok,
a szczypce to wydatek jednorazowy.
Obecna cena powyższego zestawu przewodów w sklepie Mouser
wynosi około 120PLN. Oczywiście zawsze warto sprawdzić czy
nie znajdziemy lepszej oferty w polskich sklepach, na ceneo czy
w końcu na AliExpressie.

Oprócz zestawu przewodów, w sklepach można znaleźć również zestawy zworek
(numer jeden na zdjęciu):

Zestawy takie są, w stosunku do ich ceny, kompletnie bezużyteczne.
Zwory prawie nigdy nie miały potrzebnej długości gdy chciałem
ich użyć. Krótkie zworki kończyły się bardzo szybko, podczas
gdy długich zostawał nadmiar. Jednym słowem: nie polecam.

Polecam za to zakup elastycznych przewodów połączeniowych
(numer dwa i trzy na zdjęciu).
Przewody typu trzy dostępne są w zestawach o dość przystępnej
cenie. Przewody typu dwa występują we wstęgach, które można
rozrywać (nawet na pojedyncze przewody) wedle upodobań.

Do zabawy z płytkami stykowymi i Arduino potrzebne nam będą przede
wszystkim przewody z wtykami męskimi (patrz numer trzy).
Do zabawy z Rasbperry PI,
a także z modułami do Arduino (np. czujniki ruchu) przydadzą się
przewody męsko-żeńskie (patrz numer dwa).

Czasami zdarza się, że przewody będące częścią zestawów mają
końcówki wtyków pokryte ochronną warstwą plastiku którą łatwo
przeoczyć. Jeżeli przewód "źle łączy" należy sprawdzić czy
końcówki nie posiadają takiej ochronnej izolacji i ewentualnie
ją usunąć.

Warto zarezerwować sobie dwa kolory (np. czarny i czerwony)
na oznaczenie przewodów które mają potencjał masy i plusa zasilania.
Warto też pomyśleć o konwencji użycia kolorów, na przykład: przewód biały to
zawsze sygnał zegara.
Poza tym im więcej kolorów mamy do dyspozycji tym lepiej.

Pozostałe narzędzia

Pozostałe przydatne narzędzia to:

Mały płaski śrubokręt

Szczypce tnące boczne
 do ucinania zbyt długich wyprowadzeń elementów
 (model ze zdjęcia)

Oraz najbardziej przydatna z całej tej
 trójki, bo pozwalająca wygodnie wyjmować i wkładać przewody
 połączeniowe - pęseta
 (model ze zdjęcia)

Przycinanie wyprowadzeń elementów za pomocą
szczypiec może być odrobinę niebezpieczne.
Nóżki, na przykład dużych diod LED, podczas przycinania mają tendencje to
"wystrzeliwania" w znanym tylko sobie kierunku, dlatego
warto też pomyśleć o zakupie
okularów ochronnych.

Ostatnim, naprawdę niezbędnym narzędziem, w jaki
powinniśmy się zaopatrzyć jest multimetr.
Ja używam następującego modelu, mało znanej chińskiej
marki i jestem z niego całkowicie zadowolony:

Elementy elektroniczne

Można by pomyśleć, że po całym tym zamieszaniu z płytkami,
narzędziami i multimetrem zakup elementów elektronicznych
będzie czystą przyjemnością.
Nic bardziej mylnego!
Pierwszym zaskoczeniem jakie mnie spotkało, była niewielka
średnica wyprowadzeń resystorów zakupionych w zestawie
"dla początkujących". Średnica była tak mała, że czasami
trudno było uzyskać dobre połączenie z płytką stykową.
Ostatecznie skończyłem z tym zestawem rezystorów

Dobrze ilustruje to powyższe zdjęcie, rezystor oznaczony
numerem jeden pochodzi z taniego zestawu "dla początkujących".
Posiada długie i cienkie wyprowadzenia słabo współpracujące z
płytkami stykowymi. Rezystor oznaczony numerem dwa pochodzi
z zestawu velleman'a - wyraźnie widać krótsze, ale za to
grubsze i bardziej masywne wyprowadzenia.

Osobiście odradzam również zakup rezystorów o mocy większej
niż 0,25W. Rezystory 1W w porównaniu do 0,25W to prawdziwe olbrzymy.

W przeciwieństwie do rezystorów, zakup diod LED
(polecam "duże" 5mm) czy kondensatorów nie sprawiał
większych problemów, elementy po prostu działały.

Z kolei zakup przycisków ("switchy") i potencjometrów
sprawił mi trochę kłopotów. Okazuje się że wiele elementów
występuje w dwóch wersjach: do wlutowania i do płytek stykowych.
Popatrzmy na zdjęcie:

Elementy z grupy pierwszej są przeznaczone do wlutowania.
Elementy z grupy drugiej, charakteryzującej się prostymi
wyprowadzeniami, są przewidziane do umieszczenia na płytkach
stykowych. Zawsze należy dokładnie sprawdzić czy na pewno
kupujemy takie elementy, jakich naprawdę potrzebujemy.

Na koniec, żeby nie tracić czasu na mozolne odnajdywanie potrzebnych
elementów, warto zaopatrzyć się w dobry organizer:

Zasilanie

Początkowo zasilałem moje układy z baterii 9V.
Wykorzystywałem do tego celu kijankę (numer jeden),
gniazdo które można włożyć w szynę zasilania płytki stykowej (numer trzy) oraz
konwerter (numer dwa):

Konwerter okazał się konieczny, ponieważ zakupu
gniazda dokonałem "na oko", nie będąc świadom że
istnieje wiele różnych rozmiarów wtyków zasilania.

Osobiście nie polecam tego sposobu zasilania.
Po pierwsze jesteśmy zdani na napięcie baterii, a wiele
układów wymaga niestandardowych napięć 3,3V lub 5V.
Po drugie zaśmiecamy środowisko zużytymi bateriami,
przy jednoczesnym zubożaniu naszego portfela.

Najlepszym rozwiązaniem, dla osób dysponujących zapasem
gotówki jest kupno zasilacza laboratoryjnego,
nazywanego również zasilaczem warsztatowym.
Dla wszystkich pozostałych, przynajmniej na początku,
dobrym kompromisem jest zakup
zasilacza płytek stykowych:

Należy pamiętać że sam zasilacz to tylko prosta płytka PCB
(ang. printed circuit board, pl. płytka drukowana), do
pracy potrzebny jej jest zasilacz impulsowy - oznaczony na zdjęciu numerem dwa.

Przedstawiony powyżej zasilacz, który służy mi już kilka miesięcy,
niestety nie jest pozbawiony wad.
Najpoważniejsza z nich jest taka, że nie jesteśmy ostrzegani
o zwarciu przewodów zasilania.
Istnieją na rynku zasilacze które np. piszczą
gdy dojdzie do zwarcia.
W powyższym zasilaczu, zwarcie można rozpoznać jedynie po
silnie rozgrzanym radiatorze.
Dlatego, pomimo że podałem linki do sklepu, zachęcam was do
poszukania lepszego modelu lub jeżeli już taki
posiadacie do pozostawienia komentarza z linkiem.

Sklepy

Na koniec lista sklepów z których jestem
względnie zadowolony:

Sklep AVT związany od wielu lat
 z czasopismem "Elektronika dla wszystkich"

Botland

Z zagranicznych warto wspomnieć:

Mouser - ten sklep
 śmiało można nazwać profesjonalnym.
 Można łatwo i szybko (czas dostawy nie przekracza tygodnia)
 dostać układy praktycznie niedostępne na polskim rynku.
 Ale uwaga, ceny produktów podane są na modłę amerykańską,
 a więc nie zawierają
 23% podatku VAT. Najeży o tym pamiętać porównując oferty.

Oczywiście zawsze warto korzystać z porównywarek cen
i sprawdzać opinie sklepów na forach internetowych.
Bardziej odważni i cierpliwi mogą spróbować szczęścia na AliExpressie.

Na zakończenie, "starożytne" i niestety niedziałające, układy
scalone polskiej produkcji (sic!), które otrzymałem od jednego
z polskich sklepów:

                            mc's Picture

Marcin Chwedczuk

 A programmer, a geek, a human

                             Warsaw, Poland
                             http://marcinchwedczuk.pl

Share this post

                            Twitter

                            Facebook

                            Google+

        Please enable JavaScript to view the comments powered by Disqus.
        blog comments powered by Disqus

Continuations in Java

CSP or Continuation-Passing Style is a style of programming in which functions return results via...

Pitfalls of using Mockito with Scala

I need to test my new, shiny Scala code. Usually I write tests in ScalaTest,...

Programming is Magic © 2021

Proudly published with Jekyll using Jasper