text:
package net.greghaines.jesque.utils;

import static net.greghaines.jesque.utils.ResqueConstants.COLON;
import static net.greghaines.jesque.utils.ResqueConstants.FREQUENCY;

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;

import net.greghaines.jesque.Job;
import net.greghaines.jesque.worker.UnpermittedJobException;

/**
 * Miscellaneous utilities.
 *
 * @author Greg Haines
 */
public final class JesqueUtils {

    private static final String BT_PREFIX = "\tat ";
    private static final String BT_CAUSED_BY_PREFIX = "Caused by: ";
    private static final String BT_UNKNOWN_SOURCE = "Unknown Source";
    private static final String BT_NATIVE_METHOD = "Native Method";
    private static final Pattern BT_PATTERN = Pattern.compile("[\\(\\):]");
    private static final Pattern COLON_SPACE_PATTERN = Pattern.compile(":\\s");

    /**
     * Join the given strings, separated by the given separator.
     *
     * @param sep
     *            the separator
     * @param strs
     *            the strings to join
     * @return the joined string
     */
    public static String join(final String sep, final String... strs) {
        return join(sep, Arrays.asList(strs));
    }

    /**
     * Join the given strings, separated by the given separator.
     *
     * @param sep
     *            the separator
     * @param strs
     *            the strings to join
     * @return the joined string
     */
    public static String join(final String sep, final Iterable<String> strs) {
        final StringBuilder buf = new StringBuilder();
        String prefix = "";
        for (final String str : strs) {
            buf.append(prefix).append(str);
            prefix = sep;
        }
        return buf.toString();
    }

    /**
     * Builds a namespaced Redis key with the given arguments.
     *
     * @param namespace
     *            the namespace to use
     * @param parts
     *            the key parts to be joined
     * @return an assembled String key
     */
    public static String createKey(final String namespace, final String... parts) {
        return createKey(namespace, Arrays.asList(parts));
    }

    public static String createRecurringHashKey(final String queue) {
        return createKey(queue, FREQUENCY);
    }

    /**
     * Builds a namespaced Redis key with the given arguments.
     *
     * @param namespace
     *            the namespace to use
     * @param parts
     *            the key parts to be joined
     * @return an assembled String key
     */
    public static String createKey(final String namespace, final Iterable<String> parts) {
        final List<String> list = new LinkedList<String>();
        if (!"".equals(namespace)) {
            list.add(namespace);
        }
        for (final String part : parts) {
            list.add(part);
        }
        return join(COLON, list);
    }

    /**
     * Creates a Resque backtrace from a Throwable's stack trace. Includes
     * causes.
     *
     * @param t
     *            the Exception to use
     * @return a list of strings that represent how the exception's stacktrace
     *         appears.
     */
    public static List<String> createBacktrace(final Throwable t) {
        final List<String> bTrace = new LinkedList<String>();
        for (final StackTraceElement ste : t.getStackTrace()) {
            bTrace.add(BT_PREFIX + ste.toString());
        }
        if (t.getCause() != null) {
            addCauseToBacktrace(t.getCause(), bTrace);
        }
        return bTrace;
    }

    /**
     * Add a cause to the backtrace.
     *
     * @param cause
     *            the cause
     * @param bTrace
     *            the backtrace list
     */
    private static void addCauseToBacktrace(final Throwable cause, final List<String> bTrace) {
        if (cause.getMessage() == null) {
            bTrace.add(BT_CAUSED_BY_PREFIX + cause.getClass().getName());
        } else {
            bTrace.add(BT_CAUSED_BY_PREFIX + cause.getClass().getName() + ": " + cause.getMessage());
        }
        for (final StackTraceElement ste : cause.getStackTrace()) {
            bTrace.add(BT_PREFIX + ste.toString());
        }
        if (cause.getCause() != null) {
            addCauseToBacktrace(cause.getCause(), bTrace);
        }
    }

    /**
     * Recreate an exception from a type name, a message and a backtrace
     * (created from JesqueUtils.createBacktrace(Throwable)).
     *

     * Limitations:

     * This method cannot recreate Throwables with unusual/custom Constructors.
     *

     *
If the message is non-null and the cause is null, there must be a
     * Constructor with a single String as it's only parameter.

     *
If the message is non-null and the cause is non-null, there must be a
     * Constructor with a single String as it's only parameter or a Constructor
     * with a String and a Throwable as its parameters.

     *
If the message is null and the cause is null, there must be either a
     * no-arg Constructor or a Constructor with a single String as it's only
     * parameter.

     *
If the message is null and the cause is non-null, there must be
     * either a no-arg Constructor, a Constructor with a single String as its
     * only parameter or a Constructor with a String and a Throwable as its
     * parameters.

     *

     *
     * @param type
     *            the String name of the Throwable type
     * @param message
     *            the message of the exception
     * @param backtrace
     *            the backtrace of the exception
     * @return a new Throwable of the given type with the given message and
     *         given backtrace/causes
     * @throws ParseException
     *             if there is a problem parsing the given backtrace
     * @throws ClassNotFoundException
     *             if the given type is not available
     * @throws NoSuchConstructorException
     *             if there is not a common constructor available for the given
     *             type
     * @throws AmbiguousConstructorException
     *             if there is more than one constructor that is viable
     * @throws InstantiationException
     *             if there is a problem instantiating the given type
     * @throws IllegalAccessException
     *             if the common constructor is not visible
     * @throws InvocationTargetException
     *             if the constructor threw an exception
     * @see JesqueUtils#createBacktrace(Throwable)
     */
    public static Throwable recreateThrowable(final String type, final String message, final List<String> backtrace)
            throws ParseException, ClassNotFoundException, NoSuchConstructorException,
            AmbiguousConstructorException, ReflectiveOperationException {
        final LinkedList<String> bTrace = new LinkedList<String>(backtrace);
        Throwable cause = null;
        StackTraceElement[] stes = null;
        while (!bTrace.isEmpty()) {
            stes = recreateStackTrace(bTrace);
            if (!bTrace.isEmpty()) {
                final String line = bTrace.removeLast().substring(BT_CAUSED_BY_PREFIX.length());
                final String[] classNameAndMsg = COLON_SPACE_PATTERN.split(line, 2);
                final String msg = (classNameAndMsg.length == 2) ? classNameAndMsg[1] : null;
                cause = instantiateThrowable(classNameAndMsg[0], msg, cause, stes);
            }
        }
        return instantiateThrowable(type, message, cause, stes);
    }

    protected static Throwable instantiateThrowable(final String type, final String message, final Throwable cause,
            final StackTraceElement[] stes) throws ClassNotFoundException, AmbiguousConstructorException,
            ReflectiveOperationException, NoSuchConstructorException {
        Throwable throwable = null;
        boolean causeInited = false;
        final Class<?> throwableType = ReflectionUtils.forName(type);
        if (message == null) {
            try {
                try {
                    throwable = (Throwable) ReflectionUtils.createObject(throwableType);
                } catch (NoSuchConstructorException nsce2) {
                    if (cause == null) {
                        throw nsce2;
                    }
                    causeInited = true;
                    throwable = (Throwable) ReflectionUtils.createObject(throwableType, cause);
                }
            } catch (NoSuchConstructorException nsce) {
                try {
                    throwable = (Throwable) ReflectionUtils.createObject(throwableType, (String) null);
                } catch (NoSuchConstructorException nsce3) {
                    if (cause == null) {
                        throw nsce3;
                    }
                    causeInited = true;
                    throwable = (Throwable) ReflectionUtils.createObject(throwableType, (String) null, cause);
                }
            }
        } else {
            try {
                throwable = (Throwable) ReflectionUtils.createObject(throwableType, message);
            } catch (NoSuchConstructorException nsce) {
                if (cause == null) {
                    throw nsce;
                }
                causeInited = true;
                throwable = (Throwable) ReflectionUtils.createObject(throwableType, message, cause);
            }
        }
        throwable.setStackTrace(stes);
        if (!causeInited && cause != null) {
            throwable.initCause(cause);
        }
        return throwable;
    }

    protected static StackTraceElement[] recreateStackTrace(final List<String> bTrace) throws ParseException {
        final List<StackTraceElement> stes = new LinkedList<StackTraceElement>();
        if (bTrace != null) {
            final ListIterator<String> iter = bTrace.listIterator(bTrace.size());
            while (iter.hasPrevious()) {
                final String prev = iter.previous();
                if (prev.startsWith(BT_PREFIX)) { // All stack trace elements start with BT_PREFIX
                    iter.remove();
                    final String[] stParts = BT_PATTERN.split(prev.substring(BT_PREFIX.length()));
                    if (stParts.length < 2 || stParts.length > 3) {
                        throw new ParseException("Malformed stack trace element string: " + prev, 0);
                    }
                    final int periodPos = stParts[0].lastIndexOf('.');
                    final String className = stParts[0].substring(0, periodPos);
                    final String methodName = stParts[0].substring(periodPos + 1);
                    final String fileName;
                    final int lineNumber;
                    if (BT_UNKNOWN_SOURCE.equals(stParts[1])) {
                        fileName = null;
                        lineNumber = -1;
                    } else if (BT_NATIVE_METHOD.equals(stParts[1])) {
                        fileName = null;
                        lineNumber = -2;
                    } else {
                        fileName = stParts[1];
                        lineNumber = (stParts.length == 3) ? Integer.parseInt(stParts[2]) : -1;
                    }
                    stes.add(0, new StackTraceElement(className, methodName, fileName, lineNumber));
                } else { // Stop if it is not a stack trace element
                    break;
                }
            }
        }
        return stes.toArray(new StackTraceElement[stes.size()]);
    }

    /**
     * A convenient way of creating a map on the fly.
     *
     * @param <K> the key type
     * @param <V> the value type
     * @param entries
     *            Map.Entry objects to be added to the map
     * @return a LinkedHashMap with the supplied entries
     */
    @SafeVarargs
    public static <K, V> Map<K, V> map(final Entry<? extends K, ? extends V>... entries) {
        final Map<K, V> map = new LinkedHashMap<K, V>(entries.length);
        for (final Entry<? extends K, ? extends V> entry : entries) {
            map.put(entry.getKey(), entry.getValue());
        }
        return map;
    }

    /**
     * Creates a Map.Entry out of the given key and value. Commonly used in
     * conjunction with map(Entry...)
     *
     * @param <K> the key type
     * @param <V> the value type
     * @param key
     *            the key
     * @param value
     *            the value
     * @return a Map.Entry object with the given key and value
     */
    public static <K, V> Entry<K, V> entry(final K key, final V value) {
        return new SimpleImmutableEntry<K, V>(key, value);
    }

    /**
     * Creates a Set out of the given keys
     *
     * @param <K> the key type
     * @param keys
     *            the keys
     * @return a Set containing the given keys
     */
    @SafeVarargs
    public static <K> Set<K> set(final K... keys) {
        return new LinkedHashSet<K>(Arrays.asList(keys));
    }

    /**
     * Test for equality.
     * @param obj1 the first object
     * @param obj2 the second object
     * @return true if both are null or the two objects are equal
     */
    public static boolean nullSafeEquals(final Object obj1, final Object obj2) {
        return ((obj1 == null && obj2 == null)
                || (obj1 != null && obj2 != null && obj1.equals(obj2)));
    }

    /**
     * Materializes a job by assuming the {@link Job#getClassName()} is a
     * fully-qualified Java type.
     *
     * @param job
     *            the job to materialize
     * @return the materialized job
     * @throws ClassNotFoundException
     *             if the class could not be found
     * @throws Exception
     *             if there was an exception creating the object
     */
    public static Object materializeJob(final Job job) throws ClassNotFoundException, Exception {
        final Class<?> clazz = ReflectionUtils.forName(job.getClassName());
        // A bit redundant since we check when the job type is added...
        if (!Runnable.class.isAssignableFrom(clazz) && !Callable.class.isAssignableFrom(clazz)) {
            throw new ClassCastException("jobs must be a Runnable or a Callable: " + clazz.getName() + " - " + job);
        }
        return ReflectionUtils.createObject(clazz, job.getArgs(), job.getVars());
    }

    /**
     * Materializes a job by looking up {@link Job#getClassName()} in the
     * provided map of job types.
     *
     * @param job
     *            the job to materialize
     * @param jobTypes
     *            a map of String names to Java types
     * @return the materialized job
     * @throws UnpermittedJobException
     *             if there was not a non-null mapping in jobTypes for the class
     *             name
     * @throws Exception
     *             if there was an exception creating the object
     */
    public static Object materializeJob(final Job job, final Map<String, Class<?>> jobTypes)
            throws UnpermittedJobException, Exception {
        final String className = job.getClassName();
        final Class<?> clazz = jobTypes.get(className);
        if (clazz == null) {
            throw new UnpermittedJobException(className);
        }
        // A bit redundant since we check when the job type is added...
        if (!Runnable.class.isAssignableFrom(clazz) && !Callable.class.isAssignableFrom(clazz)) {
            throw new ClassCastException("jobs must be a Runnable or a Callable: " + clazz.getName() + " - " + job);
        }
        return ReflectionUtils.createObject(clazz, job.getArgs(), job.getVars());
    }

    /**
     * This is needed because Throwable doesn't override equals() and object
     * equality is not what we want to test.
     *
     * @param ex1
     *            first Throwable
     * @param ex2
     *            second Throwable
     * @return true if the two arguments are equal, as we define it.
     */
    public static boolean equal(final Throwable ex1, final Throwable ex2) {
        if (ex1 == ex2) {
            return true;
        }
        if (ex1 == null) {
            if (ex2 != null) {
                return false;
            }
        } else if (ex2 == null) {
            if (ex1 != null) {
                return false;
            }
        } else {
            if (ex1.getClass() != ex2.getClass()) {
                return false;
            }
            if (ex1.getMessage() == null) {
                if (ex2.getMessage() != null) {
                    return false;
                }
            } else if (!ex1.getMessage().equals(ex2.getMessage())) {
                return false;
            }
            if (!equal(ex1.getCause(), ex2.getCause())) {
                return false;
            }
        }
        return true;
    }

    private JesqueUtils() {
        // Utility class
    }
}


text:
{-# LANGUAGE TemplateHaskell #-}

{-|
  Module      : Tests.Murl.Api.Urls
  Description : murl URL API tests
  Copyright   : (c) 2016 murl developers
  License     : MIT

  Maintainer  : alunduil@alunduil.com
  Stability   : experimental
  Portability : portable
-}

module Tests.Murl.Api.Urls where

import Control.Monad
import Murl.Api.Urls
import qualified Murl.Store.Urls as Store
import Test.Framework.Providers.QuickCheck2
import Test.Framework.TH
import Test.QuickCheck

instance Arbitrary Store.LongUrl where
  arbitrary = liftM Store.LongUrl arbitrary

prop_shorten_fixed_length x = 12 == (length . fromShort . shorten $ x)

prop_shorten_unquoted x = not . quoted . fromShort . shorten $ x
                          where quoted :: String -> Bool
                                quoted ('"':cs) | last cs == '"' = True
                                quoted ('\'':cs) | last cs == '\'' = True
                                quoted _ = False

fromShort :: Store.ShortUrl -> String
fromShort (Store.ShortUrl s) = s

tests = $(testGroupGenerator)

redpajama_set_name: RedPajamaGithub


text:
package ir.co.dpq.pluf;

import static org.junit.Assert.assertNotNull;

import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.util.List;

import org.junit.Test;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import ir.co.dpq.pluf.retrofit.PErrorHandler;
import ir.co.dpq.pluf.retrofit.user.IRUserService;
import ir.co.dpq.pluf.retrofit.wiki.IRWikiBookService;
import ir.co.dpq.pluf.retrofit.wiki.IRWikiPageService;
import ir.co.dpq.pluf.test.TestCoreConstant;
import ir.co.dpq.pluf.user.PUser;
import ir.co.dpq.pluf.wiki.PWikiBook;
import retrofit.RestAdapter;
import retrofit.converter.GsonConverter;

public class TestConstant extends TestCoreConstant {

	public static final String API_URL = "http://localhost:8081";

	@Test
	public void test() {
		CookieManager cookieManager = new CookieManager();
		cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
		CookieHandler.setDefault(cookieManager);

		GsonBuilder gsonBuilder = new GsonBuilder();
		gsonBuilder//
				.setDateFormat("yyyy-MM-dd HH:mm:ss");//
		Gson gson = gsonBuilder.create();

		RestAdapter restAdapter = new RestAdapter.Builder()
				// تعیین مبدل داده
				.setConverter(new GsonConverter(gson))
				// تعیین کنترل کننده خطا
				.setErrorHandler(new PErrorHandler())
				// تعیین آدرس سایت مورد نظر
				.setEndpoint(API_URL)
				// ایجاد یک نمونه
				.build();
		// ایجاد سرویس‌ها
		IRUserService userSerivece = restAdapter.create(IRUserService.class);
		IRWikiBookService wikiBookService = restAdapter.create(IRWikiBookService.class);
		IRWikiPageService wikiPageService = restAdapter.create(IRWikiPageService.class);

		PWikiBookDaoRetrofit wikiBookDaoRetrofit = new PWikiBookDaoRetrofit();
		wikiBookDaoRetrofit.setWikiBookService(wikiBookService);

		// Login
		PUser user = userSerivece.login(ADMIN_LOGIN, ADMIN_PASSWORD);
		assertNotNull(user);

		IPPaginatorPage<PWikiBook> result = wikiBookDaoRetrofit.findWikiBook(null);
		List<PWikiBook> books = result.getItems();
		for (PWikiBook b : books) {
			System.out.println("Book: "+b.getTitle());
		}
	}
}


text:
/**
 * @module ol/render/canvas/PolygonBuilder
 */
import {snap} from '../../geom/flat/simplify.js';
import {defaultFillStyle} from '../canvas.js';
import CanvasInstruction, {
  fillInstruction, strokeInstruction, beginPathInstruction, closePathInstruction
} from './Instruction.js';
import CanvasBuilder from './Builder.js';

class CanvasPolygonBuilder extends CanvasBuilder {
  /**
   * @param {number} tolerance Tolerance.
   * @param {import("../../extent.js").Extent} maxExtent Maximum extent.
   * @param {number} resolution Resolution.
   * @param {number} pixelRatio Pixel ratio.
   */
  constructor(tolerance, maxExtent, resolution, pixelRatio) {
    super(tolerance, maxExtent, resolution, pixelRatio);
  }

  /**
   * @param {Array<number>} flatCoordinates Flat coordinates.
   * @param {number} offset Offset.
   * @param {Array<number>} ends Ends.
   * @param {number} stride Stride.
   * @private
   * @return {number} End.
   */
  drawFlatCoordinatess_(flatCoordinates, offset, ends, stride) {
    const state = this.state;
    const fill = state.fillStyle !== undefined;
    const stroke = state.strokeStyle != undefined;
    const numEnds = ends.length;
    this.instructions.push(beginPathInstruction);
    this.hitDetectionInstructions.push(beginPathInstruction);
    for (let i = 0; i < numEnds; ++i) {
      const end = ends[i];
      const myBegin = this.coordinates.length;
      const myEnd = this.appendFlatCoordinates(flatCoordinates, offset, end, stride, true, !stroke);
      const moveToLineToInstruction = [CanvasInstruction.MOVE_TO_LINE_TO, myBegin, myEnd];
      this.instructions.push(moveToLineToInstruction);
      this.hitDetectionInstructions.push(moveToLineToInstruction);
      if (stroke) {
        // Performance optimization: only call closePath() when we have a stroke.
        // Otherwise the ring is closed already (see appendFlatCoordinates above).
        this.instructions.push(closePathInstruction);
        this.hitDetectionInstructions.push(closePathInstruction);
      }
      offset = end;
    }
    if (fill) {
      this.instructions.push(fillInstruction);
      this.hitDetectionInstructions.push(fillInstruction);
    }
    if (stroke) {
      this.instructions.push(strokeInstruction);
      this.hitDetectionInstructions.push(strokeInstruction);
    }
    return offset;
  }

  /**
   * @inheritDoc
   */
  drawCircle(circleGeometry, feature) {
    const state = this.state;
    const fillStyle = state.fillStyle;
    const strokeStyle = state.strokeStyle;
    if (fillStyle === undefined && strokeStyle === undefined) {
      return;
    }
    this.setFillStrokeStyles_();
    this.beginGeometry(circleGeometry, feature);
    if (state.fillStyle !== undefined) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_FILL_STYLE,
        defaultFillStyle
      ]);
    }
    if (state.strokeStyle !== undefined) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
        state.miterLimit, state.lineDash, state.lineDashOffset
      ]);
    }
    const flatCoordinates = circleGeometry.getFlatCoordinates();
    const stride = circleGeometry.getStride();
    const myBegin = this.coordinates.length;
    this.appendFlatCoordinates(
      flatCoordinates, 0, flatCoordinates.length, stride, false, false);
    const circleInstruction = [CanvasInstruction.CIRCLE, myBegin];
    this.instructions.push(beginPathInstruction, circleInstruction);
    this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);
    this.hitDetectionInstructions.push(fillInstruction);
    if (state.fillStyle !== undefined) {
      this.instructions.push(fillInstruction);
    }
    if (state.strokeStyle !== undefined) {
      this.instructions.push(strokeInstruction);
      this.hitDetectionInstructions.push(strokeInstruction);
    }
    this.endGeometry(feature);
  }

  /**
   * @inheritDoc
   */
  drawPolygon(polygonGeometry, feature) {
    const state = this.state;
    const fillStyle = state.fillStyle;
    const strokeStyle = state.strokeStyle;
    if (fillStyle === undefined && strokeStyle === undefined) {
      return;
    }
    this.setFillStrokeStyles_();
    this.beginGeometry(polygonGeometry, feature);
    if (state.fillStyle !== undefined) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_FILL_STYLE,
        defaultFillStyle
      ]);
    }
    if (state.strokeStyle !== undefined) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
        state.miterLimit, state.lineDash, state.lineDashOffset
      ]);
    }
    const ends = polygonGeometry.getEnds();
    const flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();
    const stride = polygonGeometry.getStride();
    this.drawFlatCoordinatess_(flatCoordinates, 0, ends, stride);
    this.endGeometry(feature);
  }

  /**
   * @inheritDoc
   */
  drawMultiPolygon(multiPolygonGeometry, feature) {
    const state = this.state;
    const fillStyle = state.fillStyle;
    const strokeStyle = state.strokeStyle;
    if (fillStyle === undefined && strokeStyle === undefined) {
      return;
    }
    this.setFillStrokeStyles_();
    this.beginGeometry(multiPolygonGeometry, feature);
    if (state.fillStyle !== undefined) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_FILL_STYLE,
        defaultFillStyle
      ]);
    }
    if (state.strokeStyle !== undefined) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
        state.miterLimit, state.lineDash, state.lineDashOffset
      ]);
    }
    const endss = multiPolygonGeometry.getEndss();
    const flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();
    const stride = multiPolygonGeometry.getStride();
    let offset = 0;
    for (let i = 0, ii = endss.length; i < ii; ++i) {
      offset = this.drawFlatCoordinatess_(flatCoordinates, offset, endss[i], stride);
    }
    this.endGeometry(feature);
  }

  /**
   * @inheritDoc
   */
  finish() {
    this.reverseHitDetectionInstructions();
    this.state = null;
    // We want to preserve topology when drawing polygons.  Polygons are
    // simplified using quantization and point elimination. However, we might
    // have received a mix of quantized and non-quantized geometries, so ensure
    // that all are quantized by quantizing all coordinates in the batch.
    const tolerance = this.tolerance;
    if (tolerance !== 0) {
      const coordinates = this.coordinates;
      for (let i = 0, ii = coordinates.length; i < ii; ++i) {
        coordinates[i] = snap(coordinates[i], tolerance);
      }
    }
    return super.finish();
  }

  /**
   * @private
   */
  setFillStrokeStyles_() {
    const state = this.state;
    const fillStyle = state.fillStyle;
    if (fillStyle !== undefined) {
      this.updateFillStyle(state, this.createFill);
    }
    if (state.strokeStyle !== undefined) {
      this.updateStrokeStyle(state, this.applyStroke);
    }
  }
}

export default CanvasPolygonBuilder;


text:
namespace ip_unicast_compile {

void test()
{
  using namespace asio;
  namespace ip = asio::ip;

  try
  {
    io_service ios;
    ip::udp::socket sock(ios);

    // hops class.

    ip::unicast::hops hops1(1024);
    sock.set_option(hops1);
    ip::unicast::hops hops2;
    sock.get_option(hops2);
    hops1 = 1;
    (void)static_cast<int>(hops1.value());
  }
  catch (std::exception&)
  {
  }
}

} // namespace ip_unicast_compile

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

// ip_unicast_runtime test
// ~~~~~~~~~~~~~~~~~~~~~~~
// The following test checks the runtime operation of the socket options defined
// in the ip::unicast namespace.

namespace ip_unicast_runtime {

void test()
{
  using namespace asio;
  namespace ip = asio::ip;

  io_service ios;
  asio::error_code ec;

  ip::udp::endpoint ep_v4(ip::address_v4::loopback(), 0);
  ip::udp::socket sock_v4(ios);
  sock_v4.open(ep_v4.protocol(), ec);
  sock_v4.bind(ep_v4, ec);
  bool have_v4 = !ec;

  ip::udp::endpoint ep_v6(ip::address_v6::loopback(), 0);
  ip::udp::socket sock_v6(ios);
  sock_v6.open(ep_v6.protocol(), ec);
  sock_v6.bind(ep_v6, ec);
  bool have_v6 = !ec;

  ASIO_CHECK(have_v4 || have_v6);

  // hops class.

  if (have_v4)
  {
    ip::unicast::hops hops1(1);
    ASIO_CHECK(hops1.value() == 1);
    sock_v4.set_option(hops1, ec);
#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
    // Option is not supported under Windows CE.
    ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
        ec.value() << ", " << ec.message());
#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
    ASIO_CHECK(!ec);
#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)

    ip::unicast::hops hops2;
    sock_v4.get_option(hops2, ec);
#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
    // Option is not supported under Windows CE.
    ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
        ec.value() << ", " << ec.message());
#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
    ASIO_CHECK(!ec);
    ASIO_CHECK(hops2.value() == 1);
#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)

    ip::unicast::hops hops3(255);
    ASIO_CHECK(hops3.value() == 255);
    sock_v4.set_option(hops3, ec);
#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
    // Option is not supported under Windows CE.
    ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
        ec.value() << ", " << ec.message());
#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
    ASIO_CHECK(!ec);
#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)

    ip::unicast::hops hops4;
    sock_v4.get_option(hops4, ec);
#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
    // Option is not supported under Windows CE.
    ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
        ec.value() << ", " << ec.message());
#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
    ASIO_CHECK(!ec);
    ASIO_CHECK(hops4.value() == 255);
#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
  }

  if (have_v6)
  {
    ip::unicast::hops hops1(1);
    ASIO_CHECK(hops1.value() == 1);
    sock_v6.set_option(hops1, ec);
    ASIO_CHECK(!ec);

    ip::unicast::hops hops2;
    sock_v6.get_option(hops2, ec);
    ASIO_CHECK(!ec);
    ASIO_CHECK(hops2.value() == 1);

    ip::unicast::hops hops3(255);
    ASIO_CHECK(hops3.value() == 255);
    sock_v6.set_option(hops3, ec);
    ASIO_CHECK(!ec);

    ip::unicast::hops hops4;
    sock_v6.get_option(hops4, ec);
    ASIO_CHECK(!ec);
    ASIO_CHECK(hops4.value() == 255);
  }
}

} // namespace ip_unicast_runtime

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

ASIO_TEST_SUITE
(
  "ip/unicast",
  ASIO_TEST_CASE(ip_unicast_compile::test)
  ASIO_TEST_CASE(ip_unicast_runtime::test)
)


text:
require 'spec_helper'

class ManagedStateTest
  include Collins::State::Mixin
end

class ManagedStateTestWithClient
  include Collins::State::Mixin
  attr_accessor :collins_client
  manage_state :foo do |client|
  end
  def initialize client
    @collins_client = client
  end
end

describe Collins::State do

  subject { ManagedStateTest.new }

  it "throw an exception if no collins_client" do
    expect { subject.collins_client }.to raise_error(NotImplementedError)
  end

  it "throw an exception if no logger" do
    expect { subject.logger }.to raise_error(NotImplementedError)
  end

  it "throw an exception if no transition" do
    client = double("client")
    client.should_receive(:get).with("fizz") { Collins::Asset.new("fizz") }
    msc = ManagedStateTestWithClient.new client
    expect { msc.transition("fizz") }.to raise_error(/no initial/)
  end

  it "calls super on no arg to method_missing" do
    expect { subject.foo }.to raise_error
  end

  it "calls super when arg isn't an asset" do
    expect { subject.foo(123) }.to raise_error
  end

  it "calls super when second arg not a hash" do
    expect {subject.foo("tag", 123)}.to raise_error
  end

  it "bails when no such event" do
    expect {subject.foo("tag")}.to raise_error
  end

  it "barfs if no event description" do
    expect {subject.class.event("fizz")}.to raise_error(/missing :desc/)
  end

  context "#after" do
    subject {ManagedStateTest}
    it "handles seconds" do
      subject.after(60, :seconds).should == 60
    end
    it "handles minutes" do
      subject.after(60, :minutes).should == 3600
    end
    it "handles hours" do
      subject.after(24, :hours).should == 86400
    end
  end

end


text:
/*jslint indent: 2 */
/*global $: false, togglbutton: false, createTag:false, document: false*/

'use strict';

togglbutton.render('.dialog:not(.toggl)', {observe: true}, function (elem) {
  var link, wrap = createTag('div'),
    container = $('#top-level-details', elem),
    projectElem = $('.folderSelector', elem),
    titleFunc;

  titleFunc = function () {
    return document.querySelector('#title', elem).textContent;
  };

  link = togglbutton.createTimerLink({
    className: 'anydo',
    description: titleFunc,
    projectName: projectElem.textContent
  });

  wrap.appendChild(link);
  container.appendChild(wrap);
});

/* Subtasks */

togglbutton.render('.subtasks-list li .container:not(.toggl)', {observe: true}, function (elem) {
  var link, wrap = createTag('div'),
    projectElem = $('.folderSelector'),
    titleFunc;

  titleFunc = function () {
    return $('.title', elem).textContent;
  };

  link = togglbutton.createTimerLink({
    className: 'anydo',
    description: titleFunc,
    projectName: projectElem.textContent
  });

  wrap.appendChild(link);
  elem.insertBefore(wrap, $('.controls', elem));
});


text:
#import <Foundation/Foundation.h>
#import "IStoreAssets.h"

@class VirtualCategory;
@class VirtualCurrency;
@class VirtualGood;
@class VirtualCurrencyPack;
@class NonConsumableItem;
@class VirtualItem;
@class PurchasableVirtualItem;
@class UpgradeVG;

/**
 * This class holds the store's meta data including:
 * - Virtual Currencies
 * - Virtual Currency Packs
 * - All kinds of Virtual Goods
 * - Virtual Categories
 * - NonConsumables
 */
@interface StoreInfo : NSObject{
    @private
    NSDictionary* virtualItems;
    NSDictionary* purchasableItems;
    NSDictionary* goodsCategories;
    NSDictionary* goodsUpgrades;
    @public
    NSArray* virtualCurrencies;
    NSArray* virtualGoods;
    NSArray* virtualCurrencyPacks;
    NSArray* nonConsumableItems;
    NSArray* virtualCategories;
}

@property (nonatomic, retain) NSArray* virtualCurrencies;
@property (nonatomic, retain) NSArray* virtualGoods;
@property (nonatomic, retain) NSArray* virtualCurrencyPacks;
@property (nonatomic, retain) NSArray* nonConsumableItems;
@property (nonatomic, retain) NSArray* virtualCategories;
@property (nonatomic, retain) NSDictionary* virtualItems;
@property (nonatomic, retain) NSDictionary* purchasableItems;
@property (nonatomic, retain) NSDictionary* goodsCategories;
@property (nonatomic, retain) NSDictionary* goodsUpgrades;

+ (StoreInfo*)getInstance;

/**
 * This function initializes StoreInfo. On first initialization, when the
 * database doesn't have any previous version of the store metadata, StoreInfo
 * is being loaded from the given IStoreAssets. After the first initialization,
 * StoreInfo will be initialized from the database.
 *
 * IMPORTANT: If you want to override the current StoreInfo, you'll have to bump the version of your
 * implementation of IStoreAssets in order to remove the metadata when the application loads.
 * (bumping the version is done by returning a higher number in IStoreAssets:getVersion.
 */
- (void)initializeWithIStoreAssets:(id <IStoreAssets>)storeAssets;

/**
 * Initializes StoreInfo from the database. This action should be performed only once during the lifetime of
 * a session of the game. StoreController automatically initializes StoreInfo. Don't do it if you don't know what
 * you're doing.
 * return success.
 */
- (BOOL)initializeFromDB;
- (NSDictionary*)toDictionary;

/**
 * A utility function to retrieve a single VirtualItem that resides in the meta data.
 *
 * itemId is the itemId of the required VirtualItem.
 *
 * throws VirtualItemNotFoundException when the given itemId was not found.
 */
- (VirtualItem*)virtualItemWithId:(NSString*)itemId;

/**
 * A utility function to retrieve a single PurchasableVirtualItem that resides in the meta data.
 *
 * IMPORTANT: The retrieved PurchasableVirtualItems are only those which has a purchaseType of PurchaseWithMarket.
 * (This is why we fetch here with productId)
 *
 * productId the productId of the required PurchasableVirtualItem.
 *
 * throws VirtualItemNotFoundException when the given productId was not found.
 */
- (PurchasableVirtualItem*)purchasableItemWithProductId:(NSString*)productId;

/**
 * A utility function to retrieve a single VirtualCategory for a given VirtualGood itemId.
 *
 * goodItemId is the virtualGood in the category.
 *
 * returns a VirtualCategory for the given VirtualGood.
 *
 * throws VirtualItemNotFoundException when the given goodItemId was not found.
 */
- (VirtualCategory*)categoryForGoodWithItemId:(NSString*)goodItemId;

/**
 * A utility function to retrieve a first UpgradeVG for a given VirtualGood itemId.
 * goodItemId is the VirtualGood we're searching the upgrade for.
 */
- (UpgradeVG*)firstUpgradeForGoodWithItemId:(NSString*)goodItemId;

/**
 * A utility function to retrieve a last UpgradeVG for a given VirtualGood itemId.
 * goodItemId is the VirtualGood we're searching the upgrade for.
 */
- (UpgradeVG*)lastUpgradeForGoodWithItemId:(NSString*)goodItemId;

/**
 * A utility function to retrieve all UpgradeVGs for a given VirtualGood itemId.
 * goodItemId is the VirtualGood we're searching the upgrades for.
 */
- (NSArray*)upgradesForGoodWithItemId:(NSString*)goodItemId;

- (NSArray*)allProductIds;
- (BOOL)goodHasUpgrades:(NSString*)goodItemId;
@end


text: <body>XWork util classes.</body>


text:
title: If you can read this... Thank a Teacher!
date: 2017-11-23T06:21:22-03:00
description: "This week, take some time to thank a teacher or mentor you appreciate."
tags:
    - Admonition
    - Teachers/Teaching
    - Thankfulness
    - Galatians
---

All it takes is a quick email, phone call, or even a text. Or better yet... next time you see them, take some time to let them know how much you appreciate what they do for you. It is *really* hard to be a teacher and is often a thank-less endeavour which can get depressing over time. Even a short word of thanks can go great lengths to encourage your teacher. Consider **Galatians 6:13**:

> The one who is taught the word is to share all good things with the one who teaches

We need to develop a culture where teachers challenge students to grow and where students *encourage* teachers to keep challenging them. As a professor of mine once said:

> Teachers are not producers and students are not consumers.

The best growth and learning occurs when both teachers *and* students are engaged in the teaching/learning process.

All of these principles also apply to student-teacher relationships outside of the Church, but especially those within the Church.

Find someone you appreciate and say "Thank you"!


text:
<!DOCTYPE html>

  <title>OneDrive Dev Center - OneDrive API and File Pickers</title>
  <meta name="description" content="OneDrive API works on every platform, so you don't have to.">
  <meta name="keywords" content="onedrive dev center,onedrive api,onedrive,files api">
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
  <link rel="stylesheet" href="css/od-dev.css" />
  <link rel="icon" href="https://d.sfx-df.ms/images/favicon.ico" type="image/x-icon">
  <link rel="mask-icon" href="https://d.sfx-df.ms/images/mask_icon.svg" color="#094AB2">

            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                Toggle navigation

            </button>

Home

Documentation

SDKs

Samples

App Registration

OneDrive Files API

Access OneDrive, OneDrive for Business, and SharePoint files from Microsoft Graph.

Learn more »

OneDrive Files API

Access OneDrive, OneDrive for Business, and SharePoint files from Microsoft Graph.

Learn more »

OneDrive Files API

Access OneDrive, OneDrive for Business, and SharePoint files from Microsoft Graph.

Learn more »

Start with REST

Store and access files in OneDrive and SharePoint from within your solution.
                   Leverage OneDrive and SharePoint to keep your user content secure, compliant, and available across all devices.

Getting started »

Start with a client library

                   Whether you love .NET or Python, or are building apps for iOS or
                   Android devices, we want to make it as easy as possible to develop apps for OneDrive and SharePoint.

Choose an SDK »

Use the JavaScript file picker

                    Want to add OneDrive to your web app fast? With only a few lines of code you can enable
                    your app to open and save files to and from OneDrive and OneDrive for Business.

JavaScript File picker »

At Docady, we integrate with many cloud services. Adding the OneDrive API
                           was so easy, we were up an running in hours, including automated tests. And,
                           having the integration serve both OneDrive consumers and Enterprise users
                           was just perfect.

Nadav Weizmann (Wiz)
CTO and Co-Founder Docady

Try the API

                      Explore the OneDrive through Microsoft Graph API Explorer.

Try it out »

Integrate with OneDrive mobile

                    Connect your app to the OneDrive app on iOS and Android using the native OS file contracts.

Learn more »

OneDrive API features

OneDrive and Microsoft Graph are used by thousands of applications to connect with files across Office 365, OneDrive, and SharePoint.



Powered by Microsoft Graph

Connect to OneDrive, OneDrive for Business, or SharePoint files with the same API.



Webhooks and notifications

Receive notifications when content changes so your app is always up-to-date.



App folders

Find a home for your files by giving your app its own folder in OneDrive.



Delta sync

Track file and folder changes, efficiently keeping track of cloud files in your app.



Upload large files

Reliably upload large files with a resumable upload API.



CORS support

Call the OneDrive API from your single page JavaScript app.

Documentation

All of our documentation is on GitHub, but you can get started here. We've worked hard to create a modern, RESTful API environment that works the way you do.

View the documentation »

Samples

Learn more about the Microsoft Graph through sample code projects on GitHub.

View code samples »

Stack Overflow

Tag a question about OneDrive here. We're listening.

GitHub

We are on GitHub too. Find all of our official documentation here.

User Voice

Have a feature to suggest for OneDrive? We want to hear what you have to say.

Built by the community, powered by OneDrive

Apps that work with files in OneDrive, OneDrive for Business, and SharePoint. Find more OneDrive partner apps on office.com.

                            Privacy

                            Terms of use

                            Trademarks

© 2015 Microsoft

© 2015 Microsoft

                            Privacy Statement

                            Trademarks

                            Terms of Use


text:
package org.mycontroller.standalone.db.dao;

import java.sql.SQLException;
import java.util.List;

import org.mycontroller.standalone.AppProperties.NETWORK_TYPE;
import org.mycontroller.standalone.AppProperties.RESOURCE_TYPE;
import org.mycontroller.standalone.api.jaxrs.model.AllowedResources;
import org.mycontroller.standalone.api.jaxrs.model.Query;
import org.mycontroller.standalone.api.jaxrs.model.QueryResponse;
import org.mycontroller.standalone.auth.AuthUtils;
import org.mycontroller.standalone.db.tables.GatewayTable;
import org.mycontroller.standalone.exceptions.McDatabaseException;
import org.mycontroller.standalone.gateway.GatewayUtils.GATEWAY_TYPE;

import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.j256.ormlite.support.ConnectionSource;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Jeeva Kandasamy (jkandasa)
 * @since 0.0.2
 */
@Slf4j
public class GatewayDaoImpl extends BaseAbstractDaoImpl<GatewayTable, Integer> implements GatewayDao {
    public GatewayDaoImpl(ConnectionSource connectionSource) throws SQLException {
        super(connectionSource, GatewayTable.class);
    }

    @Override
    public List<GatewayTable> getAllEnabled() {
        return getAll(null, null, true);
    }

    @Override
    public List<GatewayTable> getAll(GATEWAY_TYPE gatewayType, NETWORK_TYPE networkType) {
        return getAll(gatewayType, networkType, null);
    }

    @Override
    public List<GatewayTable> getAll(GATEWAY_TYPE gatewayType, NETWORK_TYPE networkType, Boolean enabled) {
        try {
            if (gatewayType == null && networkType == null && enabled == null) {
                return this.getDao().queryForAll();
            }
            QueryBuilder<GatewayTable, Integer> queryBuilder = this.getDao().queryBuilder();
            Where<GatewayTable, Integer> where = queryBuilder.where();
            where.gt("id", 0);//This line is used to add and() for above inputs
            if (enabled != null) {
                where.and().eq(GatewayTable.KEY_ENABLED, enabled);
            }
            if (gatewayType != null) {
                where.and().eq(GatewayTable.KEY_TYPE, gatewayType);
            }
            if (networkType != null) {
                where.and().eq(GatewayTable.KEY_NETWORK_TYPE, networkType);
            }
            queryBuilder.setWhere(where);
            List<GatewayTable> gateways = this.getDao().query(queryBuilder.prepare());
            return gateways;
        } catch (SQLException ex) {
            _logger.error("unable to get all gateways:[type:{}, NetworkType:{}, Enabled:{}]",
                    gatewayType != null ? gatewayType.getText() : null, networkType, enabled, ex);
            throw new McDatabaseException(ex);
        }
    }

    @Override
    public QueryResponse getAll(Query query) {
        try {
            query.setIdColumn(GatewayTable.KEY_ID);
            return this.getQueryResponse(query);
        } catch (SQLException ex) {
            _logger.error("unable to run query:[{}]", query, ex);
            throw new McDatabaseException(ex);
        }
    }

    @Override
    public GatewayTable get(GatewayTable tdao) {
        return this.getById(tdao.getId());
    }

    @Override
    public List<GatewayTable> getAll(List<Integer> ids) {
        return getAll(GatewayTable.KEY_ID, ids);
    }

    public List<GatewayTable> getAll(Query query, String filter, AllowedResources allowedResources) {
        AuthUtils.updateQueryFilter(query.getFilters(), RESOURCE_TYPE.GATEWAY, allowedResources);
        query.getFilters().put(GatewayTable.KEY_NAME, filter);
        query.setAndQuery(false);
        return super.getAllData(query);
    }
}


text:
(function(window){

	// Variables
	var term = {}
		, schedule = {}
		, seat_workers_cnt = 15
		, seat_workers_i = 0
		, seat_workers = []
		, conflict_worker = 0
		, majors_updating = {}
		, tooltip_data = {}
		, seats = io.connect('/seats')
		, notifications = io.connect('/notifications')
		,	array_diff = function(o,a){return o.filter(function(e){return((a.indexOf(e)>-1)===false)})}

	//fallback on console log
	if ( !window['console'] ){
		window.console = {};
		window.console.info = function(){};
		window.console.log = function(){};
		window.console.warn = function(){};
		window.console.error = function(){};
	}

	// Setup ajax
	$.ajaxSetup({
		timeout: 60000 ///60 second timeout
	});

/***************************************************************************
 *
 * Storage Helpers
 *
***************************************************************************/
	Storage = window.Storage || window.localStorage || {};
	Storage.prototype.setObject = function(key, value) {
			localStorage.setItem(key, JSON.stringify(value));
	}
	Storage.prototype.getObject = function(key) {
			// :TODO: Add experation code
			return localStorage.getItem(key) && JSON.parse(localStorage.getItem(key));
	}
	function storeObject(name, obj){
		if ( Modernizr.localstorage ){
			localStorage.setObject(name, obj);
		}
	}
	function removeItem(name){
		if ( Modernizr.localstorage ){
			localStorage.removeItem(name);
		}
	}
	function getObject(name){
		if ( Modernizr.localstorage ){
			return localStorage.getObject(name);
		}
		return null;
	}

/***************************************************************************
 *
 * Main Shark Object
 *
***************************************************************************/
	Shark = function(){
		this.io = {seats: seats, notifications: notifications}
		this.Schedule = require('/scripts/modules/schedule')
		return this
	}
	window.shark = new Shark();

function errorHandler(err, text, errInfo)
{
	if (text === ''){
		text = 'An unexpected error has occurred.

Please check your information and try again.

If the problem persists, please contact us or file a bug report."';
	}
	errorDialog(text, errInfo);
}

function redirect(url){
	window.location = url;
}

function noscript(){
	$('noscript').each(function(){$(this).remove();});
}

function logout(){
	var removed = window.localStorage ? window.localStorage.removeItem ? window.localStorage.removeItem("primary-schedule") : 0 : 0;
	window.location = '/users/logout';
}

function get_courses_from_major(id, callback, term){
	$.ajax({
			url:"/term/"+term+"/courses/"+id,
			success: function(c){callback(c);},
			dataType:'json',
			data:{},
			error: function(jqXHR, textStatus, errorThrown){errorHandler(jqXHR,'',errorThrown);}
		});
}

function get_full_sections_from_course(id, term_id, callback){
	$.ajax({
			url:"/school/"+school+"/course/"+id+"/term/"+term_id+"/full" ,
			success: callback,
			dataType:'json',
			data:{},
			error: function(jqXHR, textStatus, errorThrown){errorHandler(jqXHR,'',errorThrown);}
		});
}

try{
	$.ajaxSetup({timeout:15000});
}catch(err){}

$(document).mousemove(function(e){
	document.x = e.pageX;
	document.y = e.pageY;
});

/*
 * jQuery Placeholder Plug-in
 *
 * Copyright (c) 2010 Max Davis
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: 2
 * Version: .1
 *
 * v0.1
 * - First public release
 *
 * Modified for use on CourseShark by James Rundquist
 * Copyright (c) 2011 James Rundquist
*/
(function($){

	$.fn.placeholder = function() {

		/** Test for modern HTML5 browsers **/
		var dummy = document.createElement('input');
		if(dummy.placeholder !== undefined){
			return $(this)
		}

		if($(this).attr("type") == "password") {

			var original_pass_field = $(this);

			if(original_pass_field.val() === "") {
				$(this).parent().prepend("<input type=\"text\" style=\"color:#777777;\" value=\""+ $(this).attr("placeholder") +"\" name=\"pass_placeholder\" class=\"form-text\" id=\"pass_placeholder\">");
				$(this).css("display","none");
			}

			$("#pass_placeholder").focus(function() {
				if(original_pass_field.val() === "") {
					$("#pass_placeholder").css("display","none");
					original_pass_field.css("display","");
					original_pass_field.focus();
				}
			});

			original_pass_field.blur(function() {
				if(original_pass_field.val() === "") {
					$("#pass_placeholder").css("display","");
					original_pass_field.css("display","none");
				}
			});

		} else {

			if($(this).val() === "") {
				$(this).val($(this).attr("placeholder"));
				$(this).css("color","#777777");
			}

			$(this).focus(function() {
				if($(this).val() === $(this).attr("placeholder")) {
					$(this).css("color","#000000");
					$(this).val("");
				}
			}).blur(function() {
				if($(this).val() === "") {
					$(this).css("color","#777777");
					$(this).val($(this).attr("placeholder"));
				}
			});
		}
	}

})(jQuery);

SectionPicker = function(opts){
	var $term, $major, $course, $section, options, term, updating;
	$term = this.$term = opts['term']
	$department = this.$department = opts['department']
	$course = this.$course = opts['course']?opts['course']:$('<select>')
	$section = this.$section = opts['section']?opts['section']:$('<select>')
	config = this.config = opts['options']
	updating = {}

	term = $term?$term.val():window.term?window.term.id?window.term.id:window.term:'';

		$.ajax({
				url: '/term/'+term+'/departments'
			, dataType: 'json'
			, success: function(d){
					var options = '', e = {}
					for ( var i=0,len=d.length; i<len; i++ ){
						e = d[i]
						options += '<option value="'+e._id+'">'+e.name+'</option>'
					}
					$department.html(options).removeAttr('disabled').change()
				}
			})

	$department.change(function(){
		var id = $department.val()
		if ( $department.children('option').first().val() === '' ){
			$department.children('option').first().remove();
		}
		if (!id){return;}
		$course.attr('disabled','true').html("<option>Loading...</option>");
		$section.attr('disabled','true').html("<option value=''>Loading...</option>");
		$.ajax({
				url:"/term/"+term+"/courses/"+id
			, dataType:'json'
			, success: function(c){
					var options = '';
					for (var i = 0; i < c.length; i++) {
						options += '<option value="'+c[i]._id+'">'+c[i].number+' — '+c[i].name+'</option>'
					}
					$course.html(options).removeAttr('disabled').change()
				}
			, error: function(jqXHR, textStatus, errorThrown){errorHandler(jqXHR,textStatus,errorThrown);}
		});
	});

	$course.change(function(){
		var id=$course.val()
		$section.attr('disabled','true').html("<option value=''>Loading...</option>");
		if (!id){return;}
		$.ajax({
				url:"/sections/"+id
			, dataType:'json'
			, success: function(secs){
					updating[id] = 0
					var options = '', s = {}
					for ( var i=0,len=secs.length; i<len; i++ ){
						s = secs[i]
						if ( !config['empty'] ){
							options += '<option value="'+s._id+'">'+s.number+' — '+s.timeslots[0].instructor+'</option>'
						}else{
							updating[id]++
							seats.emit('update', s._id)
						}
					}
					if ( !config['empty'] ){
						$section.html(options).removeAttr('disabled')
					}
				}
			, error: function(jqXHR, textStatus, errorThrown){errorHandler(jqXHR,textStatus,errorThrown);}
		});
	})
	if ( config['empty'] ){
		seats.on('result', function(section){
			s = section.section
			if ( section.avail <= 0 ){
				$section.append('<option value="'+s._id+'">'+s.number+' — '+s.timeslots[0].instructor+'</option>')
			}
			if ( --updating[s.course._id] === 0 ){
				$section.children("option[value='']").remove();
				if ( $section.children('option').length === 0 ){
					$section.html('<option value="">No Full Sections</option>')
				}else{
					$section.removeAttr('disabled')
				}
			}

		});
	}
}

})(window);

function validateEmail(email) {
		var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
		return email.match(re);
}


text:
/* Authors: Lutong Wang and Bangqi Xu */
/*
 * Copyright (c) 2019, The Regents of the University of California
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <cmath>

#include "ta/FlexTA.h"

using namespace std;
using namespace fr;

frSquaredDistance FlexTAWorker::box2boxDistSquare(const Rect& box1,
                                                  const Rect& box2,
                                                  frCoord& dx,
                                                  frCoord& dy)
{
  dx = max(max(box1.xMin(), box2.xMin()) - min(box1.xMax(), box2.xMax()), 0);
  dy = max(max(box1.yMin(), box2.yMin()) - min(box1.yMax(), box2.yMax()), 0);
  return (frSquaredDistance) dx * dx + (frSquaredDistance) dy * dy;
}

// must be current TA layer
void FlexTAWorker::modMinSpacingCostPlanar(const Rect& box,
                                           frLayerNum lNum,
                                           taPinFig* fig,
                                           bool isAddCost,
                                           set<taPin*, frBlockObjectComp>* pinS)
{
  // obj1 = curr obj
  frCoord width1 = box.minDXDY();
  frCoord length1 = box.maxDXDY();
  // obj2 = other obj
  // layer default width
  frCoord width2 = getDesign()->getTech()->getLayer(lNum)->getWidth();
  frCoord halfwidth2 = width2 / 2;
  // spacing value needed
  frCoord bloatDist = 0;
  auto con = getDesign()->getTech()->getLayer(lNum)->getMinSpacing();
  if (con) {
    if (con->typeId() == frConstraintTypeEnum::frcSpacingConstraint) {
      bloatDist = static_cast<frSpacingConstraint*>(con)->getMinSpacing();
    } else if (con->typeId()
               == frConstraintTypeEnum::frcSpacingTablePrlConstraint) {
      bloatDist = static_cast<frSpacingTablePrlConstraint*>(con)->find(
          max(width1, width2), length1);
    } else if (con->typeId()
               == frConstraintTypeEnum::frcSpacingTableTwConstraint) {
      bloatDist = static_cast<frSpacingTableTwConstraint*>(con)->find(
          width1, width2, length1);
    } else {
      cout << "Warning: min spacing rule not supporterd" << endl;
      return;
    }
  } else {
    cout << "Warning: no min spacing rule" << endl;
    return;
  }
  if (fig->getNet()->getNondefaultRule())
    bloatDist
        = max(bloatDist,
              fig->getNet()->getNondefaultRule()->getSpacing(lNum / 2 - 1));

  frSquaredDistance bloatDistSquare = (frSquaredDistance) bloatDist * bloatDist;

  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);

  // now assume track in H direction
  frCoord boxLow = isH ? box.yMin() : box.xMin();
  frCoord boxHigh = isH ? box.yMax() : box.xMax();
  frCoord boxLeft = isH ? box.xMin() : box.yMin();
  frCoord boxRight = isH ? box.xMax() : box.yMax();
  Rect box1(boxLeft, boxLow, boxRight, boxHigh);

  int idx1, idx2;
  getTrackIdx(boxLow - bloatDist - halfwidth2 + 1,
              boxHigh + bloatDist + halfwidth2 - 1,
              lNum,
              idx1,
              idx2);

  Rect box2(-halfwidth2, -halfwidth2, halfwidth2, halfwidth2);
  dbTransform xform;
  frCoord dx, dy;
  auto& trackLocs = getTrackLocs(lNum);
  auto& workerRegionQuery = getWorkerRegionQuery();
  for (int i = idx1; i <= idx2; i++) {
    auto trackLoc = trackLocs[i];
    xform.setOffset(Point(boxLeft, trackLoc));
    xform.apply(box2);
    box2boxDistSquare(box1, box2, dx, dy);
    if (dy >= bloatDist) {
      continue;
    }
    frCoord maxX = (frCoord) (sqrt(1.0 * bloatDistSquare
                                   - 1.0 * (frSquaredDistance) dy * dy));
    if ((frSquaredDistance) maxX * maxX + (frSquaredDistance) dy * dy
        == bloatDistSquare) {
      maxX = max(0, maxX - 1);
    }
    frCoord blockLeft = boxLeft - maxX - halfwidth2;
    frCoord blockRight = boxRight + maxX + halfwidth2;
    Rect tmpBox;
    if (isH) {
      tmpBox.init(blockLeft, trackLoc, blockRight, trackLoc);
    } else {
      tmpBox.init(trackLoc, blockLeft, trackLoc, blockRight);
    }
    if (isAddCost) {
      workerRegionQuery.addCost(tmpBox, lNum, fig, con);
      if (pinS) {
        workerRegionQuery.query(tmpBox, lNum, *pinS);
      }
    } else {
      workerRegionQuery.removeCost(tmpBox, lNum, fig, con);
      if (pinS) {
        workerRegionQuery.query(tmpBox, lNum, *pinS);
      }
    }
  }
}

// given a shape on any routing layer n, block via @(n+1) if isUpperVia is true
void FlexTAWorker::modMinSpacingCostVia(const Rect& box,
                                        frLayerNum lNum,
                                        taPinFig* fig,
                                        bool isAddCost,
                                        bool isUpperVia,
                                        bool isCurrPs,
                                        set<taPin*, frBlockObjectComp>* pinS)
{
  // obj1 = curr obj
  frCoord width1 = box.minDXDY();
  frCoord length1 = box.maxDXDY();
  // obj2 = other obj
  // default via dimension
  frViaDef* viaDef = nullptr;
  frLayerNum cutLNum = 0;
  if (isUpperVia) {
    viaDef
        = (lNum < getDesign()->getTech()->getTopLayerNum())
              ? getDesign()->getTech()->getLayer(lNum + 1)->getDefaultViaDef()
              : nullptr;
    cutLNum = lNum + 1;
  } else {
    viaDef
        = (lNum > getDesign()->getTech()->getBottomLayerNum())
              ? getDesign()->getTech()->getLayer(lNum - 1)->getDefaultViaDef()
              : nullptr;
    cutLNum = lNum - 1;
  }
  if (viaDef == nullptr) {
    return;
  }
  frVia via(viaDef);
  Rect viaBox(0, 0, 0, 0);
  if (isUpperVia) {
    viaBox = via.getLayer1BBox();
  } else {
    viaBox = via.getLayer2BBox();
  }
  frCoord width2 = viaBox.minDXDY();
  frCoord length2 = viaBox.maxDXDY();

  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
  frLayerNum followTrackLNum;
  if (cutLNum - 1 >= getDesign()->getTech()->getBottomLayerNum()
      && getDesign()->getTech()->getLayer(cutLNum - 1)->getType()
             == dbTechLayerType::ROUTING
      && getDesign()->getTech()->getLayer(cutLNum - 1)->getDir() == getDir()) {
    followTrackLNum = cutLNum - 1;
  } else if (cutLNum + 1 <= getDesign()->getTech()->getTopLayerNum()
             && getDesign()->getTech()->getLayer(cutLNum + 1)->getType()
                    == dbTechLayerType::ROUTING
             && getDesign()->getTech()->getLayer(cutLNum + 1)->getDir()
                    == getDir()) {
    followTrackLNum = cutLNum + 1;
  } else {
    cout << "Warning: via layer connected to non-routing layer, skipped in "
            "modMinSpacingCostVia"
         << endl;
    return;
  }

  // spacing value needed
  frCoord bloatDist = 0;
  auto con = getDesign()->getTech()->getLayer(lNum)->getMinSpacing();
  if (con) {
    if (con->typeId() == frConstraintTypeEnum::frcSpacingConstraint) {
      bloatDist = static_cast<frSpacingConstraint*>(con)->getMinSpacing();
    } else if (con->typeId()
               == frConstraintTypeEnum::frcSpacingTablePrlConstraint) {
      bloatDist = static_cast<frSpacingTablePrlConstraint*>(con)->find(
          max(width1, width2), isCurrPs ? length2 : min(length1, length2));
    } else if (con->typeId()
               == frConstraintTypeEnum::frcSpacingTableTwConstraint) {
      bloatDist = static_cast<frSpacingTableTwConstraint*>(con)->find(
          width1, width2, isCurrPs ? length2 : min(length1, length2));
    } else {
      cout << "Warning: min spacing rule not supporterd" << endl;
      return;
    }
  } else {
    cout << "Warning: no min spacing rule" << endl;
    return;
  }
  if (fig->getNet()->getNondefaultRule())
    bloatDist
        = max(bloatDist,
              fig->getNet()->getNondefaultRule()->getSpacing(lNum / 2 - 1));
  int idx1, idx2;
  if (isH) {
    getTrackIdx(box.yMin() - bloatDist - (viaBox.yMax() - 0) + 1,
                box.yMax() + bloatDist + (0 - viaBox.yMin()) - 1,
                followTrackLNum,
                idx1,
                idx2);
  } else {
    getTrackIdx(box.xMin() - bloatDist - (viaBox.xMax() - 0) + 1,
                box.xMax() + bloatDist + (0 - viaBox.xMin()) - 1,
                followTrackLNum,
                idx1,
                idx2);
  }

  auto& trackLocs = getTrackLocs(followTrackLNum);
  auto& workerRegionQuery = getWorkerRegionQuery();
  Rect tmpBx;
  dbTransform xform;
  frCoord dx, dy, prl;
  frCoord reqDist = 0;
  frCoord maxX, blockLeft, blockRight;
  Rect blockBox;
  for (int i = idx1; i <= idx2; i++) {
    auto trackLoc = trackLocs[i];
    if (isH) {
      xform.setOffset(Point(box.xMin(), trackLoc));
    } else {
      xform.setOffset(Point(trackLoc, box.yMin()));
    }
    tmpBx = viaBox;
    xform.apply(tmpBx);
    box2boxDistSquare(box, tmpBx, dx, dy);
    if (isH) {           // track is horizontal
      if (dy > 0) {      // via at the bottom of box
        if (isCurrPs) {  // prl maxed out to be viaBox
          prl = viaBox.xMax() - viaBox.xMin();
        } else {  // prl maxed out to be smaller of box and viaBox
          prl = min(box.xMax() - box.xMin(), viaBox.xMax() - viaBox.xMin());
        }
        // via at the side of box
      } else {
        if (isCurrPs) {  // prl maxed out to be viaBox
          prl = viaBox.yMax() - viaBox.yMin();
        } else {  // prl maxed out to be smaller of box and viaBox
          prl = min(box.yMax() - box.yMin(), viaBox.yMax() - viaBox.yMin());
        }
      }
    } else {             // track is vertical
      if (dx > 0) {      // via at the bottom of box
        if (isCurrPs) {  // prl maxed out to be viaBox
          prl = viaBox.yMax() - viaBox.yMin();
        } else {  // prl maxed out to be smaller of box and viaBox
          prl = min(box.yMax() - box.yMin(), viaBox.yMax() - viaBox.yMin());
        }
        // via at the side of box
      } else {
        if (isCurrPs) {  // prl maxed out to be viaBox
          prl = viaBox.xMax() - viaBox.xMin();
        } else {  // prl maxed out to be smaller of box and viaBox
          prl = min(box.xMax() - box.xMin(), viaBox.xMax() - viaBox.xMin());
        }
      }
    }

    if (con->typeId() == frConstraintTypeEnum::frcSpacingConstraint) {
      reqDist = static_cast<frSpacingConstraint*>(con)->getMinSpacing();
    } else if (con->typeId()
               == frConstraintTypeEnum::frcSpacingTablePrlConstraint) {
      reqDist = static_cast<frSpacingTablePrlConstraint*>(con)->find(
          max(width1, width2), prl);
    } else if (con->typeId()
               == frConstraintTypeEnum::frcSpacingTableTwConstraint) {
      reqDist = static_cast<frSpacingTableTwConstraint*>(con)->find(
          width1, width2, prl);
    }
    if (fig->getNet()->getNondefaultRule())
      reqDist
          = max(reqDist,
                fig->getNet()->getNondefaultRule()->getSpacing(lNum / 2 - 1));

    if (isH) {
      if (dy >= reqDist) {
        continue;
      }
      maxX = (frCoord) (sqrt(1.0 * reqDist * reqDist - 1.0 * dy * dy));
      if (maxX * maxX + dy * dy == reqDist * reqDist) {
        maxX = max(0, maxX - 1);
      }
      blockLeft = box.xMin() - maxX - (viaBox.xMax() - 0);
      blockRight = box.xMax() + maxX + (0 - viaBox.xMin());

      blockBox.init(blockLeft, trackLoc, blockRight, trackLoc);
    } else {
      if (dx >= reqDist) {
        continue;
      }
      maxX = (frCoord) (sqrt(1.0 * reqDist * reqDist - 1.0 * dx * dx));
      if (maxX * maxX + dx * dx == reqDist * reqDist) {
        maxX = max(0, maxX - 1);
      }
      blockLeft = box.yMin() - maxX - (viaBox.yMax() - 0);
      blockRight = box.yMax() + maxX + (0 - viaBox.yMin());

      blockBox.init(trackLoc, blockLeft, trackLoc, blockRight);
    }

    if (isAddCost) {
      workerRegionQuery.addCost(blockBox, cutLNum, fig, con);
      if (pinS) {
        workerRegionQuery.query(blockBox, cutLNum, *pinS);
      }
    } else {
      workerRegionQuery.removeCost(blockBox, cutLNum, fig, con);
      if (pinS) {
        workerRegionQuery.query(blockBox, cutLNum, *pinS);
      }
    }
  }
}

void FlexTAWorker::modCutSpacingCost(const Rect& box,
                                     frLayerNum lNum,
                                     taPinFig* fig,
                                     bool isAddCost,
                                     set<taPin*, frBlockObjectComp>* pinS)
{
  if (!getDesign()->getTech()->getLayer(lNum)->hasCutSpacing()) {
    return;
  }
  // obj1 = curr obj
  // obj2 = other obj
  // default via dimension
  frViaDef* viaDef = getDesign()->getTech()->getLayer(lNum)->getDefaultViaDef();
  frVia via(viaDef);
  Rect viaBox = via.getCutBBox();

  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
  frLayerNum followTrackLNum;
  if (lNum - 1 >= getDesign()->getTech()->getBottomLayerNum()
      && getDesign()->getTech()->getLayer(lNum - 1)->getType()
             == dbTechLayerType::ROUTING
      && getDesign()->getTech()->getLayer(lNum - 1)->getDir() == getDir()) {
    followTrackLNum = lNum - 1;
  } else if (lNum + 1 <= getDesign()->getTech()->getTopLayerNum()
             && getDesign()->getTech()->getLayer(lNum + 1)->getType()
                    == dbTechLayerType::ROUTING
             && getDesign()->getTech()->getLayer(lNum + 1)->getDir()
                    == getDir()) {
    followTrackLNum = lNum + 1;
  } else {
    cout << "Warning: via layer connected to non-routing layer, skipped in "
            "modMinSpacingCostVia"
         << endl;
    return;
  }

  // spacing value needed
  frCoord bloatDist = 0;
  for (auto con : getDesign()->getTech()->getLayer(lNum)->getCutSpacing()) {
    bloatDist = max(bloatDist, con->getCutSpacing());
  }

  int idx1, idx2;
  if (isH) {
    getTrackIdx(box.yMin() - bloatDist - (viaBox.yMax() - 0) + 1,
                box.yMax() + bloatDist + (0 - viaBox.yMin()) - 1,
                followTrackLNum,
                idx1,
                idx2);
  } else {
    getTrackIdx(box.xMin() - bloatDist - (viaBox.xMax() - 0) + 1,
                box.xMax() + bloatDist + (0 - viaBox.xMin()) - 1,
                followTrackLNum,
                idx1,
                idx2);
  }

  auto& trackLocs = getTrackLocs(followTrackLNum);
  auto& workerRegionQuery = getWorkerRegionQuery();
  Rect tmpBx;
  dbTransform xform;
  frCoord dx, dy, c2ctrackdist;
  frCoord reqDist = 0;
  frCoord maxX, blockLeft, blockRight;
  Rect blockBox;
  Point boxCenter, tmpBxCenter;
  boxCenter.set((box.xMin() + box.xMax()) / 2, (box.yMin() + box.yMax()) / 2);
  bool hasViol = false;
  for (int i = idx1; i <= idx2; i++) {
    auto trackLoc = trackLocs[i];
    if (isH) {
      xform.setOffset(Point(box.xMin(), trackLoc));
    } else {
      xform.setOffset(Point(trackLoc, box.yMin()));
    }
    tmpBx = viaBox;
    xform.apply(tmpBx);
    box2boxDistSquare(box, tmpBx, dx, dy);

    for (auto con : getDesign()->getTech()->getLayer(lNum)->getCutSpacing()) {
      hasViol = false;
      reqDist = con->getCutSpacing();
      bool isC2C = con->hasCenterToCenter();
      if (isH) {
        c2ctrackdist = abs(boxCenter.y() - trackLoc);
      } else {
        c2ctrackdist = abs(boxCenter.x() - trackLoc);
      }

      if (isH) {
        if (isC2C) {
          if (c2ctrackdist >= reqDist) {
            continue;
          }
        } else {
          if (dy >= reqDist) {
            continue;
          }
        }
        if (isC2C) {
          maxX = (frCoord) (sqrt(1.0 * reqDist * reqDist
                                 - 1.0 * c2ctrackdist * c2ctrackdist));
        } else {
          maxX = (frCoord) (sqrt(1.0 * reqDist * reqDist - 1.0 * dy * dy));
        }
        if (maxX * maxX + dy * dy == reqDist * reqDist) {
          maxX = max(0, maxX - 1);
        }
        if (isC2C) {
          blockLeft = boxCenter.x() - maxX;
          blockRight = boxCenter.x() + maxX;
        } else {
          blockLeft = box.xMin() - maxX - (viaBox.xMax() - 0);
          blockRight = box.xMax() + maxX + (0 - viaBox.xMin());
        }
        blockBox.init(blockLeft, trackLoc, blockRight, trackLoc);
      } else {
        if (isC2C) {
          if (c2ctrackdist >= reqDist) {
            continue;
          }
        } else {
          if (dx >= reqDist) {
            continue;
          }
        }
        if (isC2C) {
          maxX = (frCoord) (sqrt(1.0 * reqDist * reqDist
                                 - 1.0 * c2ctrackdist * c2ctrackdist));
        } else {
          maxX = (frCoord) (sqrt(1.0 * reqDist * reqDist - 1.0 * dx * dx));
        }
        if (maxX * maxX + dx * dx == reqDist * reqDist) {
          maxX = max(0, maxX - 1);
        }
        if (isC2C) {
          blockLeft = boxCenter.y() - maxX;
          blockRight = boxCenter.y() + maxX;
        } else {
          blockLeft = box.yMin() - maxX - (viaBox.yMax() - 0);
          blockRight = box.yMax() + maxX + (0 - viaBox.yMin());
        }

        blockBox.init(trackLoc, blockLeft, trackLoc, blockRight);
      }
      if (con->hasSameNet()) {
        continue;
      }
      if (con->isLayer()) {
        ;
      } else if (con->isAdjacentCuts()) {
        hasViol = true;
        // should disable hasViol and modify this part to new grid graph
      } else if (con->isParallelOverlap()) {
        if (isH) {
          if (dy > 0) {
            blockBox.init(max(box.xMin() - (viaBox.xMax() - 0) + 1, blockLeft),
                          trackLoc,
                          min(box.xMax() + (0 - viaBox.xMin()) - 1, blockRight),
                          trackLoc);
          }
        } else {
          if (dx > 0) {
            blockBox.init(
                trackLoc,
                max(box.yMin() - (viaBox.yMax() - 0) + 1, blockLeft),
                trackLoc,
                min(box.yMax() + (0 - viaBox.yMin()) - 1, blockRight));
          }
        }
        if (blockBox.xMin() <= blockBox.xMax()
            && blockBox.yMin() <= blockBox.yMax()) {
          hasViol = true;
        }
      } else if (con->isArea()) {
        auto currArea = max(box.maxDXDY() * box.minDXDY(),
                            tmpBx.maxDXDY() * tmpBx.minDXDY());
        if (currArea >= con->getCutArea()) {
          hasViol = true;
        }
      } else {
        hasViol = true;
      }
      if (hasViol) {
        if (isAddCost) {
          workerRegionQuery.addCost(blockBox, lNum, fig, con);
          if (pinS) {
            workerRegionQuery.query(blockBox, lNum, *pinS);
          }
        } else {
          workerRegionQuery.removeCost(blockBox, lNum, fig, con);
          if (pinS) {
            workerRegionQuery.query(blockBox, lNum, *pinS);
          }
        }
      }
    }
  }
}

void FlexTAWorker::addCost(taPinFig* fig, set<taPin*, frBlockObjectComp>* pinS)
{
  modCost(fig, true, pinS);
}

void FlexTAWorker::subCost(taPinFig* fig, set<taPin*, frBlockObjectComp>* pinS)
{
  modCost(fig, false, pinS);
}

void FlexTAWorker::modCost(taPinFig* fig,
                           bool isAddCost,
                           set<taPin*, frBlockObjectComp>* pinS)
{
  if (fig->typeId() == tacPathSeg) {
    auto obj = static_cast<taPathSeg*>(fig);
    auto layerNum = obj->getLayerNum();
    Rect box = obj->getBBox();
    modMinSpacingCostPlanar(
        box, layerNum, obj, isAddCost, pinS);  // must be current TA layer
    modMinSpacingCostVia(box, layerNum, obj, isAddCost, true, true, pinS);
    modMinSpacingCostVia(box, layerNum, obj, isAddCost, false, true, pinS);
  } else if (fig->typeId() == tacVia) {
    auto obj = static_cast<taVia*>(fig);
    // assumes enclosure for via is always rectangle
    Rect box = obj->getLayer1BBox();
    auto layerNum = obj->getViaDef()->getLayer1Num();
    // current TA layer
    if (getDir() == getDesign()->getTech()->getLayer(layerNum)->getDir()) {
      modMinSpacingCostPlanar(box, layerNum, obj, isAddCost, pinS);
    }
    modMinSpacingCostVia(box, layerNum, obj, isAddCost, true, false, pinS);
    modMinSpacingCostVia(box, layerNum, obj, isAddCost, false, false, pinS);

    // assumes enclosure for via is always rectangle
    box = obj->getLayer2BBox();
    layerNum = obj->getViaDef()->getLayer2Num();
    // current TA layer
    if (getDir() == getDesign()->getTech()->getLayer(layerNum)->getDir()) {
      modMinSpacingCostPlanar(box, layerNum, obj, isAddCost, pinS);
    }
    modMinSpacingCostVia(box, layerNum, obj, isAddCost, true, false, pinS);
    modMinSpacingCostVia(box, layerNum, obj, isAddCost, false, false, pinS);

    dbTransform xform;
    Point pt = obj->getOrigin();
    xform.setOffset(pt);
    for (auto& uFig : obj->getViaDef()->getCutFigs()) {
      auto rect = static_cast<frRect*>(uFig.get());
      box = rect->getBBox();
      xform.apply(box);
      layerNum = obj->getViaDef()->getCutLayerNum();
      modCutSpacingCost(box, layerNum, obj, isAddCost, pinS);
    }
  } else {
    cout << "Error: unsupported region query add" << endl;
  }
}

void FlexTAWorker::assignIroute_availTracks(taPin* iroute,
                                            frLayerNum& lNum,
                                            int& idx1,
                                            int& idx2)
{
  lNum = iroute->getGuide()->getBeginLayerNum();
  auto [gbp, gep] = iroute->getGuide()->getPoints();
  Point gIdx = getDesign()->getTopBlock()->getGCellIdx(gbp);
  Rect gBox = getDesign()->getTopBlock()->getGCellBox(gIdx);
  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
  frCoord coordLow = isH ? gBox.yMin() : gBox.xMin();
  frCoord coordHigh = isH ? gBox.yMax() : gBox.xMax();
  coordHigh--;  // to avoid higher track == guide top/right
  if (getTech()->getLayer(lNum)->isUnidirectional()) {
    const Rect& dieBx = design_->getTopBlock()->getDieBox();
    frViaDef* via = nullptr;
    Rect testBox;
    if (lNum + 1 <= getTech()->getTopLayerNum()) {
      via = getTech()->getLayer(lNum + 1)->getDefaultViaDef();
      testBox = via->getLayer1ShapeBox();
      testBox.merge(via->getLayer2ShapeBox());
    } else {
      via = getTech()->getLayer(lNum - 1)->getDefaultViaDef();
      testBox = via->getLayer1ShapeBox();
      testBox.merge(via->getLayer2ShapeBox());
    }
    int diffLow, diffHigh;
    if (isH) {
      diffLow = dieBx.yMin() - (coordLow - testBox.dy() / 2);
      diffHigh = coordHigh + testBox.dy() / 2 - dieBx.yMax();
    } else {
      diffLow = dieBx.xMin() - (coordLow - testBox.dx() / 2);
      diffHigh = coordHigh + testBox.dx() / 2 - dieBx.xMax();
    }
    if (diffLow > 0)
      coordLow += diffLow;
    if (diffHigh > 0)
      coordHigh -= diffHigh;
  }
  getTrackIdx(coordLow, coordHigh, lNum, idx1, idx2);
}

frUInt4 FlexTAWorker::assignIroute_getWlenCost(taPin* iroute, frCoord trackLoc)
{
  auto guide = iroute->getGuide();
  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
  auto [begin, end] = guide->getPoints();
  Point idx = getDesign()->getTopBlock()->getGCellIdx(end);
  Rect endBox = getDesign()->getTopBlock()->getGCellBox(idx);
  int wlen = 0;
  auto wlen_helper = iroute->getWlenHelper();
  if (wlen_helper <= 0) {
    if (isH) {
      wlen = abs(wlen_helper) * (trackLoc - endBox.yMin());
    } else {
      wlen = abs(wlen_helper) * (trackLoc - endBox.xMin());
    }
  } else {
    if (isH) {
      wlen = abs(wlen_helper) * (endBox.yMax() - trackLoc);
    } else {
      wlen = abs(wlen_helper) * (endBox.xMax() - trackLoc);
    }
  }
  if (wlen < 0) {
    double dbu = getDesign()->getTopBlock()->getDBUPerUU();
    cout << "Error: getWlenCost has wlenCost < 0"
         << ", trackLoc@" << trackLoc / dbu << " box (" << endBox.xMin() / dbu
         << ", " << endBox.yMin() / dbu << ") (" << endBox.xMax() / dbu << ", "
         << endBox.yMax() / dbu << ")" << endl;
    return (frUInt4) 0;
  } else {
    return (frUInt4) wlen;
  }
}

frUInt4 FlexTAWorker::assignIroute_getPinCost(taPin* iroute, frCoord trackLoc)
{
  frUInt4 sol = 0;
  if (iroute->hasWlenHelper2()) {
    sol = abs(trackLoc - iroute->getWlenHelper2());
    if (DBPROCESSNODE == "GF14_13M_3Mx_2Cx_4Kx_2Hx_2Gx_LB") {
      bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
      auto layerNum = iroute->getGuide()->getBeginLayerNum();
      int zIdx = layerNum / 2 - 1;
      if (sol) {
        if (isH) {
          // if cannot use bottom or upper layer to bridge, then add cost
          if ((getTech()->isVia2ViaForbiddenLen(
                   zIdx, false, false, false, sol, nullptr)
               || layerNum - 2 < BOTTOM_ROUTING_LAYER)
              && (getTech()->isVia2ViaForbiddenLen(
                      zIdx, true, true, false, sol, nullptr)
                  || layerNum + 2 > getTech()->getTopLayerNum())) {
            sol += TADRCCOST;
          }
        } else {
          if ((getTech()->isVia2ViaForbiddenLen(
                   zIdx, false, false, true, sol, nullptr)
               || layerNum - 2 < BOTTOM_ROUTING_LAYER)
              && (getTech()->isVia2ViaForbiddenLen(
                      zIdx, true, true, true, sol, nullptr)
                  || layerNum + 2 > getTech()->getTopLayerNum())) {
            sol += TADRCCOST;
          }
        }
      }
    }
  }
  return sol;
}

frUInt4 FlexTAWorker::assignIroute_getDRCCost_helper(taPin* iroute,
                                                     Rect& box,
                                                     frLayerNum lNum)
{
  auto& workerRegionQuery = getWorkerRegionQuery();
  vector<rq_box_value_t<std::pair<frBlockObject*, frConstraint*>>> result;
  int overlap = 0;
  if (iroute->getGuide()->getNet()->getNondefaultRule()) {
    int r = iroute->getGuide()->getNet()->getNondefaultRule()->getWidth(lNum / 2
                                                                        - 1)
            / 2;
    r += iroute->getGuide()->getNet()->getNondefaultRule()->getSpacing(lNum / 2
                                                                       - 1);
    box.bloat(r, box);
  }
  workerRegionQuery.queryCost(box, lNum, result);
  bool isCut = false;
  for (auto& [bounds, pr] : result) {
    auto& [obj, con] = pr;
    frCoord tmpOvlp
        = -max(box.xMin(), bounds.xMin()) + min(box.xMax(), bounds.xMax())
          - max(box.yMin(), bounds.yMin()) + min(box.yMax(), bounds.yMax()) + 1;
    if (tmpOvlp <= 0) {
      cout << "Error: assignIroute_getDRCCost_helper overlap < 0" << endl;
      exit(1);
    }
    // unknown obj, always add cost
    if (obj == nullptr) {
      overlap += tmpOvlp;
      // only add cost for diff-net
    } else if (obj->typeId() == frcNet) {
      if (iroute->getGuide()->getNet() != obj) {
        overlap += tmpOvlp;
      }
      // two taObjs
    } else if (obj->typeId() == tacPathSeg || obj->typeId() == tacVia) {
      auto taObj = static_cast<taPinFig*>(obj);
      // can exclude same iroute objs also
      if (taObj->getPin() == iroute) {
        continue;
      }
      if (iroute->getGuide()->getNet()
          != taObj->getPin()->getGuide()->getNet()) {
        overlap += tmpOvlp;
      }
    } else {
      cout << "Warning: assignIroute_getDRCCost_helper unsupported type"
           << endl;
    }
  }
  frCoord pitch = 0;
  if (getDesign()->getTech()->getLayer(lNum)->getType()
      == dbTechLayerType::ROUTING) {
    pitch = getDesign()->getTech()->getLayer(lNum)->getPitch();
    isCut = false;
  } else if (getDesign()->getTech()->getTopLayerNum() >= lNum + 1
             && getDesign()->getTech()->getLayer(lNum + 1)->getType()
                    == dbTechLayerType::ROUTING) {
    pitch = getDesign()->getTech()->getLayer(lNum + 1)->getPitch();
    isCut = true;
  } else if (getDesign()->getTech()->getBottomLayerNum() <= lNum - 1
             && getDesign()->getTech()->getLayer(lNum - 1)->getType()
                    == dbTechLayerType::ROUTING) {
    pitch = getDesign()->getTech()->getLayer(lNum - 1)->getPitch();
    isCut = true;
  } else {
    cout << "Error: assignIroute_getDRCCost_helper unknown layer type" << endl;
    exit(1);
  }
  // always penalize two pitch per cut, regardless of cnts
  return (overlap == 0) ? 0 : (isCut ? pitch * 2 : max(pitch * 2, overlap));
}

frUInt4 FlexTAWorker::assignIroute_getDRCCost(taPin* iroute, frCoord trackLoc)
{
  frUInt4 cost = 0;
  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
  for (auto& uPinFig : iroute->getFigs()) {
    if (uPinFig->typeId() == tacPathSeg) {
      auto obj = static_cast<taPathSeg*>(uPinFig.get());
      auto [bp, ep] = obj->getPoints();
      if (isH) {
        bp.set(bp.x(), trackLoc);
        ep.set(ep.x(), trackLoc);
      } else {
        bp.set(trackLoc, bp.y());
        ep.set(trackLoc, ep.y());
      }
      Rect bbox(bp, ep);
      frUInt4 wireCost
          = assignIroute_getDRCCost_helper(iroute, bbox, obj->getLayerNum());
      cost += wireCost;
    } else if (uPinFig->typeId() == tacVia) {
      auto obj = static_cast<taVia*>(uPinFig.get());
      auto bp = obj->getOrigin();
      if (isH) {
        bp.set(bp.x(), trackLoc);
      } else {
        bp.set(trackLoc, bp.y());
      }
      Rect bbox(bp, bp);
      frUInt4 viaCost = assignIroute_getDRCCost_helper(
          iroute, bbox, obj->getViaDef()->getCutLayerNum());
      cost += viaCost;
    } else {
      cout << "Error: assignIroute_updateIroute unsupported pinFig" << endl;
      exit(1);
    }
  }
  return cost;
}

frUInt4 FlexTAWorker::assignIroute_getAlignCost(taPin* iroute, frCoord trackLoc)
{
  frUInt4 sol = 0;
  frCoord pitch = 0;
  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
  for (auto& uPinFig : iroute->getFigs()) {
    if (uPinFig->typeId() == tacPathSeg) {
      auto obj = static_cast<taPathSeg*>(uPinFig.get());
      auto [bp, ep] = obj->getPoints();
      auto lNum = obj->getLayerNum();
      pitch = getDesign()->getTech()->getLayer(lNum)->getPitch();
      auto& workerRegionQuery = getWorkerRegionQuery();
      set<taPin*, frBlockObjectComp> result;
      Rect box;
      if (isH) {
        box.init(bp.x(), trackLoc, ep.x(), trackLoc);
      } else {
        box.init(trackLoc, bp.y(), trackLoc, ep.y());
      }
      workerRegionQuery.query(box, lNum, result);
      for (auto& iroute2 : result) {
        if (iroute2->getGuide()->getNet() == iroute->getGuide()->getNet()) {
          sol = 1;
          break;
        }
      }
    }
    if (sol == 1) {
      break;
    }
  }
  return pitch * sol;
}

frUInt4 FlexTAWorker::assignIroute_getCost(taPin* iroute,
                                           frCoord trackLoc,
                                           frUInt4& outDrcCost)
{
  frCoord irouteLayerPitch
      = getTech()->getLayer(iroute->getGuide()->getBeginLayerNum())->getPitch();
  outDrcCost = assignIroute_getDRCCost(iroute, trackLoc);
  int drcCost = (isInitTA()) ? (0.05 * outDrcCost) : (TADRCCOST * outDrcCost);
  int wlenCost = assignIroute_getWlenCost(iroute, trackLoc);
  // int pinCost    = TAPINCOST * assignIroute_getPinCost(iroute, trackLoc);
  int tmpPinCost = assignIroute_getPinCost(iroute, trackLoc);
  int pinCost
      = (tmpPinCost == 0) ? 0 : TAPINCOST * irouteLayerPitch + tmpPinCost;
  int tmpAlignCost = assignIroute_getAlignCost(iroute, trackLoc);
  int alignCost
      = (tmpAlignCost == 0) ? 0 : TAALIGNCOST * irouteLayerPitch + tmpAlignCost;
  return max(drcCost + wlenCost + pinCost - alignCost, 0);
}

void FlexTAWorker::assignIroute_bestTrack_helper(taPin* iroute,
                                                 frLayerNum lNum,
                                                 int trackIdx,
                                                 frUInt4& bestCost,
                                                 frCoord& bestTrackLoc,
                                                 int& bestTrackIdx,
                                                 frUInt4& drcCost)
{
  auto trackLoc = getTrackLocs(lNum)[trackIdx];
  auto currCost = assignIroute_getCost(iroute, trackLoc, drcCost);
  if (isInitTA()) {
    if (currCost < bestCost) {
      bestCost = currCost;
      bestTrackLoc = trackLoc;
      bestTrackIdx = trackIdx;
    }
  } else {
    if (drcCost < bestCost) {
      bestCost = drcCost;
      bestTrackLoc = trackLoc;
      bestTrackIdx = trackIdx;
    }
  }
}

int FlexTAWorker::assignIroute_bestTrack(taPin* iroute,
                                         frLayerNum lNum,
                                         int idx1,
                                         int idx2)
{
  double dbu = getDesign()->getTopBlock()->getDBUPerUU();
  frCoord bestTrackLoc = 0;
  int bestTrackIdx = -1;
  frUInt4 bestCost = std::numeric_limits<frUInt4>::max();
  frUInt4 drcCost = 0;
  // while (1) {
  //  if wlen2, then try from  wlen2
  //  else try from wlen1 dir
  if (iroute->hasWlenHelper2()) {
    // cout <<"if" <<endl;
    frCoord wlen2coord = iroute->getWlenHelper2();
    if (iroute->getWlenHelper() > 0) {
      int startTrackIdx = int(std::lower_bound(trackLocs_[lNum].begin(),
                                               trackLocs_[lNum].end(),
                                               wlen2coord)
                              - trackLocs_[lNum].begin());
      startTrackIdx = min(startTrackIdx, idx2);
      startTrackIdx = max(startTrackIdx, idx1);
      for (int i = startTrackIdx; i <= idx2; i++) {
        assignIroute_bestTrack_helper(
            iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
        if (!drcCost) {
          break;
        }
      }
      if (drcCost) {
        for (int i = startTrackIdx - 1; i >= idx1; i--) {
          assignIroute_bestTrack_helper(
              iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
          if (!drcCost) {
            break;
          }
        }
      }
    } else if (iroute->getWlenHelper() == 0) {
      int startTrackIdx = int(std::lower_bound(trackLocs_[lNum].begin(),
                                               trackLocs_[lNum].end(),
                                               wlen2coord)
                              - trackLocs_[lNum].begin());
      startTrackIdx = min(startTrackIdx, idx2);
      startTrackIdx = max(startTrackIdx, idx1);
      // cout <<"startTrackIdx " <<startTrackIdx <<endl;
      for (int i = 0; i <= idx2 - idx1; i++) {
        int currTrackIdx = startTrackIdx + i;
        if (currTrackIdx >= idx1 && currTrackIdx <= idx2) {
          assignIroute_bestTrack_helper(iroute,
                                        lNum,
                                        currTrackIdx,
                                        bestCost,
                                        bestTrackLoc,
                                        bestTrackIdx,
                                        drcCost);
        }
        if (!drcCost) {
          break;
        }
        currTrackIdx = startTrackIdx - i - 1;
        if (currTrackIdx >= idx1 && currTrackIdx <= idx2) {
          assignIroute_bestTrack_helper(iroute,
                                        lNum,
                                        currTrackIdx,
                                        bestCost,
                                        bestTrackLoc,
                                        bestTrackIdx,
                                        drcCost);
        }
        if (!drcCost) {
          break;
        }
      }
    } else {
      int startTrackIdx = int(std::lower_bound(trackLocs_[lNum].begin(),
                                               trackLocs_[lNum].end(),
                                               wlen2coord)
                              - trackLocs_[lNum].begin());
      startTrackIdx = min(startTrackIdx, idx2);
      startTrackIdx = max(startTrackIdx, idx1);
      for (int i = startTrackIdx; i >= idx1; i--) {
        assignIroute_bestTrack_helper(
            iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
        if (!drcCost) {
          break;
        }
      }
      if (drcCost) {
        for (int i = startTrackIdx + 1; i <= idx2; i++) {
          assignIroute_bestTrack_helper(
              iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
          if (!drcCost) {
            break;
          }
        }
      }
    }
  } else {
    // cout <<"else" <<endl;
    if (iroute->getWlenHelper() > 0) {
      for (int i = idx2; i >= idx1; i--) {
        assignIroute_bestTrack_helper(
            iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
        if (!drcCost) {
          break;
        }
      }
    } else if (iroute->getWlenHelper() == 0) {
      for (int i = (idx1 + idx2) / 2; i <= idx2; i++) {
        assignIroute_bestTrack_helper(
            iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
        if (!drcCost) {
          break;
        }
      }
      if (drcCost) {
        for (int i = (idx1 + idx2) / 2 - 1; i >= idx1; i--) {
          assignIroute_bestTrack_helper(
              iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
          if (!drcCost) {
            break;
          }
        }
      }
    } else {
      for (int i = idx1; i <= idx2; i++) {
        assignIroute_bestTrack_helper(
            iroute, lNum, i, bestCost, bestTrackLoc, bestTrackIdx, drcCost);
        if (!drcCost) {
          break;
        }
      }
    }
  }
  if (bestTrackIdx == -1) {
    auto guide = iroute->getGuide();
    Rect box = guide->getBBox();
    cout << "Error: assignIroute_bestTrack select no track for "
         << guide->getNet()->getName() << " @(" << box.xMin() / dbu << ", "
         << box.yMin() / dbu << ") (" << box.xMax() / dbu << ", "
         << box.yMax() / dbu << " "
         << getDesign()->getTech()->getLayer(lNum)->getName()
         << " idx1/2=" << idx1 << "/" << idx2 << endl;
    exit(1);
  }
  totCost_ += drcCost;
  iroute->setCost(drcCost);
  return bestTrackLoc;
}

void FlexTAWorker::assignIroute_updateIroute(
    taPin* iroute,
    frCoord bestTrackLoc,
    set<taPin*, frBlockObjectComp>* pinS)
{
  auto& workerRegionQuery = getWorkerRegionQuery();
  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);

  // update coord
  for (auto& uPinFig : iroute->getFigs()) {
    if (uPinFig->typeId() == tacPathSeg) {
      auto obj = static_cast<taPathSeg*>(uPinFig.get());
      auto [bp, ep] = obj->getPoints();
      if (isH) {
        bp.set(bp.x(), bestTrackLoc);
        ep.set(ep.x(), bestTrackLoc);
      } else {
        bp.set(bestTrackLoc, bp.y());
        ep.set(bestTrackLoc, ep.y());
      }
      obj->setPoints(bp, ep);
    } else if (uPinFig->typeId() == tacVia) {
      auto obj = static_cast<taVia*>(uPinFig.get());
      auto bp = obj->getOrigin();
      if (isH) {
        bp.set(bp.x(), bestTrackLoc);
      } else {
        bp.set(bestTrackLoc, bp.y());
      }
      obj->setOrigin(bp);
    } else {
      cout << "Error: assignIroute_updateIroute unsupported pinFig" << endl;
      exit(1);
    }
  }
  // addCost
  for (auto& uPinFig : iroute->getFigs()) {
    addCost(uPinFig.get(), isInitTA() ? nullptr : pinS);
    workerRegionQuery.add(uPinFig.get());
  }
  iroute->addNumAssigned();
}

void FlexTAWorker::assignIroute_init(taPin* iroute,
                                     set<taPin*, frBlockObjectComp>* pinS)
{
  auto& workerRegionQuery = getWorkerRegionQuery();
  // subCost
  if (!isInitTA()) {
    for (auto& uPinFig : iroute->getFigs()) {
      workerRegionQuery.remove(uPinFig.get());
      subCost(uPinFig.get(), pinS);
    }
    totCost_ -= iroute->getCost();
  }
}

void FlexTAWorker::assignIroute_updateOthers(
    set<taPin*, frBlockObjectComp>& pinS)
{
  bool isH = (getDir() == dbTechLayerDir::HORIZONTAL);
  if (isInitTA()) {
    return;
  }
  for (auto& iroute : pinS) {
    if (iroute->getGuide()->getNet()->isClock() && !hardIroutesMode)
      continue;
    removeFromReassignIroutes(iroute);
    // recalculate cost
    frUInt4 drcCost = 0;
    frCoord trackLoc = std::numeric_limits<frCoord>::max();
    for (auto& uPinFig : iroute->getFigs()) {
      if (uPinFig->typeId() == tacPathSeg) {
        auto [bp, ep] = static_cast<taPathSeg*>(uPinFig.get())->getPoints();
        if (isH) {
          trackLoc = bp.y();
        } else {
          trackLoc = bp.x();
        }
        break;
      }
    }
    if (trackLoc == std::numeric_limits<frCoord>::max()) {
      cout << "Error: FlexTAWorker::assignIroute_updateOthers does not find "
              "trackLoc"
           << endl;
      exit(1);
    }
    totCost_ -= iroute->getCost();
    assignIroute_getCost(iroute, trackLoc, drcCost);
    iroute->setCost(drcCost);
    totCost_ += iroute->getCost();
    if (drcCost && iroute->getNumAssigned() < maxRetry_) {
      addToReassignIroutes(iroute);
    }
  }
}

void FlexTAWorker::assignIroute(taPin* iroute)
{
  set<taPin*, frBlockObjectComp> pinS;
  assignIroute_init(iroute, &pinS);
  frLayerNum lNum;
  int idx1, idx2;
  assignIroute_availTracks(iroute, lNum, idx1, idx2);
  auto bestTrackLoc = assignIroute_bestTrack(iroute, lNum, idx1, idx2);

  assignIroute_updateIroute(iroute, bestTrackLoc, &pinS);
  assignIroute_updateOthers(pinS);
}

void FlexTAWorker::assign()
{
  int maxBufferSize = 20;
  vector<taPin*> buffers(maxBufferSize, nullptr);
  int currBufferIdx = 0;
  auto iroute = popFromReassignIroutes();
  while (iroute != nullptr) {
    auto it = find(buffers.begin(), buffers.end(), iroute);
    // in the buffer, skip
    if (it != buffers.end() || iroute->getNumAssigned() >= maxRetry_) {
      ;
      // not in the buffer, re-assign
    } else {
      assignIroute(iroute);
      // re add last buffer item to reassigniroutes if drccost > 0
      // if (buffers[currBufferIdx]) {
      //  if (buffers[currBufferIdx]->getDrcCost()) {
      //    addToReassignIroutes(buffers[currBufferIdx]);
      //  }
      //}
      buffers[currBufferIdx] = iroute;
      currBufferIdx = (currBufferIdx + 1) % maxBufferSize;
      numAssigned_++;
    }
    iroute = popFromReassignIroutes();
  }
}